1 |
Author: hollow |
2 |
Date: 2009-06-28 17:35:40 +0000 (Sun, 28 Jun 2009) |
3 |
New Revision: 562 |
4 |
|
5 |
Added: |
6 |
vserver-sources/2.3.0.36.14/ |
7 |
vserver-sources/2.3.0.36.14/4410_vs2.3.0.36.14.patch |
8 |
Log: |
9 |
version bump |
10 |
|
11 |
Added: vserver-sources/2.3.0.36.14/4410_vs2.3.0.36.14.patch |
12 |
=================================================================== |
13 |
--- vserver-sources/2.3.0.36.14/4410_vs2.3.0.36.14.patch (rev 0) |
14 |
+++ vserver-sources/2.3.0.36.14/4410_vs2.3.0.36.14.patch 2009-06-28 17:35:40 UTC (rev 562) |
15 |
@@ -0,0 +1,28140 @@ |
16 |
+diff -NurpP --minimal linux-2.6.29.4/arch/alpha/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/Kconfig |
17 |
+--- linux-2.6.29.4/arch/alpha/Kconfig 2009-03-24 14:18:07.000000000 +0100 |
18 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/Kconfig 2009-03-24 14:48:16.000000000 +0100 |
19 |
+@@ -666,6 +666,8 @@ config DUMMY_CONSOLE |
20 |
+ depends on VGA_HOSE |
21 |
+ default y |
22 |
+ |
23 |
++source "kernel/vserver/Kconfig" |
24 |
++ |
25 |
+ source "security/Kconfig" |
26 |
+ |
27 |
+ source "crypto/Kconfig" |
28 |
+diff -NurpP --minimal linux-2.6.29.4/arch/alpha/kernel/entry.S linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/kernel/entry.S |
29 |
+--- linux-2.6.29.4/arch/alpha/kernel/entry.S 2009-03-24 14:18:07.000000000 +0100 |
30 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/kernel/entry.S 2009-03-24 14:48:16.000000000 +0100 |
31 |
+@@ -874,24 +874,15 @@ sys_getxgid: |
32 |
+ .globl sys_getxpid |
33 |
+ .ent sys_getxpid |
34 |
+ sys_getxpid: |
35 |
++ lda $sp, -16($sp) |
36 |
++ stq $26, 0($sp) |
37 |
+ .prologue 0 |
38 |
+- ldq $2, TI_TASK($8) |
39 |
+ |
40 |
+- /* See linux/kernel/timer.c sys_getppid for discussion |
41 |
+- about this loop. */ |
42 |
+- ldq $3, TASK_GROUP_LEADER($2) |
43 |
+- ldq $4, TASK_REAL_PARENT($3) |
44 |
+- ldl $0, TASK_TGID($2) |
45 |
+-1: ldl $1, TASK_TGID($4) |
46 |
+-#ifdef CONFIG_SMP |
47 |
+- mov $4, $5 |
48 |
+- mb |
49 |
+- ldq $3, TASK_GROUP_LEADER($2) |
50 |
+- ldq $4, TASK_REAL_PARENT($3) |
51 |
+- cmpeq $4, $5, $5 |
52 |
+- beq $5, 1b |
53 |
+-#endif |
54 |
+- stq $1, 80($sp) |
55 |
++ lda $16, 96($sp) |
56 |
++ jsr $26, do_getxpid |
57 |
++ ldq $26, 0($sp) |
58 |
++ |
59 |
++ lda $sp, 16($sp) |
60 |
+ ret |
61 |
+ .end sys_getxpid |
62 |
+ |
63 |
+diff -NurpP --minimal linux-2.6.29.4/arch/alpha/kernel/osf_sys.c linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/kernel/osf_sys.c |
64 |
+--- linux-2.6.29.4/arch/alpha/kernel/osf_sys.c 2009-03-24 14:18:07.000000000 +0100 |
65 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/kernel/osf_sys.c 2009-03-24 14:48:16.000000000 +0100 |
66 |
+@@ -877,7 +877,7 @@ SYSCALL_DEFINE2(osf_gettimeofday, struct |
67 |
+ { |
68 |
+ if (tv) { |
69 |
+ struct timeval ktv; |
70 |
+- do_gettimeofday(&ktv); |
71 |
++ vx_gettimeofday(&ktv); |
72 |
+ if (put_tv32(tv, &ktv)) |
73 |
+ return -EFAULT; |
74 |
+ } |
75 |
+diff -NurpP --minimal linux-2.6.29.4/arch/alpha/kernel/ptrace.c linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/kernel/ptrace.c |
76 |
+--- linux-2.6.29.4/arch/alpha/kernel/ptrace.c 2008-12-25 00:26:37.000000000 +0100 |
77 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/kernel/ptrace.c 2009-02-22 22:54:24.000000000 +0100 |
78 |
+@@ -15,6 +15,7 @@ |
79 |
+ #include <linux/slab.h> |
80 |
+ #include <linux/security.h> |
81 |
+ #include <linux/signal.h> |
82 |
++#include <linux/vs_base.h> |
83 |
+ |
84 |
+ #include <asm/uaccess.h> |
85 |
+ #include <asm/pgtable.h> |
86 |
+diff -NurpP --minimal linux-2.6.29.4/arch/alpha/kernel/systbls.S linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/kernel/systbls.S |
87 |
+--- linux-2.6.29.4/arch/alpha/kernel/systbls.S 2009-03-24 14:18:08.000000000 +0100 |
88 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/kernel/systbls.S 2009-03-24 14:48:16.000000000 +0100 |
89 |
+@@ -446,7 +446,7 @@ sys_call_table: |
90 |
+ .quad sys_stat64 /* 425 */ |
91 |
+ .quad sys_lstat64 |
92 |
+ .quad sys_fstat64 |
93 |
+- .quad sys_ni_syscall /* sys_vserver */ |
94 |
++ .quad sys_vserver /* sys_vserver */ |
95 |
+ .quad sys_ni_syscall /* sys_mbind */ |
96 |
+ .quad sys_ni_syscall /* sys_get_mempolicy */ |
97 |
+ .quad sys_ni_syscall /* sys_set_mempolicy */ |
98 |
+diff -NurpP --minimal linux-2.6.29.4/arch/alpha/kernel/traps.c linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/kernel/traps.c |
99 |
+--- linux-2.6.29.4/arch/alpha/kernel/traps.c 2008-12-25 00:26:37.000000000 +0100 |
100 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/kernel/traps.c 2009-02-22 22:54:24.000000000 +0100 |
101 |
+@@ -183,7 +183,8 @@ die_if_kernel(char * str, struct pt_regs |
102 |
+ #ifdef CONFIG_SMP |
103 |
+ printk("CPU %d ", hard_smp_processor_id()); |
104 |
+ #endif |
105 |
+- printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err); |
106 |
++ printk("%s(%d[#%u]): %s %ld\n", current->comm, |
107 |
++ task_pid_nr(current), current->xid, str, err); |
108 |
+ dik_show_regs(regs, r9_15); |
109 |
+ add_taint(TAINT_DIE); |
110 |
+ dik_show_trace((unsigned long *)(regs+1)); |
111 |
+diff -NurpP --minimal linux-2.6.29.4/arch/alpha/mm/fault.c linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/mm/fault.c |
112 |
+--- linux-2.6.29.4/arch/alpha/mm/fault.c 2008-12-25 00:26:37.000000000 +0100 |
113 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/alpha/mm/fault.c 2009-02-22 22:54:24.000000000 +0100 |
114 |
+@@ -193,8 +193,8 @@ do_page_fault(unsigned long address, uns |
115 |
+ down_read(&mm->mmap_sem); |
116 |
+ goto survive; |
117 |
+ } |
118 |
+- printk(KERN_ALERT "VM: killing process %s(%d)\n", |
119 |
+- current->comm, task_pid_nr(current)); |
120 |
++ printk(KERN_ALERT "VM: killing process %s(%d:#%u)\n", |
121 |
++ current->comm, task_pid_nr(current), current->xid); |
122 |
+ if (!user_mode(regs)) |
123 |
+ goto no_context; |
124 |
+ do_group_exit(SIGKILL); |
125 |
+diff -NurpP --minimal linux-2.6.29.4/arch/arm/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/arm/Kconfig |
126 |
+--- linux-2.6.29.4/arch/arm/Kconfig 2009-03-24 14:18:08.000000000 +0100 |
127 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/arm/Kconfig 2009-03-24 14:48:16.000000000 +0100 |
128 |
+@@ -1333,6 +1333,8 @@ source "fs/Kconfig" |
129 |
+ |
130 |
+ source "arch/arm/Kconfig.debug" |
131 |
+ |
132 |
++source "kernel/vserver/Kconfig" |
133 |
++ |
134 |
+ source "security/Kconfig" |
135 |
+ |
136 |
+ source "crypto/Kconfig" |
137 |
+diff -NurpP --minimal linux-2.6.29.4/arch/arm/kernel/calls.S linux-2.6.29.4-vs2.3.0.36.14/arch/arm/kernel/calls.S |
138 |
+--- linux-2.6.29.4/arch/arm/kernel/calls.S 2009-03-24 14:18:09.000000000 +0100 |
139 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/arm/kernel/calls.S 2009-02-22 22:54:24.000000000 +0100 |
140 |
+@@ -322,7 +322,7 @@ |
141 |
+ /* 310 */ CALL(sys_request_key) |
142 |
+ CALL(sys_keyctl) |
143 |
+ CALL(ABI(sys_semtimedop, sys_oabi_semtimedop)) |
144 |
+-/* vserver */ CALL(sys_ni_syscall) |
145 |
++ CALL(sys_vserver) |
146 |
+ CALL(sys_ioprio_set) |
147 |
+ /* 315 */ CALL(sys_ioprio_get) |
148 |
+ CALL(sys_inotify_init) |
149 |
+diff -NurpP --minimal linux-2.6.29.4/arch/arm/kernel/process.c linux-2.6.29.4-vs2.3.0.36.14/arch/arm/kernel/process.c |
150 |
+--- linux-2.6.29.4/arch/arm/kernel/process.c 2008-12-25 00:26:37.000000000 +0100 |
151 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/arm/kernel/process.c 2009-02-22 22:54:24.000000000 +0100 |
152 |
+@@ -262,7 +262,8 @@ void __show_regs(struct pt_regs *regs) |
153 |
+ void show_regs(struct pt_regs * regs) |
154 |
+ { |
155 |
+ printk("\n"); |
156 |
+- printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm); |
157 |
++ printk("Pid: %d[#%u], comm: %20s\n", |
158 |
++ task_pid_nr(current), current->xid, current->comm); |
159 |
+ __show_regs(regs); |
160 |
+ __backtrace(); |
161 |
+ } |
162 |
+diff -NurpP --minimal linux-2.6.29.4/arch/arm/kernel/traps.c linux-2.6.29.4-vs2.3.0.36.14/arch/arm/kernel/traps.c |
163 |
+--- linux-2.6.29.4/arch/arm/kernel/traps.c 2008-12-25 00:26:37.000000000 +0100 |
164 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/arm/kernel/traps.c 2009-02-22 22:54:24.000000000 +0100 |
165 |
+@@ -214,8 +214,8 @@ static void __die(const char *str, int e |
166 |
+ str, err, ++die_counter); |
167 |
+ print_modules(); |
168 |
+ __show_regs(regs); |
169 |
+- printk("Process %s (pid: %d, stack limit = 0x%p)\n", |
170 |
+- tsk->comm, task_pid_nr(tsk), thread + 1); |
171 |
++ printk("Process %s (pid: %d:#%u, stack limit = 0x%p)\n", |
172 |
++ tsk->comm, task_pid_nr(tsk), tsk->xid, thread + 1); |
173 |
+ |
174 |
+ if (!user_mode(regs) || in_interrupt()) { |
175 |
+ dump_mem("Stack: ", regs->ARM_sp, |
176 |
+diff -NurpP --minimal linux-2.6.29.4/arch/arm/mm/fault.c linux-2.6.29.4-vs2.3.0.36.14/arch/arm/mm/fault.c |
177 |
+--- linux-2.6.29.4/arch/arm/mm/fault.c 2009-03-24 14:18:17.000000000 +0100 |
178 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/arm/mm/fault.c 2009-03-24 14:48:17.000000000 +0100 |
179 |
+@@ -294,7 +294,8 @@ do_page_fault(unsigned long addr, unsign |
180 |
+ * happened to us that made us unable to handle |
181 |
+ * the page fault gracefully. |
182 |
+ */ |
183 |
+- printk("VM: killing process %s\n", tsk->comm); |
184 |
++ printk("VM: killing process %s(%d:#%u)\n", |
185 |
++ tsk->comm, task_pid_nr(tsk), tsk->xid); |
186 |
+ do_group_exit(SIGKILL); |
187 |
+ return 0; |
188 |
+ } |
189 |
+diff -NurpP --minimal linux-2.6.29.4/arch/cris/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/cris/Kconfig |
190 |
+--- linux-2.6.29.4/arch/cris/Kconfig 2009-03-24 14:18:23.000000000 +0100 |
191 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/cris/Kconfig 2009-03-24 14:48:19.000000000 +0100 |
192 |
+@@ -685,6 +685,8 @@ source "drivers/staging/Kconfig" |
193 |
+ |
194 |
+ source "arch/cris/Kconfig.debug" |
195 |
+ |
196 |
++source "kernel/vserver/Kconfig" |
197 |
++ |
198 |
+ source "security/Kconfig" |
199 |
+ |
200 |
+ source "crypto/Kconfig" |
201 |
+diff -NurpP --minimal linux-2.6.29.4/arch/frv/kernel/kernel_thread.S linux-2.6.29.4-vs2.3.0.36.14/arch/frv/kernel/kernel_thread.S |
202 |
+--- linux-2.6.29.4/arch/frv/kernel/kernel_thread.S 2008-12-25 00:26:37.000000000 +0100 |
203 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/frv/kernel/kernel_thread.S 2009-02-22 22:54:24.000000000 +0100 |
204 |
+@@ -37,7 +37,7 @@ kernel_thread: |
205 |
+ |
206 |
+ # start by forking the current process, but with shared VM |
207 |
+ setlos.p #__NR_clone,gr7 ; syscall number |
208 |
+- ori gr10,#CLONE_VM,gr8 ; first syscall arg [clone_flags] |
209 |
++ ori gr10,#CLONE_KT,gr8 ; first syscall arg [clone_flags] |
210 |
+ sethi.p #0xe4e4,gr9 ; second syscall arg [newsp] |
211 |
+ setlo #0xe4e4,gr9 |
212 |
+ setlos.p #0,gr10 ; third syscall arg [parent_tidptr] |
213 |
+diff -NurpP --minimal linux-2.6.29.4/arch/h8300/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/h8300/Kconfig |
214 |
+--- linux-2.6.29.4/arch/h8300/Kconfig 2009-03-24 14:18:24.000000000 +0100 |
215 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/h8300/Kconfig 2009-03-24 14:48:19.000000000 +0100 |
216 |
+@@ -226,6 +226,8 @@ source "fs/Kconfig" |
217 |
+ |
218 |
+ source "arch/h8300/Kconfig.debug" |
219 |
+ |
220 |
++source "kernel/vserver/Kconfig" |
221 |
++ |
222 |
+ source "security/Kconfig" |
223 |
+ |
224 |
+ source "crypto/Kconfig" |
225 |
+diff -NurpP --minimal linux-2.6.29.4/arch/ia64/ia32/ia32_entry.S linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/ia32/ia32_entry.S |
226 |
+--- linux-2.6.29.4/arch/ia64/ia32/ia32_entry.S 2009-03-24 14:18:24.000000000 +0100 |
227 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/ia32/ia32_entry.S 2009-02-22 22:54:24.000000000 +0100 |
228 |
+@@ -451,7 +451,7 @@ ia32_syscall_table: |
229 |
+ data8 sys_tgkill /* 270 */ |
230 |
+ data8 compat_sys_utimes |
231 |
+ data8 sys32_fadvise64_64 |
232 |
+- data8 sys_ni_syscall |
233 |
++ data8 sys32_vserver |
234 |
+ data8 sys_ni_syscall |
235 |
+ data8 sys_ni_syscall /* 275 */ |
236 |
+ data8 sys_ni_syscall |
237 |
+diff -NurpP --minimal linux-2.6.29.4/arch/ia64/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/Kconfig |
238 |
+--- linux-2.6.29.4/arch/ia64/Kconfig 2009-03-24 14:18:24.000000000 +0100 |
239 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/Kconfig 2009-03-24 14:48:19.000000000 +0100 |
240 |
+@@ -672,6 +672,8 @@ source "fs/Kconfig" |
241 |
+ |
242 |
+ source "arch/ia64/Kconfig.debug" |
243 |
+ |
244 |
++source "kernel/vserver/Kconfig" |
245 |
++ |
246 |
+ source "security/Kconfig" |
247 |
+ |
248 |
+ source "crypto/Kconfig" |
249 |
+diff -NurpP --minimal linux-2.6.29.4/arch/ia64/kernel/entry.S linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/kernel/entry.S |
250 |
+--- linux-2.6.29.4/arch/ia64/kernel/entry.S 2009-03-24 14:18:25.000000000 +0100 |
251 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/kernel/entry.S 2009-02-22 22:54:24.000000000 +0100 |
252 |
+@@ -1653,7 +1653,7 @@ sys_call_table: |
253 |
+ data8 sys_mq_notify |
254 |
+ data8 sys_mq_getsetattr |
255 |
+ data8 sys_kexec_load |
256 |
+- data8 sys_ni_syscall // reserved for vserver |
257 |
++ data8 sys_vserver |
258 |
+ data8 sys_waitid // 1270 |
259 |
+ data8 sys_add_key |
260 |
+ data8 sys_request_key |
261 |
+diff -NurpP --minimal linux-2.6.29.4/arch/ia64/kernel/perfmon.c linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/kernel/perfmon.c |
262 |
+--- linux-2.6.29.4/arch/ia64/kernel/perfmon.c 2009-03-24 14:18:25.000000000 +0100 |
263 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/kernel/perfmon.c 2009-03-24 14:48:19.000000000 +0100 |
264 |
+@@ -41,6 +41,7 @@ |
265 |
+ #include <linux/rcupdate.h> |
266 |
+ #include <linux/completion.h> |
267 |
+ #include <linux/tracehook.h> |
268 |
++#include <linux/vs_memory.h> |
269 |
+ |
270 |
+ #include <asm/errno.h> |
271 |
+ #include <asm/intrinsics.h> |
272 |
+@@ -2372,7 +2373,7 @@ pfm_smpl_buffer_alloc(struct task_struct |
273 |
+ */ |
274 |
+ insert_vm_struct(mm, vma); |
275 |
+ |
276 |
+- mm->total_vm += size >> PAGE_SHIFT; |
277 |
++ vx_vmpages_add(mm, size >> PAGE_SHIFT); |
278 |
+ vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, |
279 |
+ vma_pages(vma)); |
280 |
+ up_write(&task->mm->mmap_sem); |
281 |
+diff -NurpP --minimal linux-2.6.29.4/arch/ia64/kernel/process.c linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/kernel/process.c |
282 |
+--- linux-2.6.29.4/arch/ia64/kernel/process.c 2008-12-25 00:26:37.000000000 +0100 |
283 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/kernel/process.c 2009-02-22 22:54:24.000000000 +0100 |
284 |
+@@ -110,8 +110,8 @@ show_regs (struct pt_regs *regs) |
285 |
+ unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; |
286 |
+ |
287 |
+ print_modules(); |
288 |
+- printk("\nPid: %d, CPU %d, comm: %20s\n", task_pid_nr(current), |
289 |
+- smp_processor_id(), current->comm); |
290 |
++ printk("\nPid: %d[#%u], CPU %d, comm: %20s\n", task_pid_nr(current), |
291 |
++ current->xid, smp_processor_id(), current->comm); |
292 |
+ printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s)\n", |
293 |
+ regs->cr_ipsr, regs->cr_ifs, ip, print_tainted(), |
294 |
+ init_utsname()->release); |
295 |
+diff -NurpP --minimal linux-2.6.29.4/arch/ia64/kernel/ptrace.c linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/kernel/ptrace.c |
296 |
+--- linux-2.6.29.4/arch/ia64/kernel/ptrace.c 2008-12-25 00:26:37.000000000 +0100 |
297 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/kernel/ptrace.c 2009-02-22 22:54:24.000000000 +0100 |
298 |
+@@ -23,6 +23,7 @@ |
299 |
+ #include <linux/regset.h> |
300 |
+ #include <linux/elf.h> |
301 |
+ #include <linux/tracehook.h> |
302 |
++#include <linux/vs_base.h> |
303 |
+ |
304 |
+ #include <asm/pgtable.h> |
305 |
+ #include <asm/processor.h> |
306 |
+diff -NurpP --minimal linux-2.6.29.4/arch/ia64/kernel/traps.c linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/kernel/traps.c |
307 |
+--- linux-2.6.29.4/arch/ia64/kernel/traps.c 2008-12-25 00:26:37.000000000 +0100 |
308 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/kernel/traps.c 2009-02-22 22:54:24.000000000 +0100 |
309 |
+@@ -60,8 +60,9 @@ die (const char *str, struct pt_regs *re |
310 |
+ put_cpu(); |
311 |
+ |
312 |
+ if (++die.lock_owner_depth < 3) { |
313 |
+- printk("%s[%d]: %s %ld [%d]\n", |
314 |
+- current->comm, task_pid_nr(current), str, err, ++die_counter); |
315 |
++ printk("%s[%d[#%u]]: %s %ld [%d]\n", |
316 |
++ current->comm, task_pid_nr(current), current->xid, |
317 |
++ str, err, ++die_counter); |
318 |
+ if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV) |
319 |
+ != NOTIFY_STOP) |
320 |
+ show_regs(regs); |
321 |
+@@ -324,8 +325,9 @@ handle_fpu_swa (int fp_fault, struct pt_ |
322 |
+ if ((last.count & 15) < 5 && (ia64_fetchadd(1, &last.count, acq) & 15) < 5) { |
323 |
+ last.time = current_jiffies + 5 * HZ; |
324 |
+ printk(KERN_WARNING |
325 |
+- "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n", |
326 |
+- current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr); |
327 |
++ "%s(%d[#%u]): floating-point assist fault at ip %016lx, isr %016lx\n", |
328 |
++ current->comm, task_pid_nr(current), current->xid, |
329 |
++ regs->cr_iip + ia64_psr(regs)->ri, isr); |
330 |
+ } |
331 |
+ } |
332 |
+ } |
333 |
+diff -NurpP --minimal linux-2.6.29.4/arch/ia64/mm/fault.c linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/mm/fault.c |
334 |
+--- linux-2.6.29.4/arch/ia64/mm/fault.c 2008-12-25 00:26:37.000000000 +0100 |
335 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/ia64/mm/fault.c 2009-02-22 22:54:24.000000000 +0100 |
336 |
+@@ -10,6 +10,7 @@ |
337 |
+ #include <linux/interrupt.h> |
338 |
+ #include <linux/kprobes.h> |
339 |
+ #include <linux/kdebug.h> |
340 |
++#include <linux/vs_memory.h> |
341 |
+ |
342 |
+ #include <asm/pgtable.h> |
343 |
+ #include <asm/processor.h> |
344 |
+diff -NurpP --minimal linux-2.6.29.4/arch/m32r/kernel/traps.c linux-2.6.29.4-vs2.3.0.36.14/arch/m32r/kernel/traps.c |
345 |
+--- linux-2.6.29.4/arch/m32r/kernel/traps.c 2008-12-25 00:26:37.000000000 +0100 |
346 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/m32r/kernel/traps.c 2009-02-22 22:54:24.000000000 +0100 |
347 |
+@@ -196,8 +196,9 @@ static void show_registers(struct pt_reg |
348 |
+ } else { |
349 |
+ printk("SPI: %08lx\n", sp); |
350 |
+ } |
351 |
+- printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)", |
352 |
+- current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current); |
353 |
++ printk("Process %s (pid: %d[#%u], process nr: %d, stackpage=%08lx)", |
354 |
++ current->comm, task_pid_nr(current), current->xid, |
355 |
++ 0xffff & i, 4096+(unsigned long)current); |
356 |
+ |
357 |
+ /* |
358 |
+ * When in-kernel, we also print out the stack and code at the |
359 |
+diff -NurpP --minimal linux-2.6.29.4/arch/m68k/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/m68k/Kconfig |
360 |
+--- linux-2.6.29.4/arch/m68k/Kconfig 2009-03-24 14:18:26.000000000 +0100 |
361 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/m68k/Kconfig 2009-03-24 14:48:20.000000000 +0100 |
362 |
+@@ -616,6 +616,8 @@ source "fs/Kconfig" |
363 |
+ |
364 |
+ source "arch/m68k/Kconfig.debug" |
365 |
+ |
366 |
++source "kernel/vserver/Kconfig" |
367 |
++ |
368 |
+ source "security/Kconfig" |
369 |
+ |
370 |
+ source "crypto/Kconfig" |
371 |
+diff -NurpP --minimal linux-2.6.29.4/arch/m68k/kernel/ptrace.c linux-2.6.29.4-vs2.3.0.36.14/arch/m68k/kernel/ptrace.c |
372 |
+--- linux-2.6.29.4/arch/m68k/kernel/ptrace.c 2008-12-25 00:26:37.000000000 +0100 |
373 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/m68k/kernel/ptrace.c 2009-02-22 22:54:24.000000000 +0100 |
374 |
+@@ -18,6 +18,7 @@ |
375 |
+ #include <linux/ptrace.h> |
376 |
+ #include <linux/user.h> |
377 |
+ #include <linux/signal.h> |
378 |
++#include <linux/vs_base.h> |
379 |
+ |
380 |
+ #include <asm/uaccess.h> |
381 |
+ #include <asm/page.h> |
382 |
+@@ -269,6 +270,8 @@ long arch_ptrace(struct task_struct *chi |
383 |
+ ret = ptrace_request(child, request, addr, data); |
384 |
+ break; |
385 |
+ } |
386 |
++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT)) |
387 |
++ goto out_tsk; |
388 |
+ |
389 |
+ return ret; |
390 |
+ out_eio: |
391 |
+diff -NurpP --minimal linux-2.6.29.4/arch/m68k/kernel/traps.c linux-2.6.29.4-vs2.3.0.36.14/arch/m68k/kernel/traps.c |
392 |
+--- linux-2.6.29.4/arch/m68k/kernel/traps.c 2009-03-24 14:18:26.000000000 +0100 |
393 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/m68k/kernel/traps.c 2009-03-24 14:48:20.000000000 +0100 |
394 |
+@@ -906,8 +906,8 @@ void show_registers(struct pt_regs *regs |
395 |
+ printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", |
396 |
+ regs->d4, regs->d5, regs->a0, regs->a1); |
397 |
+ |
398 |
+- printk("Process %s (pid: %d, task=%p)\n", |
399 |
+- current->comm, task_pid_nr(current), current); |
400 |
++ printk("Process %s (pid: %d[#%u], task=%p)\n", |
401 |
++ current->comm, task_pid_nr(current), current->xid, current); |
402 |
+ addr = (unsigned long)&fp->un; |
403 |
+ printk("Frame format=%X ", regs->format); |
404 |
+ switch (regs->format) { |
405 |
+diff -NurpP --minimal linux-2.6.29.4/arch/m68knommu/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/m68knommu/Kconfig |
406 |
+--- linux-2.6.29.4/arch/m68knommu/Kconfig 2009-03-24 14:18:27.000000000 +0100 |
407 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/m68knommu/Kconfig 2009-03-24 14:48:20.000000000 +0100 |
408 |
+@@ -720,6 +720,8 @@ source "fs/Kconfig" |
409 |
+ |
410 |
+ source "arch/m68knommu/Kconfig.debug" |
411 |
+ |
412 |
++source "kernel/vserver/Kconfig" |
413 |
++ |
414 |
+ source "security/Kconfig" |
415 |
+ |
416 |
+ source "crypto/Kconfig" |
417 |
+diff -NurpP --minimal linux-2.6.29.4/arch/m68knommu/kernel/traps.c linux-2.6.29.4-vs2.3.0.36.14/arch/m68knommu/kernel/traps.c |
418 |
+--- linux-2.6.29.4/arch/m68knommu/kernel/traps.c 2008-12-25 00:26:37.000000000 +0100 |
419 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/m68knommu/kernel/traps.c 2009-02-22 22:54:24.000000000 +0100 |
420 |
+@@ -78,8 +78,9 @@ void die_if_kernel(char *str, struct pt_ |
421 |
+ printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", |
422 |
+ fp->d4, fp->d5, fp->a0, fp->a1); |
423 |
+ |
424 |
+- printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n", |
425 |
+- current->comm, current->pid, PAGE_SIZE+(unsigned long)current); |
426 |
++ printk(KERN_EMERG "Process %s (pid: %d[#%u], stackpage=%08lx)\n", |
427 |
++ current->comm, task_pid_nr(current), current->xid, |
428 |
++ PAGE_SIZE+(unsigned long)current); |
429 |
+ show_stack(NULL, (unsigned long *)(fp + 1)); |
430 |
+ add_taint(TAINT_DIE); |
431 |
+ do_exit(SIGSEGV); |
432 |
+diff -NurpP --minimal linux-2.6.29.4/arch/mips/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/mips/Kconfig |
433 |
+--- linux-2.6.29.4/arch/mips/Kconfig 2009-03-24 14:18:29.000000000 +0100 |
434 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/mips/Kconfig 2009-03-24 14:48:21.000000000 +0100 |
435 |
+@@ -2142,6 +2142,8 @@ source "fs/Kconfig" |
436 |
+ |
437 |
+ source "arch/mips/Kconfig.debug" |
438 |
+ |
439 |
++source "kernel/vserver/Kconfig" |
440 |
++ |
441 |
+ source "security/Kconfig" |
442 |
+ |
443 |
+ source "crypto/Kconfig" |
444 |
+diff -NurpP --minimal linux-2.6.29.4/arch/mips/kernel/ptrace.c linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/ptrace.c |
445 |
+--- linux-2.6.29.4/arch/mips/kernel/ptrace.c 2008-12-25 00:26:37.000000000 +0100 |
446 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/ptrace.c 2009-02-22 22:54:24.000000000 +0100 |
447 |
+@@ -25,6 +25,7 @@ |
448 |
+ #include <linux/security.h> |
449 |
+ #include <linux/audit.h> |
450 |
+ #include <linux/seccomp.h> |
451 |
++#include <linux/vs_base.h> |
452 |
+ |
453 |
+ #include <asm/byteorder.h> |
454 |
+ #include <asm/cpu.h> |
455 |
+@@ -259,6 +260,9 @@ long arch_ptrace(struct task_struct *chi |
456 |
+ { |
457 |
+ int ret; |
458 |
+ |
459 |
++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT)) |
460 |
++ goto out; |
461 |
++ |
462 |
+ switch (request) { |
463 |
+ /* when I and D space are separate, these will need to be fixed. */ |
464 |
+ case PTRACE_PEEKTEXT: /* read word at location addr. */ |
465 |
+diff -NurpP --minimal linux-2.6.29.4/arch/mips/kernel/scall32-o32.S linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/scall32-o32.S |
466 |
+--- linux-2.6.29.4/arch/mips/kernel/scall32-o32.S 2009-03-24 14:18:31.000000000 +0100 |
467 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/scall32-o32.S 2009-03-24 14:48:21.000000000 +0100 |
468 |
+@@ -597,7 +597,7 @@ einval: li v0, -ENOSYS |
469 |
+ sys sys_mq_timedreceive 5 |
470 |
+ sys sys_mq_notify 2 /* 4275 */ |
471 |
+ sys sys_mq_getsetattr 3 |
472 |
+- sys sys_ni_syscall 0 /* sys_vserver */ |
473 |
++ sys sys_vserver 3 |
474 |
+ sys sys_waitid 5 |
475 |
+ sys sys_ni_syscall 0 /* available, was setaltroot */ |
476 |
+ sys sys_add_key 5 /* 4280 */ |
477 |
+diff -NurpP --minimal linux-2.6.29.4/arch/mips/kernel/scall64-64.S linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/scall64-64.S |
478 |
+--- linux-2.6.29.4/arch/mips/kernel/scall64-64.S 2009-03-24 14:18:31.000000000 +0100 |
479 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/scall64-64.S 2009-03-24 14:48:21.000000000 +0100 |
480 |
+@@ -434,7 +434,7 @@ sys_call_table: |
481 |
+ PTR sys_mq_timedreceive |
482 |
+ PTR sys_mq_notify |
483 |
+ PTR sys_mq_getsetattr /* 5235 */ |
484 |
+- PTR sys_ni_syscall /* sys_vserver */ |
485 |
++ PTR sys_vserver |
486 |
+ PTR sys_waitid |
487 |
+ PTR sys_ni_syscall /* available, was setaltroot */ |
488 |
+ PTR sys_add_key |
489 |
+diff -NurpP --minimal linux-2.6.29.4/arch/mips/kernel/scall64-n32.S linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/scall64-n32.S |
490 |
+--- linux-2.6.29.4/arch/mips/kernel/scall64-n32.S 2009-03-24 14:18:31.000000000 +0100 |
491 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/scall64-n32.S 2009-03-24 14:48:21.000000000 +0100 |
492 |
+@@ -360,7 +360,7 @@ EXPORT(sysn32_call_table) |
493 |
+ PTR compat_sys_mq_timedreceive |
494 |
+ PTR compat_sys_mq_notify |
495 |
+ PTR compat_sys_mq_getsetattr |
496 |
+- PTR sys_ni_syscall /* 6240, sys_vserver */ |
497 |
++ PTR sys32_vserver /* 6240 */ |
498 |
+ PTR compat_sys_waitid |
499 |
+ PTR sys_ni_syscall /* available, was setaltroot */ |
500 |
+ PTR sys_add_key |
501 |
+diff -NurpP --minimal linux-2.6.29.4/arch/mips/kernel/scall64-o32.S linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/scall64-o32.S |
502 |
+--- linux-2.6.29.4/arch/mips/kernel/scall64-o32.S 2009-03-24 14:18:31.000000000 +0100 |
503 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/scall64-o32.S 2009-03-24 14:59:48.000000000 +0100 |
504 |
+@@ -480,7 +480,7 @@ sys_call_table: |
505 |
+ PTR compat_sys_mq_timedreceive |
506 |
+ PTR compat_sys_mq_notify /* 4275 */ |
507 |
+ PTR compat_sys_mq_getsetattr |
508 |
+- PTR sys_ni_syscall /* sys_vserver */ |
509 |
++ PTR sys32_vserver |
510 |
+ PTR sys_32_waitid |
511 |
+ PTR sys_ni_syscall /* available, was setaltroot */ |
512 |
+ PTR sys_add_key /* 4280 */ |
513 |
+diff -NurpP --minimal linux-2.6.29.4/arch/mips/kernel/traps.c linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/traps.c |
514 |
+--- linux-2.6.29.4/arch/mips/kernel/traps.c 2009-03-24 14:18:31.000000000 +0100 |
515 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/mips/kernel/traps.c 2009-03-24 14:48:21.000000000 +0100 |
516 |
+@@ -335,9 +335,10 @@ void show_registers(const struct pt_regs |
517 |
+ |
518 |
+ __show_regs(regs); |
519 |
+ print_modules(); |
520 |
+- printk("Process %s (pid: %d, threadinfo=%p, task=%p, tls=%0*lx)\n", |
521 |
+- current->comm, current->pid, current_thread_info(), current, |
522 |
+- field, current_thread_info()->tp_value); |
523 |
++ printk("Process %s (pid: %d:#%u, threadinfo=%p, task=%p, tls=%0*lx)\n", |
524 |
++ current->comm, task_pid_nr(current), current->xid, |
525 |
++ current_thread_info(), current, |
526 |
++ field, current_thread_info()->tp_value); |
527 |
+ if (cpu_has_userlocal) { |
528 |
+ unsigned long tls; |
529 |
+ |
530 |
+diff -NurpP --minimal linux-2.6.29.4/arch/parisc/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/parisc/Kconfig |
531 |
+--- linux-2.6.29.4/arch/parisc/Kconfig 2009-03-24 14:18:32.000000000 +0100 |
532 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/parisc/Kconfig 2009-03-24 14:48:21.000000000 +0100 |
533 |
+@@ -281,6 +281,8 @@ source "fs/Kconfig" |
534 |
+ |
535 |
+ source "arch/parisc/Kconfig.debug" |
536 |
+ |
537 |
++source "kernel/vserver/Kconfig" |
538 |
++ |
539 |
+ source "security/Kconfig" |
540 |
+ |
541 |
+ source "crypto/Kconfig" |
542 |
+diff -NurpP --minimal linux-2.6.29.4/arch/parisc/kernel/syscall_table.S linux-2.6.29.4-vs2.3.0.36.14/arch/parisc/kernel/syscall_table.S |
543 |
+--- linux-2.6.29.4/arch/parisc/kernel/syscall_table.S 2008-12-25 00:26:37.000000000 +0100 |
544 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/parisc/kernel/syscall_table.S 2009-02-22 22:54:24.000000000 +0100 |
545 |
+@@ -361,7 +361,7 @@ |
546 |
+ ENTRY_COMP(mbind) /* 260 */ |
547 |
+ ENTRY_COMP(get_mempolicy) |
548 |
+ ENTRY_COMP(set_mempolicy) |
549 |
+- ENTRY_SAME(ni_syscall) /* 263: reserved for vserver */ |
550 |
++ ENTRY_DIFF(vserver) |
551 |
+ ENTRY_SAME(add_key) |
552 |
+ ENTRY_SAME(request_key) /* 265 */ |
553 |
+ ENTRY_SAME(keyctl) |
554 |
+diff -NurpP --minimal linux-2.6.29.4/arch/parisc/kernel/traps.c linux-2.6.29.4-vs2.3.0.36.14/arch/parisc/kernel/traps.c |
555 |
+--- linux-2.6.29.4/arch/parisc/kernel/traps.c 2009-03-24 14:18:32.000000000 +0100 |
556 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/parisc/kernel/traps.c 2009-03-24 14:48:21.000000000 +0100 |
557 |
+@@ -236,8 +236,9 @@ void die_if_kernel(char *str, struct pt_ |
558 |
+ if (err == 0) |
559 |
+ return; /* STFU */ |
560 |
+ |
561 |
+- printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n", |
562 |
+- current->comm, task_pid_nr(current), str, err, regs->iaoq[0]); |
563 |
++ printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld) at " RFMT "\n", |
564 |
++ current->comm, task_pid_nr(current), current->xid, |
565 |
++ str, err, regs->iaoq[0]); |
566 |
+ #ifdef PRINT_USER_FAULTS |
567 |
+ /* XXX for debugging only */ |
568 |
+ show_regs(regs); |
569 |
+@@ -269,8 +270,8 @@ KERN_CRIT " || | |
570 |
+ pdc_console_restart(); |
571 |
+ |
572 |
+ if (err) |
573 |
+- printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n", |
574 |
+- current->comm, task_pid_nr(current), str, err); |
575 |
++ printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld)\n", |
576 |
++ current->comm, task_pid_nr(current), current->xid, str, err); |
577 |
+ |
578 |
+ /* Wot's wrong wif bein' racy? */ |
579 |
+ if (current->thread.flags & PARISC_KERNEL_DEATH) { |
580 |
+diff -NurpP --minimal linux-2.6.29.4/arch/parisc/mm/fault.c linux-2.6.29.4-vs2.3.0.36.14/arch/parisc/mm/fault.c |
581 |
+--- linux-2.6.29.4/arch/parisc/mm/fault.c 2009-03-24 14:18:33.000000000 +0100 |
582 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/parisc/mm/fault.c 2009-03-24 14:48:21.000000000 +0100 |
583 |
+@@ -238,8 +238,9 @@ bad_area: |
584 |
+ |
585 |
+ #ifdef PRINT_USER_FAULTS |
586 |
+ printk(KERN_DEBUG "\n"); |
587 |
+- printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n", |
588 |
+- task_pid_nr(tsk), tsk->comm, code, address); |
589 |
++ printk(KERN_DEBUG "do_page_fault() pid=%d:#%u " |
590 |
++ "command='%s' type=%lu address=0x%08lx\n", |
591 |
++ task_pid_nr(tsk), tsk->xid, tsk->comm, code, address); |
592 |
+ if (vma) { |
593 |
+ printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n", |
594 |
+ vma->vm_start, vma->vm_end); |
595 |
+@@ -265,7 +266,8 @@ no_context: |
596 |
+ |
597 |
+ out_of_memory: |
598 |
+ up_read(&mm->mmap_sem); |
599 |
+- printk(KERN_CRIT "VM: killing process %s\n", current->comm); |
600 |
++ printk(KERN_CRIT "VM: killing process %s(%d:#%u)\n", |
601 |
++ current->comm, current->pid, current->xid); |
602 |
+ if (user_mode(regs)) |
603 |
+ do_group_exit(SIGKILL); |
604 |
+ goto no_context; |
605 |
+diff -NurpP --minimal linux-2.6.29.4/arch/powerpc/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/Kconfig |
606 |
+--- linux-2.6.29.4/arch/powerpc/Kconfig 2009-03-24 14:18:33.000000000 +0100 |
607 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/Kconfig 2009-03-24 14:48:22.000000000 +0100 |
608 |
+@@ -882,6 +882,8 @@ source "lib/Kconfig" |
609 |
+ |
610 |
+ source "arch/powerpc/Kconfig.debug" |
611 |
+ |
612 |
++source "kernel/vserver/Kconfig" |
613 |
++ |
614 |
+ source "security/Kconfig" |
615 |
+ |
616 |
+ config KEYS_COMPAT |
617 |
+diff -NurpP --minimal linux-2.6.29.4/arch/powerpc/kernel/irq.c linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/kernel/irq.c |
618 |
+--- linux-2.6.29.4/arch/powerpc/kernel/irq.c 2009-03-24 14:18:35.000000000 +0100 |
619 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/kernel/irq.c 2009-03-24 14:48:22.000000000 +0100 |
620 |
+@@ -53,6 +53,7 @@ |
621 |
+ #include <linux/bootmem.h> |
622 |
+ #include <linux/pci.h> |
623 |
+ #include <linux/debugfs.h> |
624 |
++#include <linux/vs_context.h> |
625 |
+ |
626 |
+ #include <asm/uaccess.h> |
627 |
+ #include <asm/system.h> |
628 |
+diff -NurpP --minimal linux-2.6.29.4/arch/powerpc/kernel/process.c linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/kernel/process.c |
629 |
+--- linux-2.6.29.4/arch/powerpc/kernel/process.c 2009-03-24 14:18:35.000000000 +0100 |
630 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/kernel/process.c 2009-03-24 14:48:22.000000000 +0100 |
631 |
+@@ -516,8 +516,9 @@ void show_regs(struct pt_regs * regs) |
632 |
+ #else |
633 |
+ printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr); |
634 |
+ #endif |
635 |
+- printk("TASK = %p[%d] '%s' THREAD: %p", |
636 |
+- current, task_pid_nr(current), current->comm, task_thread_info(current)); |
637 |
++ printk("TASK = %p[%d,#%u] '%s' THREAD: %p", |
638 |
++ current, task_pid_nr(current), current->xid, |
639 |
++ current->comm, task_thread_info(current)); |
640 |
+ |
641 |
+ #ifdef CONFIG_SMP |
642 |
+ printk(" CPU: %d", raw_smp_processor_id()); |
643 |
+diff -NurpP --minimal linux-2.6.29.4/arch/powerpc/kernel/traps.c linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/kernel/traps.c |
644 |
+--- linux-2.6.29.4/arch/powerpc/kernel/traps.c 2009-03-24 14:18:35.000000000 +0100 |
645 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/kernel/traps.c 2009-03-24 14:48:22.000000000 +0100 |
646 |
+@@ -940,8 +940,9 @@ void nonrecoverable_exception(struct pt_ |
647 |
+ |
648 |
+ void trace_syscall(struct pt_regs *regs) |
649 |
+ { |
650 |
+- printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n", |
651 |
+- current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0], |
652 |
++ printk("Task: %p(%d[#%u]), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n", |
653 |
++ current, task_pid_nr(current), current->xid, |
654 |
++ regs->nip, regs->link, regs->gpr[0], |
655 |
+ regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted()); |
656 |
+ } |
657 |
+ |
658 |
+diff -NurpP --minimal linux-2.6.29.4/arch/powerpc/kernel/vdso.c linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/kernel/vdso.c |
659 |
+--- linux-2.6.29.4/arch/powerpc/kernel/vdso.c 2009-03-24 14:18:35.000000000 +0100 |
660 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/kernel/vdso.c 2009-03-24 14:48:22.000000000 +0100 |
661 |
+@@ -22,6 +22,7 @@ |
662 |
+ #include <linux/security.h> |
663 |
+ #include <linux/bootmem.h> |
664 |
+ #include <linux/lmb.h> |
665 |
++#include <linux/vs_memory.h> |
666 |
+ |
667 |
+ #include <asm/pgtable.h> |
668 |
+ #include <asm/system.h> |
669 |
+diff -NurpP --minimal linux-2.6.29.4/arch/powerpc/mm/fault.c linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/mm/fault.c |
670 |
+--- linux-2.6.29.4/arch/powerpc/mm/fault.c 2009-03-24 14:18:36.000000000 +0100 |
671 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/powerpc/mm/fault.c 2009-03-24 14:48:22.000000000 +0100 |
672 |
+@@ -362,7 +362,8 @@ out_of_memory: |
673 |
+ down_read(&mm->mmap_sem); |
674 |
+ goto survive; |
675 |
+ } |
676 |
+- printk("VM: killing process %s\n", current->comm); |
677 |
++ printk("VM: killing process %s(%d:#%u)\n", |
678 |
++ current->comm, current->pid, current->xid); |
679 |
+ if (user_mode(regs)) |
680 |
+ do_group_exit(SIGKILL); |
681 |
+ return SIGKILL; |
682 |
+diff -NurpP --minimal linux-2.6.29.4/arch/s390/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/s390/Kconfig |
683 |
+--- linux-2.6.29.4/arch/s390/Kconfig 2009-03-24 14:18:38.000000000 +0100 |
684 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/s390/Kconfig 2009-03-24 14:48:22.000000000 +0100 |
685 |
+@@ -586,6 +586,8 @@ source "fs/Kconfig" |
686 |
+ |
687 |
+ source "arch/s390/Kconfig.debug" |
688 |
+ |
689 |
++source "kernel/vserver/Kconfig" |
690 |
++ |
691 |
+ source "security/Kconfig" |
692 |
+ |
693 |
+ source "crypto/Kconfig" |
694 |
+diff -NurpP --minimal linux-2.6.29.4/arch/s390/kernel/ptrace.c linux-2.6.29.4-vs2.3.0.36.14/arch/s390/kernel/ptrace.c |
695 |
+--- linux-2.6.29.4/arch/s390/kernel/ptrace.c 2009-03-24 14:18:40.000000000 +0100 |
696 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/s390/kernel/ptrace.c 2009-03-24 14:48:22.000000000 +0100 |
697 |
+@@ -36,6 +36,7 @@ |
698 |
+ #include <linux/elf.h> |
699 |
+ #include <linux/regset.h> |
700 |
+ #include <linux/tracehook.h> |
701 |
++#include <linux/vs_base.h> |
702 |
+ |
703 |
+ #include <asm/segment.h> |
704 |
+ #include <asm/page.h> |
705 |
+diff -NurpP --minimal linux-2.6.29.4/arch/s390/kernel/syscalls.S linux-2.6.29.4-vs2.3.0.36.14/arch/s390/kernel/syscalls.S |
706 |
+--- linux-2.6.29.4/arch/s390/kernel/syscalls.S 2009-03-24 14:18:40.000000000 +0100 |
707 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/s390/kernel/syscalls.S 2009-03-24 14:48:22.000000000 +0100 |
708 |
+@@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,sys_clock_sett |
709 |
+ SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper) /* 260 */ |
710 |
+ SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper) |
711 |
+ SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper) |
712 |
+-NI_SYSCALL /* reserved for vserver */ |
713 |
++SYSCALL(sys_vserver,sys_vserver,sys32_vserver) |
714 |
+ SYSCALL(sys_s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper) |
715 |
+ SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper) |
716 |
+ SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper) |
717 |
+diff -NurpP --minimal linux-2.6.29.4/arch/s390/mm/fault.c linux-2.6.29.4-vs2.3.0.36.14/arch/s390/mm/fault.c |
718 |
+--- linux-2.6.29.4/arch/s390/mm/fault.c 2008-12-25 00:26:37.000000000 +0100 |
719 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/s390/mm/fault.c 2009-02-22 22:54:24.000000000 +0100 |
720 |
+@@ -216,7 +216,8 @@ static int do_out_of_memory(struct pt_re |
721 |
+ down_read(&mm->mmap_sem); |
722 |
+ return 1; |
723 |
+ } |
724 |
+- printk("VM: killing process %s\n", tsk->comm); |
725 |
++ printk("VM: killing process %s(%d:#%u)\n", |
726 |
++ tsk->comm, tsk->pid, tsk->xid); |
727 |
+ if (regs->psw.mask & PSW_MASK_PSTATE) |
728 |
+ do_group_exit(SIGKILL); |
729 |
+ do_no_context(regs, error_code, address); |
730 |
+diff -NurpP --minimal linux-2.6.29.4/arch/sh/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/sh/Kconfig |
731 |
+--- linux-2.6.29.4/arch/sh/Kconfig 2009-03-24 14:18:40.000000000 +0100 |
732 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/sh/Kconfig 2009-03-24 14:48:22.000000000 +0100 |
733 |
+@@ -694,6 +694,8 @@ source "fs/Kconfig" |
734 |
+ |
735 |
+ source "arch/sh/Kconfig.debug" |
736 |
+ |
737 |
++source "kernel/vserver/Kconfig" |
738 |
++ |
739 |
+ source "security/Kconfig" |
740 |
+ |
741 |
+ source "crypto/Kconfig" |
742 |
+diff -NurpP --minimal linux-2.6.29.4/arch/sh/kernel/irq.c linux-2.6.29.4-vs2.3.0.36.14/arch/sh/kernel/irq.c |
743 |
+--- linux-2.6.29.4/arch/sh/kernel/irq.c 2008-12-25 00:26:37.000000000 +0100 |
744 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/sh/kernel/irq.c 2009-02-22 22:54:24.000000000 +0100 |
745 |
+@@ -11,6 +11,7 @@ |
746 |
+ #include <linux/module.h> |
747 |
+ #include <linux/kernel_stat.h> |
748 |
+ #include <linux/seq_file.h> |
749 |
++#include <linux/vs_context.h> |
750 |
+ #include <asm/processor.h> |
751 |
+ #include <asm/machvec.h> |
752 |
+ #include <asm/uaccess.h> |
753 |
+diff -NurpP --minimal linux-2.6.29.4/arch/sh/kernel/vsyscall/vsyscall.c linux-2.6.29.4-vs2.3.0.36.14/arch/sh/kernel/vsyscall/vsyscall.c |
754 |
+--- linux-2.6.29.4/arch/sh/kernel/vsyscall/vsyscall.c 2009-03-24 14:18:42.000000000 +0100 |
755 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/sh/kernel/vsyscall/vsyscall.c 2009-03-24 14:48:22.000000000 +0100 |
756 |
+@@ -19,6 +19,7 @@ |
757 |
+ #include <linux/elf.h> |
758 |
+ #include <linux/sched.h> |
759 |
+ #include <linux/err.h> |
760 |
++#include <linux/vs_memory.h> |
761 |
+ |
762 |
+ /* |
763 |
+ * Should the kernel map a VDSO page into processes and pass its |
764 |
+diff -NurpP --minimal linux-2.6.29.4/arch/sparc/include/asm/tlb_64.h linux-2.6.29.4-vs2.3.0.36.14/arch/sparc/include/asm/tlb_64.h |
765 |
+--- linux-2.6.29.4/arch/sparc/include/asm/tlb_64.h 2009-05-23 23:16:50.000000000 +0200 |
766 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/sparc/include/asm/tlb_64.h 2009-04-30 12:14:53.000000000 +0200 |
767 |
+@@ -3,6 +3,7 @@ |
768 |
+ |
769 |
+ #include <linux/swap.h> |
770 |
+ #include <linux/pagemap.h> |
771 |
++#include <linux/vs_memory.h> |
772 |
+ #include <asm/pgalloc.h> |
773 |
+ #include <asm/tlbflush.h> |
774 |
+ #include <asm/mmu_context.h> |
775 |
+diff -NurpP --minimal linux-2.6.29.4/arch/sparc/include/asm/unistd.h linux-2.6.29.4-vs2.3.0.36.14/arch/sparc/include/asm/unistd.h |
776 |
+--- linux-2.6.29.4/arch/sparc/include/asm/unistd.h 2009-03-24 14:18:44.000000000 +0100 |
777 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/sparc/include/asm/unistd.h 2009-04-08 15:52:53.000000000 +0200 |
778 |
+@@ -335,7 +335,7 @@ |
779 |
+ #define __NR_timer_getoverrun 264 |
780 |
+ #define __NR_timer_delete 265 |
781 |
+ #define __NR_timer_create 266 |
782 |
+-/* #define __NR_vserver 267 Reserved for VSERVER */ |
783 |
++#define __NR_vserver 267 |
784 |
+ #define __NR_io_setup 268 |
785 |
+ #define __NR_io_destroy 269 |
786 |
+ #define __NR_io_submit 270 |
787 |
+diff -NurpP --minimal linux-2.6.29.4/arch/sparc/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/sparc/Kconfig |
788 |
+--- linux-2.6.29.4/arch/sparc/Kconfig 2009-03-24 14:18:43.000000000 +0100 |
789 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/sparc/Kconfig 2009-03-24 14:48:22.000000000 +0100 |
790 |
+@@ -522,6 +522,8 @@ source "fs/Kconfig" |
791 |
+ |
792 |
+ source "arch/sparc/Kconfig.debug" |
793 |
+ |
794 |
++source "kernel/vserver/Kconfig" |
795 |
++ |
796 |
+ source "security/Kconfig" |
797 |
+ |
798 |
+ source "crypto/Kconfig" |
799 |
+diff -NurpP --minimal linux-2.6.29.4/arch/sparc/kernel/systbls_32.S linux-2.6.29.4-vs2.3.0.36.14/arch/sparc/kernel/systbls_32.S |
800 |
+--- linux-2.6.29.4/arch/sparc/kernel/systbls_32.S 2009-03-24 14:18:45.000000000 +0100 |
801 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/sparc/kernel/systbls_32.S 2009-04-08 15:57:59.000000000 +0200 |
802 |
+@@ -70,7 +70,7 @@ sys_call_table: |
803 |
+ /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl |
804 |
+ /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep |
805 |
+ /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun |
806 |
+-/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy |
807 |
++/*265*/ .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy |
808 |
+ /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink |
809 |
+ /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid |
810 |
+ /*280*/ .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat |
811 |
+diff -NurpP --minimal linux-2.6.29.4/arch/sparc/kernel/systbls_64.S linux-2.6.29.4-vs2.3.0.36.14/arch/sparc/kernel/systbls_64.S |
812 |
+--- linux-2.6.29.4/arch/sparc/kernel/systbls_64.S 2009-03-24 14:18:45.000000000 +0100 |
813 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/sparc/kernel/systbls_64.S 2009-04-08 15:56:23.000000000 +0200 |
814 |
+@@ -71,7 +71,7 @@ sys_call_table32: |
815 |
+ /*250*/ .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl |
816 |
+ .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep |
817 |
+ /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun |
818 |
+- .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy |
819 |
++ .word sys_timer_delete, compat_sys_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy |
820 |
+ /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink |
821 |
+ .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid |
822 |
+ /*280*/ .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat |
823 |
+@@ -145,7 +145,7 @@ sys_call_table: |
824 |
+ /*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl |
825 |
+ .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep |
826 |
+ /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun |
827 |
+- .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy |
828 |
++ .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy |
829 |
+ /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink |
830 |
+ .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid |
831 |
+ /*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat |
832 |
+diff -NurpP --minimal linux-2.6.29.4/arch/x86/ia32/ia32entry.S linux-2.6.29.4-vs2.3.0.36.14/arch/x86/ia32/ia32entry.S |
833 |
+--- linux-2.6.29.4/arch/x86/ia32/ia32entry.S 2009-03-24 14:18:48.000000000 +0100 |
834 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/x86/ia32/ia32entry.S 2009-03-22 23:29:11.000000000 +0100 |
835 |
+@@ -768,7 +768,7 @@ ia32_sys_call_table: |
836 |
+ .quad sys_tgkill /* 270 */ |
837 |
+ .quad compat_sys_utimes |
838 |
+ .quad sys32_fadvise64_64 |
839 |
+- .quad quiet_ni_syscall /* sys_vserver */ |
840 |
++ .quad sys32_vserver |
841 |
+ .quad sys_mbind |
842 |
+ .quad compat_sys_get_mempolicy /* 275 */ |
843 |
+ .quad sys_set_mempolicy |
844 |
+diff -NurpP --minimal linux-2.6.29.4/arch/x86/include/asm/unistd_64.h linux-2.6.29.4-vs2.3.0.36.14/arch/x86/include/asm/unistd_64.h |
845 |
+--- linux-2.6.29.4/arch/x86/include/asm/unistd_64.h 2008-12-25 00:26:37.000000000 +0100 |
846 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/x86/include/asm/unistd_64.h 2009-02-22 22:54:24.000000000 +0100 |
847 |
+@@ -535,7 +535,7 @@ __SYSCALL(__NR_tgkill, sys_tgkill) |
848 |
+ #define __NR_utimes 235 |
849 |
+ __SYSCALL(__NR_utimes, sys_utimes) |
850 |
+ #define __NR_vserver 236 |
851 |
+-__SYSCALL(__NR_vserver, sys_ni_syscall) |
852 |
++__SYSCALL(__NR_vserver, sys_vserver) |
853 |
+ #define __NR_mbind 237 |
854 |
+ __SYSCALL(__NR_mbind, sys_mbind) |
855 |
+ #define __NR_set_mempolicy 238 |
856 |
+diff -NurpP --minimal linux-2.6.29.4/arch/x86/Kconfig linux-2.6.29.4-vs2.3.0.36.14/arch/x86/Kconfig |
857 |
+--- linux-2.6.29.4/arch/x86/Kconfig 2009-03-24 14:18:47.000000000 +0100 |
858 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/x86/Kconfig 2009-03-24 14:48:23.000000000 +0100 |
859 |
+@@ -1990,6 +1990,8 @@ source "fs/Kconfig" |
860 |
+ |
861 |
+ source "arch/x86/Kconfig.debug" |
862 |
+ |
863 |
++source "kernel/vserver/Kconfig" |
864 |
++ |
865 |
+ source "security/Kconfig" |
866 |
+ |
867 |
+ source "crypto/Kconfig" |
868 |
+diff -NurpP --minimal linux-2.6.29.4/arch/x86/kernel/syscall_table_32.S linux-2.6.29.4-vs2.3.0.36.14/arch/x86/kernel/syscall_table_32.S |
869 |
+--- linux-2.6.29.4/arch/x86/kernel/syscall_table_32.S 2009-03-24 14:18:51.000000000 +0100 |
870 |
++++ linux-2.6.29.4-vs2.3.0.36.14/arch/x86/kernel/syscall_table_32.S 2009-02-22 22:54:24.000000000 +0100 |
871 |
+@@ -272,7 +272,7 @@ ENTRY(sys_call_table) |
872 |
+ .long sys_tgkill /* 270 */ |
873 |
+ .long sys_utimes |
874 |
+ .long sys_fadvise64_64 |
875 |
+- .long sys_ni_syscall /* sys_vserver */ |
876 |
++ .long sys_vserver |
877 |
+ .long sys_mbind |
878 |
+ .long sys_get_mempolicy |
879 |
+ .long sys_set_mempolicy |
880 |
+diff -NurpP --minimal linux-2.6.29.4/Documentation/vserver/debug.txt linux-2.6.29.4-vs2.3.0.36.14/Documentation/vserver/debug.txt |
881 |
+--- linux-2.6.29.4/Documentation/vserver/debug.txt 1970-01-01 01:00:00.000000000 +0100 |
882 |
++++ linux-2.6.29.4-vs2.3.0.36.14/Documentation/vserver/debug.txt 2009-02-22 22:54:24.000000000 +0100 |
883 |
+@@ -0,0 +1,154 @@ |
884 |
++ |
885 |
++debug_cvirt: |
886 |
++ |
887 |
++ 2 4 "vx_map_tgid: %p/%llx: %d -> %d" |
888 |
++ "vx_rmap_tgid: %p/%llx: %d -> %d" |
889 |
++ |
890 |
++debug_dlim: |
891 |
++ |
892 |
++ 0 1 "ALLOC (%p,#%d)%c inode (%d)" |
893 |
++ "FREE (%p,#%d)%c inode" |
894 |
++ 1 2 "ALLOC (%p,#%d)%c %lld bytes (%d)" |
895 |
++ "FREE (%p,#%d)%c %lld bytes" |
896 |
++ 2 4 "ADJUST: %lld,%lld on %ld,%ld [mult=%d]" |
897 |
++ 3 8 "ext3_has_free_blocks(%p): %lu<%lu+1, %c, %u!=%u r=%d" |
898 |
++ "ext3_has_free_blocks(%p): free=%lu, root=%lu" |
899 |
++ "rcu_free_dl_info(%p)" |
900 |
++ 4 10 "alloc_dl_info(%p,%d) = %p" |
901 |
++ "dealloc_dl_info(%p)" |
902 |
++ "get_dl_info(%p[#%d.%d])" |
903 |
++ "put_dl_info(%p[#%d.%d])" |
904 |
++ 5 20 "alloc_dl_info(%p,%d)*" |
905 |
++ 6 40 "__hash_dl_info: %p[#%d]" |
906 |
++ "__unhash_dl_info: %p[#%d]" |
907 |
++ 7 80 "locate_dl_info(%p,#%d) = %p" |
908 |
++ |
909 |
++debug_misc: |
910 |
++ |
911 |
++ 0 1 "destroy_dqhash: %p [#0x%08x] c=%d" |
912 |
++ "new_dqhash: %p [#0x%08x]" |
913 |
++ "vroot[%d]_clr_dev: dev=%p[%lu,%d:%d]" |
914 |
++ "vroot[%d]_get_real_bdev: dev=%p[%lu,%d:%d]" |
915 |
++ "vroot[%d]_set_dev: dev=%p[%lu,%d:%d]" |
916 |
++ "vroot_get_real_bdev not set" |
917 |
++ 1 2 "cow_break_link(»%s«)" |
918 |
++ "temp copy »%s«" |
919 |
++ 2 4 "dentry_open(new): %p" |
920 |
++ "dentry_open(old): %p" |
921 |
++ "lookup_create(new): %p" |
922 |
++ "old path »%s«" |
923 |
++ "path_lookup(old): %d" |
924 |
++ "vfs_create(new): %d" |
925 |
++ "vfs_rename: %d" |
926 |
++ "vfs_sendfile: %d" |
927 |
++ 3 8 "fput(new_file=%p[#%d])" |
928 |
++ "fput(old_file=%p[#%d])" |
929 |
++ 4 10 "vx_info_kill(%p[#%d],%d,%d) = %d" |
930 |
++ "vx_info_kill(%p[#%d],%d,%d)*" |
931 |
++ 5 20 "vs_reboot(%p[#%d],%d)" |
932 |
++ 6 40 "dropping task %p[#%u,%u] for %p[#%u,%u]" |
933 |
++ |
934 |
++debug_net: |
935 |
++ |
936 |
++ 2 4 "nx_addr_conflict(%p,%p) %d.%d,%d.%d" |
937 |
++ 3 8 "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d" |
938 |
++ "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d" |
939 |
++ 4 10 "ip_route_connect(%p) %p,%p;%lx" |
940 |
++ 5 20 "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx" |
941 |
++ 6 40 "sk,egf: %p [#%d] (from %d)" |
942 |
++ "sk,egn: %p [#%d] (from %d)" |
943 |
++ "sk,req: %p [#%d] (from %d)" |
944 |
++ "sk: %p [#%d] (from %d)" |
945 |
++ "tw: %p [#%d] (from %d)" |
946 |
++ 7 80 "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d" |
947 |
++ "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d" |
948 |
++ |
949 |
++debug_nid: |
950 |
++ |
951 |
++ 0 1 "__lookup_nx_info(#%u): %p[#%u]" |
952 |
++ "alloc_nx_info(%d) = %p" |
953 |
++ "create_nx_info(%d) (dynamic rejected)" |
954 |
++ "create_nx_info(%d) = %p (already there)" |
955 |
++ "create_nx_info(%d) = %p (new)" |
956 |
++ "dealloc_nx_info(%p)" |
957 |
++ 1 2 "alloc_nx_info(%d)*" |
958 |
++ "create_nx_info(%d)*" |
959 |
++ 2 4 "get_nx_info(%p[#%d.%d])" |
960 |
++ "put_nx_info(%p[#%d.%d])" |
961 |
++ 3 8 "claim_nx_info(%p[#%d.%d.%d]) %p" |
962 |
++ "clr_nx_info(%p[#%d.%d])" |
963 |
++ "init_nx_info(%p[#%d.%d])" |
964 |
++ "release_nx_info(%p[#%d.%d.%d]) %p" |
965 |
++ "set_nx_info(%p[#%d.%d])" |
966 |
++ 4 10 "__hash_nx_info: %p[#%d]" |
967 |
++ "__nx_dynamic_id: [#%d]" |
968 |
++ "__unhash_nx_info: %p[#%d.%d.%d]" |
969 |
++ 5 20 "moved task %p into nxi:%p[#%d]" |
970 |
++ "nx_migrate_task(%p,%p[#%d.%d.%d])" |
971 |
++ "task_get_nx_info(%p)" |
972 |
++ 6 40 "nx_clear_persistent(%p[#%d])" |
973 |
++ |
974 |
++debug_quota: |
975 |
++ |
976 |
++ 0 1 "quota_sync_dqh(%p,%d) discard inode %p" |
977 |
++ 1 2 "quota_sync_dqh(%p,%d)" |
978 |
++ "sync_dquots(%p,%d)" |
979 |
++ "sync_dquots_dqh(%p,%d)" |
980 |
++ 3 8 "do_quotactl(%p,%d,cmd=%d,id=%d,%p)" |
981 |
++ |
982 |
++debug_switch: |
983 |
++ |
984 |
++ 0 1 "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]" |
985 |
++ 1 2 "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]" |
986 |
++ 4 10 "%s: (%s %s) returned %s with %d" |
987 |
++ |
988 |
++debug_tag: |
989 |
++ |
990 |
++ 7 80 "dx_parse_tag(»%s«): %d:#%d" |
991 |
++ "dx_propagate_tag(%p[#%lu.%d]): %d,%d" |
992 |
++ |
993 |
++debug_xid: |
994 |
++ |
995 |
++ 0 1 "__lookup_vx_info(#%u): %p[#%u]" |
996 |
++ "alloc_vx_info(%d) = %p" |
997 |
++ "alloc_vx_info(%d)*" |
998 |
++ "create_vx_info(%d) (dynamic rejected)" |
999 |
++ "create_vx_info(%d) = %p (already there)" |
1000 |
++ "create_vx_info(%d) = %p (new)" |
1001 |
++ "dealloc_vx_info(%p)" |
1002 |
++ "loc_vx_info(%d) = %p (found)" |
1003 |
++ "loc_vx_info(%d) = %p (new)" |
1004 |
++ "loc_vx_info(%d) = %p (not available)" |
1005 |
++ 1 2 "create_vx_info(%d)*" |
1006 |
++ "loc_vx_info(%d)*" |
1007 |
++ 2 4 "get_vx_info(%p[#%d.%d])" |
1008 |
++ "put_vx_info(%p[#%d.%d])" |
1009 |
++ 3 8 "claim_vx_info(%p[#%d.%d.%d]) %p" |
1010 |
++ "clr_vx_info(%p[#%d.%d])" |
1011 |
++ "init_vx_info(%p[#%d.%d])" |
1012 |
++ "release_vx_info(%p[#%d.%d.%d]) %p" |
1013 |
++ "set_vx_info(%p[#%d.%d])" |
1014 |
++ 4 10 "__hash_vx_info: %p[#%d]" |
1015 |
++ "__unhash_vx_info: %p[#%d.%d.%d]" |
1016 |
++ "__vx_dynamic_id: [#%d]" |
1017 |
++ 5 20 "enter_vx_info(%p[#%d],%p) %p[#%d,%p]" |
1018 |
++ "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]" |
1019 |
++ "moved task %p into vxi:%p[#%d]" |
1020 |
++ "task_get_vx_info(%p)" |
1021 |
++ "vx_migrate_task(%p,%p[#%d.%d])" |
1022 |
++ 6 40 "vx_clear_persistent(%p[#%d])" |
1023 |
++ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])" |
1024 |
++ "vx_set_init(%p[#%d],%p[#%d,%d,%d])" |
1025 |
++ "vx_set_persistent(%p[#%d])" |
1026 |
++ "vx_set_reaper(%p[#%d],%p[#%d,%d])" |
1027 |
++ 7 80 "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]" |
1028 |
++ |
1029 |
++ |
1030 |
++debug_limit: |
1031 |
++ |
1032 |
++ n 2^n "vx_acc_cres[%5d,%s,%2d]: %5d%s" |
1033 |
++ "vx_cres_avail[%5d,%s,%2d]: %5ld > %5d + %5d" |
1034 |
++ |
1035 |
++ m 2^m "vx_acc_page[%5d,%s,%2d]: %5d%s" |
1036 |
++ "vx_acc_pages[%5d,%s,%2d]: %5d += %5d" |
1037 |
++ "vx_pages_avail[%5d,%s,%2d]: %5ld > %5d + %5d" |
1038 |
+diff -NurpP --minimal linux-2.6.29.4/drivers/block/Kconfig linux-2.6.29.4-vs2.3.0.36.14/drivers/block/Kconfig |
1039 |
+--- linux-2.6.29.4/drivers/block/Kconfig 2008-12-25 00:26:37.000000000 +0100 |
1040 |
++++ linux-2.6.29.4-vs2.3.0.36.14/drivers/block/Kconfig 2009-02-22 22:54:24.000000000 +0100 |
1041 |
+@@ -264,6 +264,13 @@ config BLK_DEV_CRYPTOLOOP |
1042 |
+ instead, which can be configured to be on-disk compatible with the |
1043 |
+ cryptoloop device. |
1044 |
+ |
1045 |
++config BLK_DEV_VROOT |
1046 |
++ tristate "Virtual Root device support" |
1047 |
++ depends on QUOTACTL |
1048 |
++ ---help--- |
1049 |
++ Saying Y here will allow you to use quota/fs ioctls on a shared |
1050 |
++ partition within a virtual server without compromising security. |
1051 |
++ |
1052 |
+ config BLK_DEV_NBD |
1053 |
+ tristate "Network block device support" |
1054 |
+ depends on NET |
1055 |
+diff -NurpP --minimal linux-2.6.29.4/drivers/block/loop.c linux-2.6.29.4-vs2.3.0.36.14/drivers/block/loop.c |
1056 |
+--- linux-2.6.29.4/drivers/block/loop.c 2009-03-24 14:18:56.000000000 +0100 |
1057 |
++++ linux-2.6.29.4-vs2.3.0.36.14/drivers/block/loop.c 2009-03-24 15:09:29.000000000 +0100 |
1058 |
+@@ -75,6 +75,7 @@ |
1059 |
+ #include <linux/gfp.h> |
1060 |
+ #include <linux/kthread.h> |
1061 |
+ #include <linux/splice.h> |
1062 |
++#include <linux/vs_context.h> |
1063 |
+ |
1064 |
+ #include <asm/uaccess.h> |
1065 |
+ |
1066 |
+@@ -809,6 +810,7 @@ static int loop_set_fd(struct loop_devic |
1067 |
+ lo->lo_blocksize = lo_blocksize; |
1068 |
+ lo->lo_device = bdev; |
1069 |
+ lo->lo_flags = lo_flags; |
1070 |
++ lo->lo_xid = vx_current_xid(); |
1071 |
+ lo->lo_backing_file = file; |
1072 |
+ lo->transfer = transfer_none; |
1073 |
+ lo->ioctl = NULL; |
1074 |
+@@ -931,6 +933,7 @@ static int loop_clr_fd(struct loop_devic |
1075 |
+ lo->lo_encrypt_key_size = 0; |
1076 |
+ lo->lo_flags = 0; |
1077 |
+ lo->lo_thread = NULL; |
1078 |
++ lo->lo_xid = 0; |
1079 |
+ memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); |
1080 |
+ memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); |
1081 |
+ memset(lo->lo_file_name, 0, LO_NAME_SIZE); |
1082 |
+@@ -958,7 +961,7 @@ loop_set_status(struct loop_device *lo, |
1083 |
+ |
1084 |
+ if (lo->lo_encrypt_key_size && |
1085 |
+ lo->lo_key_owner != uid && |
1086 |
+- !capable(CAP_SYS_ADMIN)) |
1087 |
++ !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) |
1088 |
+ return -EPERM; |
1089 |
+ if (lo->lo_state != Lo_bound) |
1090 |
+ return -ENXIO; |
1091 |
+@@ -1042,7 +1045,8 @@ loop_get_status(struct loop_device *lo, |
1092 |
+ memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE); |
1093 |
+ info->lo_encrypt_type = |
1094 |
+ lo->lo_encryption ? lo->lo_encryption->number : 0; |
1095 |
+- if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) { |
1096 |
++ if (lo->lo_encrypt_key_size && |
1097 |
++ vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) { |
1098 |
+ info->lo_encrypt_key_size = lo->lo_encrypt_key_size; |
1099 |
+ memcpy(info->lo_encrypt_key, lo->lo_encrypt_key, |
1100 |
+ lo->lo_encrypt_key_size); |
1101 |
+@@ -1351,6 +1355,9 @@ static int lo_open(struct block_device * |
1102 |
+ { |
1103 |
+ struct loop_device *lo = bdev->bd_disk->private_data; |
1104 |
+ |
1105 |
++ if (!vx_check(lo->lo_xid, VS_IDENT|VS_HOSTID|VS_ADMIN_P)) |
1106 |
++ return -EACCES; |
1107 |
++ |
1108 |
+ mutex_lock(&lo->lo_ctl_mutex); |
1109 |
+ lo->lo_refcnt++; |
1110 |
+ mutex_unlock(&lo->lo_ctl_mutex); |
1111 |
+diff -NurpP --minimal linux-2.6.29.4/drivers/block/Makefile linux-2.6.29.4-vs2.3.0.36.14/drivers/block/Makefile |
1112 |
+--- linux-2.6.29.4/drivers/block/Makefile 2009-03-24 14:18:55.000000000 +0100 |
1113 |
++++ linux-2.6.29.4-vs2.3.0.36.14/drivers/block/Makefile 2009-03-24 14:48:25.000000000 +0100 |
1114 |
+@@ -31,5 +31,6 @@ obj-$(CONFIG_VIODASD) += viodasd.o |
1115 |
+ obj-$(CONFIG_BLK_DEV_SX8) += sx8.o |
1116 |
+ obj-$(CONFIG_BLK_DEV_UB) += ub.o |
1117 |
+ obj-$(CONFIG_BLK_DEV_HD) += hd.o |
1118 |
++obj-$(CONFIG_BLK_DEV_VROOT) += vroot.o |
1119 |
+ |
1120 |
+ obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o |
1121 |
+diff -NurpP --minimal linux-2.6.29.4/drivers/block/vroot.c linux-2.6.29.4-vs2.3.0.36.14/drivers/block/vroot.c |
1122 |
+--- linux-2.6.29.4/drivers/block/vroot.c 1970-01-01 01:00:00.000000000 +0100 |
1123 |
++++ linux-2.6.29.4-vs2.3.0.36.14/drivers/block/vroot.c 2009-02-22 22:54:24.000000000 +0100 |
1124 |
+@@ -0,0 +1,281 @@ |
1125 |
++/* |
1126 |
++ * linux/drivers/block/vroot.c |
1127 |
++ * |
1128 |
++ * written by Herbert Pötzl, 9/11/2002 |
1129 |
++ * ported to 2.6.10 by Herbert Pötzl, 30/12/2004 |
1130 |
++ * |
1131 |
++ * based on the loop.c code by Theodore Ts'o. |
1132 |
++ * |
1133 |
++ * Copyright (C) 2002-2007 by Herbert Pötzl. |
1134 |
++ * Redistribution of this file is permitted under the |
1135 |
++ * GNU General Public License. |
1136 |
++ * |
1137 |
++ */ |
1138 |
++ |
1139 |
++#include <linux/module.h> |
1140 |
++#include <linux/moduleparam.h> |
1141 |
++#include <linux/file.h> |
1142 |
++#include <linux/major.h> |
1143 |
++#include <linux/blkdev.h> |
1144 |
++ |
1145 |
++#include <linux/vroot.h> |
1146 |
++#include <linux/vs_context.h> |
1147 |
++ |
1148 |
++ |
1149 |
++static int max_vroot = 8; |
1150 |
++ |
1151 |
++static struct vroot_device *vroot_dev; |
1152 |
++static struct gendisk **disks; |
1153 |
++ |
1154 |
++ |
1155 |
++static int vroot_set_dev( |
1156 |
++ struct vroot_device *vr, |
1157 |
++ struct block_device *bdev, |
1158 |
++ unsigned int arg) |
1159 |
++{ |
1160 |
++ struct block_device *real_bdev; |
1161 |
++ struct file *file; |
1162 |
++ struct inode *inode; |
1163 |
++ int error; |
1164 |
++ |
1165 |
++ error = -EBUSY; |
1166 |
++ if (vr->vr_state != Vr_unbound) |
1167 |
++ goto out; |
1168 |
++ |
1169 |
++ error = -EBADF; |
1170 |
++ file = fget(arg); |
1171 |
++ if (!file) |
1172 |
++ goto out; |
1173 |
++ |
1174 |
++ error = -EINVAL; |
1175 |
++ inode = file->f_dentry->d_inode; |
1176 |
++ |
1177 |
++ |
1178 |
++ if (S_ISBLK(inode->i_mode)) { |
1179 |
++ real_bdev = inode->i_bdev; |
1180 |
++ vr->vr_device = real_bdev; |
1181 |
++ __iget(real_bdev->bd_inode); |
1182 |
++ } else |
1183 |
++ goto out_fput; |
1184 |
++ |
1185 |
++ vxdprintk(VXD_CBIT(misc, 0), |
1186 |
++ "vroot[%d]_set_dev: dev=" VXF_DEV, |
1187 |
++ vr->vr_number, VXD_DEV(real_bdev)); |
1188 |
++ |
1189 |
++ vr->vr_state = Vr_bound; |
1190 |
++ error = 0; |
1191 |
++ |
1192 |
++ out_fput: |
1193 |
++ fput(file); |
1194 |
++ out: |
1195 |
++ return error; |
1196 |
++} |
1197 |
++ |
1198 |
++static int vroot_clr_dev( |
1199 |
++ struct vroot_device *vr, |
1200 |
++ struct block_device *bdev) |
1201 |
++{ |
1202 |
++ struct block_device *real_bdev; |
1203 |
++ |
1204 |
++ if (vr->vr_state != Vr_bound) |
1205 |
++ return -ENXIO; |
1206 |
++ if (vr->vr_refcnt > 1) /* we needed one fd for the ioctl */ |
1207 |
++ return -EBUSY; |
1208 |
++ |
1209 |
++ real_bdev = vr->vr_device; |
1210 |
++ |
1211 |
++ vxdprintk(VXD_CBIT(misc, 0), |
1212 |
++ "vroot[%d]_clr_dev: dev=" VXF_DEV, |
1213 |
++ vr->vr_number, VXD_DEV(real_bdev)); |
1214 |
++ |
1215 |
++ bdput(real_bdev); |
1216 |
++ vr->vr_state = Vr_unbound; |
1217 |
++ vr->vr_device = NULL; |
1218 |
++ return 0; |
1219 |
++} |
1220 |
++ |
1221 |
++ |
1222 |
++static int vr_ioctl(struct block_device *bdev, fmode_t mode, |
1223 |
++ unsigned int cmd, unsigned long arg) |
1224 |
++{ |
1225 |
++ struct vroot_device *vr = bdev->bd_disk->private_data; |
1226 |
++ int err; |
1227 |
++ |
1228 |
++ down(&vr->vr_ctl_mutex); |
1229 |
++ switch (cmd) { |
1230 |
++ case VROOT_SET_DEV: |
1231 |
++ err = vroot_set_dev(vr, bdev, arg); |
1232 |
++ break; |
1233 |
++ case VROOT_CLR_DEV: |
1234 |
++ err = vroot_clr_dev(vr, bdev); |
1235 |
++ break; |
1236 |
++ default: |
1237 |
++ err = -EINVAL; |
1238 |
++ break; |
1239 |
++ } |
1240 |
++ up(&vr->vr_ctl_mutex); |
1241 |
++ return err; |
1242 |
++} |
1243 |
++ |
1244 |
++static int vr_open(struct block_device *bdev, fmode_t mode) |
1245 |
++{ |
1246 |
++ struct vroot_device *vr = bdev->bd_disk->private_data; |
1247 |
++ |
1248 |
++ down(&vr->vr_ctl_mutex); |
1249 |
++ vr->vr_refcnt++; |
1250 |
++ up(&vr->vr_ctl_mutex); |
1251 |
++ return 0; |
1252 |
++} |
1253 |
++ |
1254 |
++static int vr_release(struct gendisk *disk, fmode_t mode) |
1255 |
++{ |
1256 |
++ struct vroot_device *vr = disk->private_data; |
1257 |
++ |
1258 |
++ down(&vr->vr_ctl_mutex); |
1259 |
++ --vr->vr_refcnt; |
1260 |
++ up(&vr->vr_ctl_mutex); |
1261 |
++ return 0; |
1262 |
++} |
1263 |
++ |
1264 |
++static struct block_device_operations vr_fops = { |
1265 |
++ .owner = THIS_MODULE, |
1266 |
++ .open = vr_open, |
1267 |
++ .release = vr_release, |
1268 |
++ .ioctl = vr_ioctl, |
1269 |
++}; |
1270 |
++ |
1271 |
++struct block_device *__vroot_get_real_bdev(struct block_device *bdev) |
1272 |
++{ |
1273 |
++ struct inode *inode = bdev->bd_inode; |
1274 |
++ struct vroot_device *vr; |
1275 |
++ struct block_device *real_bdev; |
1276 |
++ int minor = iminor(inode); |
1277 |
++ |
1278 |
++ vr = &vroot_dev[minor]; |
1279 |
++ real_bdev = vr->vr_device; |
1280 |
++ |
1281 |
++ vxdprintk(VXD_CBIT(misc, 0), |
1282 |
++ "vroot[%d]_get_real_bdev: dev=" VXF_DEV, |
1283 |
++ vr->vr_number, VXD_DEV(real_bdev)); |
1284 |
++ |
1285 |
++ if (vr->vr_state != Vr_bound) |
1286 |
++ return ERR_PTR(-ENXIO); |
1287 |
++ |
1288 |
++ __iget(real_bdev->bd_inode); |
1289 |
++ return real_bdev; |
1290 |
++} |
1291 |
++ |
1292 |
++/* |
1293 |
++ * And now the modules code and kernel interface. |
1294 |
++ */ |
1295 |
++ |
1296 |
++module_param(max_vroot, int, 0); |
1297 |
++ |
1298 |
++MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)"); |
1299 |
++MODULE_LICENSE("GPL"); |
1300 |
++MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR); |
1301 |
++ |
1302 |
++MODULE_AUTHOR ("Herbert Pötzl"); |
1303 |
++MODULE_DESCRIPTION ("Virtual Root Device Mapper"); |
1304 |
++ |
1305 |
++ |
1306 |
++int __init vroot_init(void) |
1307 |
++{ |
1308 |
++ int err, i; |
1309 |
++ |
1310 |
++ if (max_vroot < 1 || max_vroot > 256) { |
1311 |
++ max_vroot = MAX_VROOT_DEFAULT; |
1312 |
++ printk(KERN_WARNING "vroot: invalid max_vroot " |
1313 |
++ "(must be between 1 and 256), " |
1314 |
++ "using default (%d)\n", max_vroot); |
1315 |
++ } |
1316 |
++ |
1317 |
++ if (register_blkdev(VROOT_MAJOR, "vroot")) |
1318 |
++ return -EIO; |
1319 |
++ |
1320 |
++ err = -ENOMEM; |
1321 |
++ vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL); |
1322 |
++ if (!vroot_dev) |
1323 |
++ goto out_mem1; |
1324 |
++ memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device)); |
1325 |
++ |
1326 |
++ disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL); |
1327 |
++ if (!disks) |
1328 |
++ goto out_mem2; |
1329 |
++ |
1330 |
++ for (i = 0; i < max_vroot; i++) { |
1331 |
++ disks[i] = alloc_disk(1); |
1332 |
++ if (!disks[i]) |
1333 |
++ goto out_mem3; |
1334 |
++ disks[i]->queue = blk_alloc_queue(GFP_KERNEL); |
1335 |
++ if (!disks[i]->queue) |
1336 |
++ goto out_mem3; |
1337 |
++ } |
1338 |
++ |
1339 |
++ for (i = 0; i < max_vroot; i++) { |
1340 |
++ struct vroot_device *vr = &vroot_dev[i]; |
1341 |
++ struct gendisk *disk = disks[i]; |
1342 |
++ |
1343 |
++ memset(vr, 0, sizeof(*vr)); |
1344 |
++ init_MUTEX(&vr->vr_ctl_mutex); |
1345 |
++ vr->vr_number = i; |
1346 |
++ disk->major = VROOT_MAJOR; |
1347 |
++ disk->first_minor = i; |
1348 |
++ disk->fops = &vr_fops; |
1349 |
++ sprintf(disk->disk_name, "vroot%d", i); |
1350 |
++ disk->private_data = vr; |
1351 |
++ } |
1352 |
++ |
1353 |
++ err = register_vroot_grb(&__vroot_get_real_bdev); |
1354 |
++ if (err) |
1355 |
++ goto out_mem3; |
1356 |
++ |
1357 |
++ for (i = 0; i < max_vroot; i++) |
1358 |
++ add_disk(disks[i]); |
1359 |
++ printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot); |
1360 |
++ return 0; |
1361 |
++ |
1362 |
++out_mem3: |
1363 |
++ while (i--) |
1364 |
++ put_disk(disks[i]); |
1365 |
++ kfree(disks); |
1366 |
++out_mem2: |
1367 |
++ kfree(vroot_dev); |
1368 |
++out_mem1: |
1369 |
++ unregister_blkdev(VROOT_MAJOR, "vroot"); |
1370 |
++ printk(KERN_ERR "vroot: ran out of memory\n"); |
1371 |
++ return err; |
1372 |
++} |
1373 |
++ |
1374 |
++void vroot_exit(void) |
1375 |
++{ |
1376 |
++ int i; |
1377 |
++ |
1378 |
++ if (unregister_vroot_grb(&__vroot_get_real_bdev)) |
1379 |
++ printk(KERN_WARNING "vroot: cannot unregister grb\n"); |
1380 |
++ |
1381 |
++ for (i = 0; i < max_vroot; i++) { |
1382 |
++ del_gendisk(disks[i]); |
1383 |
++ put_disk(disks[i]); |
1384 |
++ } |
1385 |
++ unregister_blkdev(VROOT_MAJOR, "vroot"); |
1386 |
++ |
1387 |
++ kfree(disks); |
1388 |
++ kfree(vroot_dev); |
1389 |
++} |
1390 |
++ |
1391 |
++module_init(vroot_init); |
1392 |
++module_exit(vroot_exit); |
1393 |
++ |
1394 |
++#ifndef MODULE |
1395 |
++ |
1396 |
++static int __init max_vroot_setup(char *str) |
1397 |
++{ |
1398 |
++ max_vroot = simple_strtol(str, NULL, 0); |
1399 |
++ return 1; |
1400 |
++} |
1401 |
++ |
1402 |
++__setup("max_vroot=", max_vroot_setup); |
1403 |
++ |
1404 |
++#endif |
1405 |
++ |
1406 |
+diff -NurpP --minimal linux-2.6.29.4/drivers/char/sysrq.c linux-2.6.29.4-vs2.3.0.36.14/drivers/char/sysrq.c |
1407 |
+--- linux-2.6.29.4/drivers/char/sysrq.c 2009-03-24 14:18:57.000000000 +0100 |
1408 |
++++ linux-2.6.29.4-vs2.3.0.36.14/drivers/char/sysrq.c 2009-03-24 15:15:27.000000000 +0100 |
1409 |
+@@ -38,6 +38,7 @@ |
1410 |
+ #include <linux/irq.h> |
1411 |
+ #include <linux/hrtimer.h> |
1412 |
+ #include <linux/oom.h> |
1413 |
++#include <linux/vserver/debug.h> |
1414 |
+ |
1415 |
+ #include <asm/ptrace.h> |
1416 |
+ #include <asm/irq_regs.h> |
1417 |
+@@ -369,6 +370,21 @@ static struct sysrq_key_op sysrq_unrt_op |
1418 |
+ .enable_mask = SYSRQ_ENABLE_RTNICE, |
1419 |
+ }; |
1420 |
+ |
1421 |
++ |
1422 |
++#ifdef CONFIG_VSERVER_DEBUG |
1423 |
++static void sysrq_handle_vxinfo(int key, struct tty_struct *tty) |
1424 |
++{ |
1425 |
++ dump_vx_info_inactive((key == 'x')?0:1); |
1426 |
++} |
1427 |
++ |
1428 |
++static struct sysrq_key_op sysrq_showvxinfo_op = { |
1429 |
++ .handler = sysrq_handle_vxinfo, |
1430 |
++ .help_msg = "conteXt", |
1431 |
++ .action_msg = "Show Context Info", |
1432 |
++ .enable_mask = SYSRQ_ENABLE_DUMP, |
1433 |
++}; |
1434 |
++#endif |
1435 |
++ |
1436 |
+ /* Key Operations table and lock */ |
1437 |
+ static DEFINE_SPINLOCK(sysrq_key_table_lock); |
1438 |
+ |
1439 |
+@@ -419,7 +435,11 @@ static struct sysrq_key_op *sysrq_key_ta |
1440 |
+ NULL, /* v */ |
1441 |
+ &sysrq_showstate_blocked_op, /* w */ |
1442 |
+ /* x: May be registered on ppc/powerpc for xmon */ |
1443 |
++#ifdef CONFIG_VSERVER_DEBUG |
1444 |
++ &sysrq_showvxinfo_op, /* x */ |
1445 |
++#else |
1446 |
+ NULL, /* x */ |
1447 |
++#endif |
1448 |
+ /* y: May be registered on sparc64 for global register dump */ |
1449 |
+ NULL, /* y */ |
1450 |
+ &sysrq_ftrace_dump_op, /* z */ |
1451 |
+@@ -434,6 +454,8 @@ static int sysrq_key_table_key2index(int |
1452 |
+ retval = key - '0'; |
1453 |
+ else if ((key >= 'a') && (key <= 'z')) |
1454 |
+ retval = key + 10 - 'a'; |
1455 |
++ else if ((key >= 'A') && (key <= 'Z')) |
1456 |
++ retval = key + 10 - 'A'; |
1457 |
+ else |
1458 |
+ retval = -1; |
1459 |
+ return retval; |
1460 |
+diff -NurpP --minimal linux-2.6.29.4/drivers/char/tty_io.c linux-2.6.29.4-vs2.3.0.36.14/drivers/char/tty_io.c |
1461 |
+--- linux-2.6.29.4/drivers/char/tty_io.c 2009-03-24 14:18:57.000000000 +0100 |
1462 |
++++ linux-2.6.29.4-vs2.3.0.36.14/drivers/char/tty_io.c 2009-03-24 14:48:25.000000000 +0100 |
1463 |
+@@ -106,6 +106,7 @@ |
1464 |
+ |
1465 |
+ #include <linux/kmod.h> |
1466 |
+ #include <linux/nsproxy.h> |
1467 |
++#include <linux/vs_pid.h> |
1468 |
+ |
1469 |
+ #undef TTY_DEBUG_HANGUP |
1470 |
+ |
1471 |
+@@ -2303,6 +2304,7 @@ static int tiocspgrp(struct tty_struct * |
1472 |
+ return -ENOTTY; |
1473 |
+ if (get_user(pgrp_nr, p)) |
1474 |
+ return -EFAULT; |
1475 |
++ pgrp_nr = vx_rmap_pid(pgrp_nr); |
1476 |
+ if (pgrp_nr < 0) |
1477 |
+ return -EINVAL; |
1478 |
+ rcu_read_lock(); |
1479 |
+diff -NurpP --minimal linux-2.6.29.4/drivers/infiniband/hw/ipath/ipath_user_pages.c linux-2.6.29.4-vs2.3.0.36.14/drivers/infiniband/hw/ipath/ipath_user_pages.c |
1480 |
+--- linux-2.6.29.4/drivers/infiniband/hw/ipath/ipath_user_pages.c 2008-12-25 00:26:37.000000000 +0100 |
1481 |
++++ linux-2.6.29.4-vs2.3.0.36.14/drivers/infiniband/hw/ipath/ipath_user_pages.c 2009-02-22 22:54:24.000000000 +0100 |
1482 |
+@@ -33,6 +33,7 @@ |
1483 |
+ |
1484 |
+ #include <linux/mm.h> |
1485 |
+ #include <linux/device.h> |
1486 |
++#include <linux/vs_memory.h> |
1487 |
+ |
1488 |
+ #include "ipath_kernel.h" |
1489 |
+ |
1490 |
+@@ -61,7 +62,8 @@ static int __get_user_pages(unsigned lon |
1491 |
+ lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> |
1492 |
+ PAGE_SHIFT; |
1493 |
+ |
1494 |
+- if (num_pages > lock_limit) { |
1495 |
++ if (num_pages > lock_limit || |
1496 |
++ !vx_vmlocked_avail(current->mm, num_pages)) { |
1497 |
+ ret = -ENOMEM; |
1498 |
+ goto bail; |
1499 |
+ } |
1500 |
+@@ -78,7 +80,7 @@ static int __get_user_pages(unsigned lon |
1501 |
+ goto bail_release; |
1502 |
+ } |
1503 |
+ |
1504 |
+- current->mm->locked_vm += num_pages; |
1505 |
++ vx_vmlocked_add(current->mm, num_pages); |
1506 |
+ |
1507 |
+ ret = 0; |
1508 |
+ goto bail; |
1509 |
+@@ -177,7 +179,7 @@ void ipath_release_user_pages(struct pag |
1510 |
+ |
1511 |
+ __ipath_release_user_pages(p, num_pages, 1); |
1512 |
+ |
1513 |
+- current->mm->locked_vm -= num_pages; |
1514 |
++ vx_vmlocked_sub(current->mm, num_pages); |
1515 |
+ |
1516 |
+ up_write(¤t->mm->mmap_sem); |
1517 |
+ } |
1518 |
+@@ -194,7 +196,7 @@ static void user_pages_account(struct wo |
1519 |
+ container_of(_work, struct ipath_user_pages_work, work); |
1520 |
+ |
1521 |
+ down_write(&work->mm->mmap_sem); |
1522 |
+- work->mm->locked_vm -= work->num_pages; |
1523 |
++ vx_vmlocked_sub(work->mm, work->num_pages); |
1524 |
+ up_write(&work->mm->mmap_sem); |
1525 |
+ mmput(work->mm); |
1526 |
+ kfree(work); |
1527 |
+diff -NurpP --minimal linux-2.6.29.4/drivers/md/dm.c linux-2.6.29.4-vs2.3.0.36.14/drivers/md/dm.c |
1528 |
+--- linux-2.6.29.4/drivers/md/dm.c 2009-03-24 14:19:05.000000000 +0100 |
1529 |
++++ linux-2.6.29.4-vs2.3.0.36.14/drivers/md/dm.c 2009-03-24 15:15:57.000000000 +0100 |
1530 |
+@@ -22,6 +22,7 @@ |
1531 |
+ #include <linux/hdreg.h> |
1532 |
+ #include <linux/blktrace_api.h> |
1533 |
+ #include <trace/block.h> |
1534 |
++#include <linux/vs_base.h> |
1535 |
+ |
1536 |
+ #define DM_MSG_PREFIX "core" |
1537 |
+ |
1538 |
+@@ -115,6 +116,7 @@ struct mapped_device { |
1539 |
+ rwlock_t map_lock; |
1540 |
+ atomic_t holders; |
1541 |
+ atomic_t open_count; |
1542 |
++ xid_t xid; |
1543 |
+ |
1544 |
+ unsigned long flags; |
1545 |
+ |
1546 |
+@@ -295,6 +297,7 @@ static void __exit dm_exit(void) |
1547 |
+ static int dm_blk_open(struct block_device *bdev, fmode_t mode) |
1548 |
+ { |
1549 |
+ struct mapped_device *md; |
1550 |
++ int ret = -ENXIO; |
1551 |
+ |
1552 |
+ spin_lock(&_minor_lock); |
1553 |
+ |
1554 |
+@@ -303,18 +306,19 @@ static int dm_blk_open(struct block_devi |
1555 |
+ goto out; |
1556 |
+ |
1557 |
+ if (test_bit(DMF_FREEING, &md->flags) || |
1558 |
+- test_bit(DMF_DELETING, &md->flags)) { |
1559 |
+- md = NULL; |
1560 |
++ test_bit(DMF_DELETING, &md->flags)) |
1561 |
++ goto out; |
1562 |
++ |
1563 |
++ ret = -EACCES; |
1564 |
++ if (!vx_check(md->xid, VS_IDENT|VS_HOSTID)) |
1565 |
+ goto out; |
1566 |
+- } |
1567 |
+ |
1568 |
+ dm_get(md); |
1569 |
+ atomic_inc(&md->open_count); |
1570 |
+- |
1571 |
++ ret = 0; |
1572 |
+ out: |
1573 |
+ spin_unlock(&_minor_lock); |
1574 |
+- |
1575 |
+- return md ? 0 : -ENXIO; |
1576 |
++ return ret; |
1577 |
+ } |
1578 |
+ |
1579 |
+ static int dm_blk_close(struct gendisk *disk, fmode_t mode) |
1580 |
+@@ -504,6 +508,14 @@ int dm_set_geometry(struct mapped_device |
1581 |
+ return 0; |
1582 |
+ } |
1583 |
+ |
1584 |
++/* |
1585 |
++ * Get the xid associated with a dm device |
1586 |
++ */ |
1587 |
++xid_t dm_get_xid(struct mapped_device *md) |
1588 |
++{ |
1589 |
++ return md->xid; |
1590 |
++} |
1591 |
++ |
1592 |
+ /*----------------------------------------------------------------- |
1593 |
+ * CRUD START: |
1594 |
+ * A more elegant soln is in the works that uses the queue |
1595 |
+@@ -1110,6 +1122,7 @@ static struct mapped_device *alloc_dev(i |
1596 |
+ INIT_LIST_HEAD(&md->uevent_list); |
1597 |
+ spin_lock_init(&md->uevent_lock); |
1598 |
+ |
1599 |
++ md->xid = vx_current_xid(); |
1600 |
+ md->queue = blk_alloc_queue(GFP_KERNEL); |
1601 |
+ if (!md->queue) |
1602 |
+ goto bad_queue; |
1603 |
+diff -NurpP --minimal linux-2.6.29.4/drivers/md/dm.h linux-2.6.29.4-vs2.3.0.36.14/drivers/md/dm.h |
1604 |
+--- linux-2.6.29.4/drivers/md/dm.h 2009-03-24 14:19:05.000000000 +0100 |
1605 |
++++ linux-2.6.29.4-vs2.3.0.36.14/drivers/md/dm.h 2009-03-24 14:48:26.000000000 +0100 |
1606 |
+@@ -54,6 +54,8 @@ int dm_table_any_congested(struct dm_tab |
1607 |
+ #define dm_target_is_valid(t) ((t)->table) |
1608 |
+ int dm_table_barrier_ok(struct dm_table *t); |
1609 |
+ |
1610 |
++xid_t dm_get_xid(struct mapped_device *md); |
1611 |
++ |
1612 |
+ /*----------------------------------------------------------------- |
1613 |
+ * A registry of target types. |
1614 |
+ *---------------------------------------------------------------*/ |
1615 |
+diff -NurpP --minimal linux-2.6.29.4/drivers/md/dm-ioctl.c linux-2.6.29.4-vs2.3.0.36.14/drivers/md/dm-ioctl.c |
1616 |
+--- linux-2.6.29.4/drivers/md/dm-ioctl.c 2009-03-24 14:19:05.000000000 +0100 |
1617 |
++++ linux-2.6.29.4-vs2.3.0.36.14/drivers/md/dm-ioctl.c 2009-03-24 14:48:26.000000000 +0100 |
1618 |
+@@ -16,6 +16,7 @@ |
1619 |
+ #include <linux/dm-ioctl.h> |
1620 |
+ #include <linux/hdreg.h> |
1621 |
+ #include <linux/compat.h> |
1622 |
++#include <linux/vs_context.h> |
1623 |
+ |
1624 |
+ #include <asm/uaccess.h> |
1625 |
+ |
1626 |
+@@ -101,7 +102,8 @@ static struct hash_cell *__get_name_cell |
1627 |
+ unsigned int h = hash_str(str); |
1628 |
+ |
1629 |
+ list_for_each_entry (hc, _name_buckets + h, name_list) |
1630 |
+- if (!strcmp(hc->name, str)) { |
1631 |
++ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) && |
1632 |
++ !strcmp(hc->name, str)) { |
1633 |
+ dm_get(hc->md); |
1634 |
+ return hc; |
1635 |
+ } |
1636 |
+@@ -115,7 +117,8 @@ static struct hash_cell *__get_uuid_cell |
1637 |
+ unsigned int h = hash_str(str); |
1638 |
+ |
1639 |
+ list_for_each_entry (hc, _uuid_buckets + h, uuid_list) |
1640 |
+- if (!strcmp(hc->uuid, str)) { |
1641 |
++ if (vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT) && |
1642 |
++ !strcmp(hc->uuid, str)) { |
1643 |
+ dm_get(hc->md); |
1644 |
+ return hc; |
1645 |
+ } |
1646 |
+@@ -352,6 +355,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl |
1647 |
+ |
1648 |
+ static int remove_all(struct dm_ioctl *param, size_t param_size) |
1649 |
+ { |
1650 |
++ if (!vx_check(0, VS_ADMIN)) |
1651 |
++ return -EPERM; |
1652 |
++ |
1653 |
+ dm_hash_remove_all(1); |
1654 |
+ param->data_size = 0; |
1655 |
+ return 0; |
1656 |
+@@ -399,6 +405,8 @@ static int list_devices(struct dm_ioctl |
1657 |
+ */ |
1658 |
+ for (i = 0; i < NUM_BUCKETS; i++) { |
1659 |
+ list_for_each_entry (hc, _name_buckets + i, name_list) { |
1660 |
++ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT)) |
1661 |
++ continue; |
1662 |
+ needed += sizeof(struct dm_name_list); |
1663 |
+ needed += strlen(hc->name) + 1; |
1664 |
+ needed += ALIGN_MASK; |
1665 |
+@@ -422,6 +430,8 @@ static int list_devices(struct dm_ioctl |
1666 |
+ */ |
1667 |
+ for (i = 0; i < NUM_BUCKETS; i++) { |
1668 |
+ list_for_each_entry (hc, _name_buckets + i, name_list) { |
1669 |
++ if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P | VS_IDENT)) |
1670 |
++ continue; |
1671 |
+ if (old_nl) |
1672 |
+ old_nl->next = (uint32_t) ((void *) nl - |
1673 |
+ (void *) old_nl); |
1674 |
+@@ -612,10 +622,11 @@ static struct hash_cell *__find_device_h |
1675 |
+ if (!md) |
1676 |
+ goto out; |
1677 |
+ |
1678 |
+- mdptr = dm_get_mdptr(md); |
1679 |
++ if (vx_check(dm_get_xid(md), VS_WATCH_P | VS_IDENT)) |
1680 |
++ mdptr = dm_get_mdptr(md); |
1681 |
++ |
1682 |
+ if (!mdptr) |
1683 |
+ dm_put(md); |
1684 |
+- |
1685 |
+ out: |
1686 |
+ return mdptr; |
1687 |
+ } |
1688 |
+@@ -1405,8 +1416,8 @@ static int ctl_ioctl(uint command, struc |
1689 |
+ ioctl_fn fn = NULL; |
1690 |
+ size_t param_size; |
1691 |
+ |
1692 |
+- /* only root can play with this */ |
1693 |
+- if (!capable(CAP_SYS_ADMIN)) |
1694 |
++ /* only root and certain contexts can play with this */ |
1695 |
++ if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER)) |
1696 |
+ return -EACCES; |
1697 |
+ |
1698 |
+ if (_IOC_TYPE(command) != DM_IOCTL) |
1699 |
+diff -NurpP --minimal linux-2.6.29.4/drivers/net/tun.c linux-2.6.29.4-vs2.3.0.36.14/drivers/net/tun.c |
1700 |
+--- linux-2.6.29.4/drivers/net/tun.c 2009-03-24 14:19:23.000000000 +0100 |
1701 |
++++ linux-2.6.29.4-vs2.3.0.36.14/drivers/net/tun.c 2009-03-25 01:51:59.000000000 +0100 |
1702 |
+@@ -61,6 +61,7 @@ |
1703 |
+ #include <linux/crc32.h> |
1704 |
+ #include <linux/nsproxy.h> |
1705 |
+ #include <linux/virtio_net.h> |
1706 |
++#include <linux/vs_network.h> |
1707 |
+ #include <net/net_namespace.h> |
1708 |
+ #include <net/netns/generic.h> |
1709 |
+ |
1710 |
+@@ -93,6 +94,7 @@ struct tun_struct { |
1711 |
+ int attached; |
1712 |
+ uid_t owner; |
1713 |
+ gid_t group; |
1714 |
++ nid_t nid; |
1715 |
+ |
1716 |
+ wait_queue_head_t read_wait; |
1717 |
+ struct sk_buff_head readq; |
1718 |
+@@ -697,6 +699,7 @@ static void tun_setup(struct net_device |
1719 |
+ |
1720 |
+ tun->owner = -1; |
1721 |
+ tun->group = -1; |
1722 |
++ tun->nid = current->nid; |
1723 |
+ |
1724 |
+ dev->ethtool_ops = &tun_ethtool_ops; |
1725 |
+ dev->destructor = free_netdev; |
1726 |
+@@ -727,6 +730,9 @@ static int tun_set_iff(struct net *net, |
1727 |
+ tn = net_generic(net, tun_net_id); |
1728 |
+ tun = tun_get_by_name(tn, ifr->ifr_name); |
1729 |
+ if (tun) { |
1730 |
++ if (!nx_check(tun->nid, VS_IDENT | VS_HOSTID | VS_ADMIN_P)) |
1731 |
++ return -EPERM; |
1732 |
++ |
1733 |
+ if (tun->attached) |
1734 |
+ return -EBUSY; |
1735 |
+ |
1736 |
+@@ -735,7 +741,7 @@ static int tun_set_iff(struct net *net, |
1737 |
+ cred->euid != tun->owner) || |
1738 |
+ (tun->group != -1 && |
1739 |
+ cred->egid != tun->group)) && |
1740 |
+- !capable(CAP_NET_ADMIN)) { |
1741 |
++ !cap_raised(current_cap(), CAP_NET_ADMIN)) { |
1742 |
+ return -EPERM; |
1743 |
+ } |
1744 |
+ } |
1745 |
+@@ -747,7 +753,7 @@ static int tun_set_iff(struct net *net, |
1746 |
+ |
1747 |
+ err = -EINVAL; |
1748 |
+ |
1749 |
+- if (!capable(CAP_NET_ADMIN)) |
1750 |
++ if (!nx_capable(CAP_NET_ADMIN, NXC_TUN_CREATE)) |
1751 |
+ return -EPERM; |
1752 |
+ |
1753 |
+ /* Set dev type */ |
1754 |
+@@ -987,6 +993,16 @@ static int tun_chr_ioctl(struct inode *i |
1755 |
+ DBG(KERN_INFO "%s: group set to %d\n", tun->dev->name, tun->group); |
1756 |
+ break; |
1757 |
+ |
1758 |
++ case TUNSETNID: |
1759 |
++ if (!capable(CAP_CONTEXT)) |
1760 |
++ return -EPERM; |
1761 |
++ |
1762 |
++ /* Set nid owner of the device */ |
1763 |
++ tun->nid = (nid_t) arg; |
1764 |
++ |
1765 |
++ DBG(KERN_INFO "%s: nid owner set to %u\n", tun->dev->name, tun->nid); |
1766 |
++ break; |
1767 |
++ |
1768 |
+ case TUNSETLINK: |
1769 |
+ /* Only allow setting the type when the interface is down */ |
1770 |
+ rtnl_lock(); |
1771 |
+diff -NurpP --minimal linux-2.6.29.4/fs/attr.c linux-2.6.29.4-vs2.3.0.36.14/fs/attr.c |
1772 |
+--- linux-2.6.29.4/fs/attr.c 2009-03-24 14:22:24.000000000 +0100 |
1773 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/attr.c 2009-03-24 14:48:34.000000000 +0100 |
1774 |
+@@ -14,6 +14,9 @@ |
1775 |
+ #include <linux/fcntl.h> |
1776 |
+ #include <linux/quotaops.h> |
1777 |
+ #include <linux/security.h> |
1778 |
++#include <linux/proc_fs.h> |
1779 |
++#include <linux/devpts_fs.h> |
1780 |
++#include <linux/vs_tag.h> |
1781 |
+ |
1782 |
+ /* Taken over from the old code... */ |
1783 |
+ |
1784 |
+@@ -55,6 +58,10 @@ int inode_change_ok(struct inode *inode, |
1785 |
+ if (!is_owner_or_cap(inode)) |
1786 |
+ goto error; |
1787 |
+ } |
1788 |
++ |
1789 |
++ if (dx_permission(inode, MAY_WRITE)) |
1790 |
++ goto error; |
1791 |
++ |
1792 |
+ fine: |
1793 |
+ retval = 0; |
1794 |
+ error: |
1795 |
+@@ -78,6 +85,8 @@ int inode_setattr(struct inode * inode, |
1796 |
+ inode->i_uid = attr->ia_uid; |
1797 |
+ if (ia_valid & ATTR_GID) |
1798 |
+ inode->i_gid = attr->ia_gid; |
1799 |
++ if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode)) |
1800 |
++ inode->i_tag = attr->ia_tag; |
1801 |
+ if (ia_valid & ATTR_ATIME) |
1802 |
+ inode->i_atime = timespec_trunc(attr->ia_atime, |
1803 |
+ inode->i_sb->s_time_gran); |
1804 |
+@@ -172,7 +181,8 @@ int notify_change(struct dentry * dentry |
1805 |
+ error = inode_change_ok(inode, attr); |
1806 |
+ if (!error) { |
1807 |
+ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || |
1808 |
+- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) |
1809 |
++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) || |
1810 |
++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) |
1811 |
+ error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; |
1812 |
+ if (!error) |
1813 |
+ error = inode_setattr(inode, attr); |
1814 |
+diff -NurpP --minimal linux-2.6.29.4/fs/binfmt_aout.c linux-2.6.29.4-vs2.3.0.36.14/fs/binfmt_aout.c |
1815 |
+--- linux-2.6.29.4/fs/binfmt_aout.c 2009-03-24 14:22:24.000000000 +0100 |
1816 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/binfmt_aout.c 2009-03-24 14:48:34.000000000 +0100 |
1817 |
+@@ -24,6 +24,7 @@ |
1818 |
+ #include <linux/binfmts.h> |
1819 |
+ #include <linux/personality.h> |
1820 |
+ #include <linux/init.h> |
1821 |
++#include <linux/vs_memory.h> |
1822 |
+ |
1823 |
+ #include <asm/system.h> |
1824 |
+ #include <asm/uaccess.h> |
1825 |
+diff -NurpP --minimal linux-2.6.29.4/fs/binfmt_elf.c linux-2.6.29.4-vs2.3.0.36.14/fs/binfmt_elf.c |
1826 |
+--- linux-2.6.29.4/fs/binfmt_elf.c 2009-03-24 14:22:24.000000000 +0100 |
1827 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/binfmt_elf.c 2009-03-24 14:48:34.000000000 +0100 |
1828 |
+@@ -38,6 +38,7 @@ |
1829 |
+ #include <linux/random.h> |
1830 |
+ #include <linux/elf.h> |
1831 |
+ #include <linux/utsname.h> |
1832 |
++#include <linux/vs_memory.h> |
1833 |
+ #include <asm/uaccess.h> |
1834 |
+ #include <asm/param.h> |
1835 |
+ #include <asm/page.h> |
1836 |
+diff -NurpP --minimal linux-2.6.29.4/fs/binfmt_flat.c linux-2.6.29.4-vs2.3.0.36.14/fs/binfmt_flat.c |
1837 |
+--- linux-2.6.29.4/fs/binfmt_flat.c 2009-03-24 14:22:24.000000000 +0100 |
1838 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/binfmt_flat.c 2009-03-24 14:48:34.000000000 +0100 |
1839 |
+@@ -35,6 +35,7 @@ |
1840 |
+ #include <linux/init.h> |
1841 |
+ #include <linux/flat.h> |
1842 |
+ #include <linux/syscalls.h> |
1843 |
++#include <linux/vs_memory.h> |
1844 |
+ |
1845 |
+ #include <asm/byteorder.h> |
1846 |
+ #include <asm/system.h> |
1847 |
+diff -NurpP --minimal linux-2.6.29.4/fs/binfmt_som.c linux-2.6.29.4-vs2.3.0.36.14/fs/binfmt_som.c |
1848 |
+--- linux-2.6.29.4/fs/binfmt_som.c 2009-03-24 14:22:24.000000000 +0100 |
1849 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/binfmt_som.c 2009-03-24 14:48:34.000000000 +0100 |
1850 |
+@@ -28,6 +28,7 @@ |
1851 |
+ #include <linux/shm.h> |
1852 |
+ #include <linux/personality.h> |
1853 |
+ #include <linux/init.h> |
1854 |
++#include <linux/vs_memory.h> |
1855 |
+ |
1856 |
+ #include <asm/uaccess.h> |
1857 |
+ #include <asm/pgtable.h> |
1858 |
+diff -NurpP --minimal linux-2.6.29.4/fs/block_dev.c linux-2.6.29.4-vs2.3.0.36.14/fs/block_dev.c |
1859 |
+--- linux-2.6.29.4/fs/block_dev.c 2009-03-24 14:22:24.000000000 +0100 |
1860 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/block_dev.c 2009-03-24 14:48:34.000000000 +0100 |
1861 |
+@@ -24,6 +24,7 @@ |
1862 |
+ #include <linux/uio.h> |
1863 |
+ #include <linux/namei.h> |
1864 |
+ #include <linux/log2.h> |
1865 |
++#include <linux/vs_device.h> |
1866 |
+ #include <asm/uaccess.h> |
1867 |
+ #include "internal.h" |
1868 |
+ |
1869 |
+@@ -392,6 +393,7 @@ struct block_device *bdget(dev_t dev) |
1870 |
+ bdev->bd_invalidated = 0; |
1871 |
+ inode->i_mode = S_IFBLK; |
1872 |
+ inode->i_rdev = dev; |
1873 |
++ inode->i_mdev = dev; |
1874 |
+ inode->i_bdev = bdev; |
1875 |
+ inode->i_data.a_ops = &def_blk_aops; |
1876 |
+ mapping_set_gfp_mask(&inode->i_data, GFP_USER); |
1877 |
+@@ -428,6 +430,11 @@ EXPORT_SYMBOL(bdput); |
1878 |
+ static struct block_device *bd_acquire(struct inode *inode) |
1879 |
+ { |
1880 |
+ struct block_device *bdev; |
1881 |
++ dev_t mdev; |
1882 |
++ |
1883 |
++ if (!vs_map_blkdev(inode->i_rdev, &mdev, DATTR_OPEN)) |
1884 |
++ return NULL; |
1885 |
++ inode->i_mdev = mdev; |
1886 |
+ |
1887 |
+ spin_lock(&bdev_lock); |
1888 |
+ bdev = inode->i_bdev; |
1889 |
+@@ -438,7 +445,7 @@ static struct block_device *bd_acquire(s |
1890 |
+ } |
1891 |
+ spin_unlock(&bdev_lock); |
1892 |
+ |
1893 |
+- bdev = bdget(inode->i_rdev); |
1894 |
++ bdev = bdget(mdev); |
1895 |
+ if (bdev) { |
1896 |
+ spin_lock(&bdev_lock); |
1897 |
+ if (!inode->i_bdev) { |
1898 |
+diff -NurpP --minimal linux-2.6.29.4/fs/char_dev.c linux-2.6.29.4-vs2.3.0.36.14/fs/char_dev.c |
1899 |
+--- linux-2.6.29.4/fs/char_dev.c 2009-03-24 14:22:25.000000000 +0100 |
1900 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/char_dev.c 2009-03-24 14:48:35.000000000 +0100 |
1901 |
+@@ -21,6 +21,8 @@ |
1902 |
+ #include <linux/cdev.h> |
1903 |
+ #include <linux/mutex.h> |
1904 |
+ #include <linux/backing-dev.h> |
1905 |
++#include <linux/vs_context.h> |
1906 |
++#include <linux/vs_device.h> |
1907 |
+ |
1908 |
+ #include "internal.h" |
1909 |
+ |
1910 |
+@@ -358,14 +360,21 @@ static int chrdev_open(struct inode *ino |
1911 |
+ struct cdev *p; |
1912 |
+ struct cdev *new = NULL; |
1913 |
+ int ret = 0; |
1914 |
++ dev_t mdev; |
1915 |
++ |
1916 |
++ if (!vs_map_chrdev(inode->i_rdev, &mdev, DATTR_OPEN)) |
1917 |
++ return -EPERM; |
1918 |
++ inode->i_mdev = mdev; |
1919 |
+ |
1920 |
+ spin_lock(&cdev_lock); |
1921 |
+ p = inode->i_cdev; |
1922 |
+ if (!p) { |
1923 |
+ struct kobject *kobj; |
1924 |
+ int idx; |
1925 |
++ |
1926 |
+ spin_unlock(&cdev_lock); |
1927 |
+- kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx); |
1928 |
++ |
1929 |
++ kobj = kobj_lookup(cdev_map, mdev, &idx); |
1930 |
+ if (!kobj) |
1931 |
+ return -ENXIO; |
1932 |
+ new = container_of(kobj, struct cdev, kobj); |
1933 |
+diff -NurpP --minimal linux-2.6.29.4/fs/dcache.c linux-2.6.29.4-vs2.3.0.36.14/fs/dcache.c |
1934 |
+--- linux-2.6.29.4/fs/dcache.c 2009-03-24 14:22:25.000000000 +0100 |
1935 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/dcache.c 2009-03-24 14:48:35.000000000 +0100 |
1936 |
+@@ -32,6 +32,7 @@ |
1937 |
+ #include <linux/seqlock.h> |
1938 |
+ #include <linux/swap.h> |
1939 |
+ #include <linux/bootmem.h> |
1940 |
++#include <linux/vs_limit.h> |
1941 |
+ #include "internal.h" |
1942 |
+ |
1943 |
+ int sysctl_vfs_cache_pressure __read_mostly = 100; |
1944 |
+@@ -229,6 +230,8 @@ repeat: |
1945 |
+ return; |
1946 |
+ } |
1947 |
+ |
1948 |
++ vx_dentry_dec(dentry); |
1949 |
++ |
1950 |
+ /* |
1951 |
+ * AV: ->d_delete() is _NOT_ allowed to block now. |
1952 |
+ */ |
1953 |
+@@ -320,6 +323,7 @@ static inline struct dentry * __dget_loc |
1954 |
+ { |
1955 |
+ atomic_inc(&dentry->d_count); |
1956 |
+ dentry_lru_del_init(dentry); |
1957 |
++ vx_dentry_inc(dentry); |
1958 |
+ return dentry; |
1959 |
+ } |
1960 |
+ |
1961 |
+@@ -918,6 +922,9 @@ struct dentry *d_alloc(struct dentry * p |
1962 |
+ struct dentry *dentry; |
1963 |
+ char *dname; |
1964 |
+ |
1965 |
++ if (!vx_dentry_avail(1)) |
1966 |
++ return NULL; |
1967 |
++ |
1968 |
+ dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); |
1969 |
+ if (!dentry) |
1970 |
+ return NULL; |
1971 |
+@@ -963,6 +970,7 @@ struct dentry *d_alloc(struct dentry * p |
1972 |
+ if (parent) |
1973 |
+ list_add(&dentry->d_u.d_child, &parent->d_subdirs); |
1974 |
+ dentry_stat.nr_dentry++; |
1975 |
++ vx_dentry_inc(dentry); |
1976 |
+ spin_unlock(&dcache_lock); |
1977 |
+ |
1978 |
+ return dentry; |
1979 |
+@@ -1418,6 +1426,7 @@ struct dentry * __d_lookup(struct dentry |
1980 |
+ } |
1981 |
+ |
1982 |
+ atomic_inc(&dentry->d_count); |
1983 |
++ vx_dentry_inc(dentry); |
1984 |
+ found = dentry; |
1985 |
+ spin_unlock(&dentry->d_lock); |
1986 |
+ break; |
1987 |
+diff -NurpP --minimal linux-2.6.29.4/fs/devpts/inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/devpts/inode.c |
1988 |
+--- linux-2.6.29.4/fs/devpts/inode.c 2009-03-24 14:22:25.000000000 +0100 |
1989 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/devpts/inode.c 2009-03-24 15:32:47.000000000 +0100 |
1990 |
+@@ -19,12 +19,12 @@ |
1991 |
+ #include <linux/tty.h> |
1992 |
+ #include <linux/mutex.h> |
1993 |
+ #include <linux/idr.h> |
1994 |
++#include <linux/magic.h> |
1995 |
+ #include <linux/devpts_fs.h> |
1996 |
+ #include <linux/parser.h> |
1997 |
+ #include <linux/fsnotify.h> |
1998 |
+ #include <linux/seq_file.h> |
1999 |
+- |
2000 |
+-#define DEVPTS_SUPER_MAGIC 0x1cd1 |
2001 |
++#include <linux/vs_base.h> |
2002 |
+ |
2003 |
+ #define DEVPTS_DEFAULT_MODE 0600 |
2004 |
+ /* |
2005 |
+@@ -36,6 +36,20 @@ |
2006 |
+ #define DEVPTS_DEFAULT_PTMX_MODE 0000 |
2007 |
+ #define PTMX_MINOR 2 |
2008 |
+ |
2009 |
++static int devpts_permission(struct inode *inode, int mask) |
2010 |
++{ |
2011 |
++ int ret = -EACCES; |
2012 |
++ |
2013 |
++ /* devpts is xid tagged */ |
2014 |
++ if (vx_check((xid_t)inode->i_tag, VS_WATCH_P | VS_IDENT)) |
2015 |
++ ret = generic_permission(inode, mask, NULL); |
2016 |
++ return ret; |
2017 |
++} |
2018 |
++ |
2019 |
++static struct inode_operations devpts_file_inode_operations = { |
2020 |
++ .permission = devpts_permission, |
2021 |
++}; |
2022 |
++ |
2023 |
+ extern int pty_limit; /* Config limit on Unix98 ptys */ |
2024 |
+ static DEFINE_MUTEX(allocated_ptys_lock); |
2025 |
+ |
2026 |
+@@ -254,6 +268,25 @@ static int devpts_show_options(struct se |
2027 |
+ return 0; |
2028 |
+ } |
2029 |
+ |
2030 |
++static int devpts_filter(struct dentry *de) |
2031 |
++{ |
2032 |
++ /* devpts is xid tagged */ |
2033 |
++ return vx_check((xid_t)de->d_inode->i_tag, VS_WATCH_P | VS_IDENT); |
2034 |
++} |
2035 |
++ |
2036 |
++static int devpts_readdir(struct file * filp, void * dirent, filldir_t filldir) |
2037 |
++{ |
2038 |
++ return dcache_readdir_filter(filp, dirent, filldir, devpts_filter); |
2039 |
++} |
2040 |
++ |
2041 |
++static struct file_operations devpts_dir_operations = { |
2042 |
++ .open = dcache_dir_open, |
2043 |
++ .release = dcache_dir_close, |
2044 |
++ .llseek = dcache_dir_lseek, |
2045 |
++ .read = generic_read_dir, |
2046 |
++ .readdir = devpts_readdir, |
2047 |
++}; |
2048 |
++ |
2049 |
+ static const struct super_operations devpts_sops = { |
2050 |
+ .statfs = simple_statfs, |
2051 |
+ .remount_fs = devpts_remount, |
2052 |
+@@ -293,12 +326,15 @@ devpts_fill_super(struct super_block *s, |
2053 |
+ inode = new_inode(s); |
2054 |
+ if (!inode) |
2055 |
+ goto free_fsi; |
2056 |
++ |
2057 |
+ inode->i_ino = 1; |
2058 |
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
2059 |
+ inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; |
2060 |
+ inode->i_op = &simple_dir_inode_operations; |
2061 |
+- inode->i_fop = &simple_dir_operations; |
2062 |
++ inode->i_fop = &devpts_dir_operations; |
2063 |
+ inode->i_nlink = 2; |
2064 |
++ /* devpts is xid tagged */ |
2065 |
++ inode->i_tag = (tag_t)vx_current_xid(); |
2066 |
+ |
2067 |
+ s->s_root = d_alloc_root(inode); |
2068 |
+ if (s->s_root) |
2069 |
+@@ -479,6 +515,7 @@ static int init_pts_mount(struct file_sy |
2070 |
+ return err; |
2071 |
+ } |
2072 |
+ |
2073 |
++ |
2074 |
+ static int devpts_get_sb(struct file_system_type *fs_type, |
2075 |
+ int flags, const char *dev_name, void *data, struct vfsmount *mnt) |
2076 |
+ { |
2077 |
+@@ -590,6 +627,9 @@ int devpts_pty_new(struct inode *ptmx_in |
2078 |
+ inode->i_gid = opts->setgid ? opts->gid : current_fsgid(); |
2079 |
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
2080 |
+ init_special_inode(inode, S_IFCHR|opts->mode, device); |
2081 |
++ /* devpts is xid tagged */ |
2082 |
++ inode->i_tag = (tag_t)vx_current_xid(); |
2083 |
++ inode->i_op = &devpts_file_inode_operations; |
2084 |
+ inode->i_private = tty; |
2085 |
+ tty->driver_data = inode; |
2086 |
+ |
2087 |
+diff -NurpP --minimal linux-2.6.29.4/fs/exec.c linux-2.6.29.4-vs2.3.0.36.14/fs/exec.c |
2088 |
+--- linux-2.6.29.4/fs/exec.c 2009-05-23 23:16:52.000000000 +0200 |
2089 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/exec.c 2009-05-10 23:42:01.000000000 +0200 |
2090 |
+@@ -257,7 +257,9 @@ static int __bprm_mm_init(struct linux_b |
2091 |
+ if (err) |
2092 |
+ goto err; |
2093 |
+ |
2094 |
+- mm->stack_vm = mm->total_vm = 1; |
2095 |
++ mm->total_vm = 0; |
2096 |
++ vx_vmpages_inc(mm); |
2097 |
++ mm->stack_vm = 1; |
2098 |
+ up_write(&mm->mmap_sem); |
2099 |
+ bprm->p = vma->vm_end - sizeof(void *); |
2100 |
+ return 0; |
2101 |
+@@ -1463,7 +1465,7 @@ static int format_corename(char *corenam |
2102 |
+ /* UNIX time of coredump */ |
2103 |
+ case 't': { |
2104 |
+ struct timeval tv; |
2105 |
+- do_gettimeofday(&tv); |
2106 |
++ vx_gettimeofday(&tv); |
2107 |
+ rc = snprintf(out_ptr, out_end - out_ptr, |
2108 |
+ "%lu", tv.tv_sec); |
2109 |
+ if (rc > out_end - out_ptr) |
2110 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext2/balloc.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/balloc.c |
2111 |
+--- linux-2.6.29.4/fs/ext2/balloc.c 2009-03-24 14:22:25.000000000 +0100 |
2112 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/balloc.c 2009-03-24 14:48:35.000000000 +0100 |
2113 |
+@@ -16,6 +16,8 @@ |
2114 |
+ #include <linux/sched.h> |
2115 |
+ #include <linux/buffer_head.h> |
2116 |
+ #include <linux/capability.h> |
2117 |
++#include <linux/vs_dlimit.h> |
2118 |
++#include <linux/vs_tag.h> |
2119 |
+ |
2120 |
+ /* |
2121 |
+ * balloc.c contains the blocks allocation and deallocation routines |
2122 |
+@@ -569,6 +571,7 @@ do_more: |
2123 |
+ } |
2124 |
+ error_return: |
2125 |
+ brelse(bitmap_bh); |
2126 |
++ DLIMIT_FREE_BLOCK(inode, freed); |
2127 |
+ release_blocks(sb, freed); |
2128 |
+ DQUOT_FREE_BLOCK(inode, freed); |
2129 |
+ } |
2130 |
+@@ -701,7 +704,6 @@ ext2_try_to_allocate(struct super_block |
2131 |
+ start = 0; |
2132 |
+ end = EXT2_BLOCKS_PER_GROUP(sb); |
2133 |
+ } |
2134 |
+- |
2135 |
+ BUG_ON(start > EXT2_BLOCKS_PER_GROUP(sb)); |
2136 |
+ |
2137 |
+ repeat: |
2138 |
+@@ -1251,6 +1253,11 @@ ext2_fsblk_t ext2_new_blocks(struct inod |
2139 |
+ *errp = -EDQUOT; |
2140 |
+ return 0; |
2141 |
+ } |
2142 |
++ if (DLIMIT_ALLOC_BLOCK(inode, num)) { |
2143 |
++ *errp = -ENOSPC; |
2144 |
++ DQUOT_FREE_BLOCK(inode, num); |
2145 |
++ return 0; |
2146 |
++ } |
2147 |
+ |
2148 |
+ sbi = EXT2_SB(sb); |
2149 |
+ es = EXT2_SB(sb)->s_es; |
2150 |
+@@ -1409,6 +1416,7 @@ allocated: |
2151 |
+ |
2152 |
+ *errp = 0; |
2153 |
+ brelse(bitmap_bh); |
2154 |
++ DLIMIT_FREE_BLOCK(inode, *count-num); |
2155 |
+ DQUOT_FREE_BLOCK(inode, *count-num); |
2156 |
+ *count = num; |
2157 |
+ return ret_block; |
2158 |
+@@ -1419,8 +1427,10 @@ out: |
2159 |
+ /* |
2160 |
+ * Undo the block allocation |
2161 |
+ */ |
2162 |
+- if (!performed_allocation) |
2163 |
++ if (!performed_allocation) { |
2164 |
++ DLIMIT_FREE_BLOCK(inode, *count); |
2165 |
+ DQUOT_FREE_BLOCK(inode, *count); |
2166 |
++ } |
2167 |
+ brelse(bitmap_bh); |
2168 |
+ return 0; |
2169 |
+ } |
2170 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext2/ext2.h linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/ext2.h |
2171 |
+--- linux-2.6.29.4/fs/ext2/ext2.h 2008-12-25 00:26:37.000000000 +0100 |
2172 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/ext2.h 2009-02-22 22:54:25.000000000 +0100 |
2173 |
+@@ -170,6 +170,7 @@ extern const struct file_operations ext2 |
2174 |
+ extern const struct address_space_operations ext2_aops; |
2175 |
+ extern const struct address_space_operations ext2_aops_xip; |
2176 |
+ extern const struct address_space_operations ext2_nobh_aops; |
2177 |
++extern int ext2_sync_flags(struct inode *inode); |
2178 |
+ |
2179 |
+ /* namei.c */ |
2180 |
+ extern const struct inode_operations ext2_dir_inode_operations; |
2181 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext2/file.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/file.c |
2182 |
+--- linux-2.6.29.4/fs/ext2/file.c 2008-12-25 00:26:37.000000000 +0100 |
2183 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/file.c 2009-02-22 22:54:25.000000000 +0100 |
2184 |
+@@ -87,4 +87,5 @@ const struct inode_operations ext2_file_ |
2185 |
+ .setattr = ext2_setattr, |
2186 |
+ .permission = ext2_permission, |
2187 |
+ .fiemap = ext2_fiemap, |
2188 |
++ .sync_flags = ext2_sync_flags, |
2189 |
+ }; |
2190 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext2/ialloc.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/ialloc.c |
2191 |
+--- linux-2.6.29.4/fs/ext2/ialloc.c 2009-03-24 14:22:25.000000000 +0100 |
2192 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/ialloc.c 2009-03-24 15:36:12.000000000 +0100 |
2193 |
+@@ -17,6 +17,8 @@ |
2194 |
+ #include <linux/backing-dev.h> |
2195 |
+ #include <linux/buffer_head.h> |
2196 |
+ #include <linux/random.h> |
2197 |
++#include <linux/vs_dlimit.h> |
2198 |
++#include <linux/vs_tag.h> |
2199 |
+ #include "ext2.h" |
2200 |
+ #include "xattr.h" |
2201 |
+ #include "acl.h" |
2202 |
+@@ -123,6 +125,7 @@ void ext2_free_inode (struct inode * ino |
2203 |
+ ext2_xattr_delete_inode(inode); |
2204 |
+ DQUOT_FREE_INODE(inode); |
2205 |
+ DQUOT_DROP(inode); |
2206 |
++ DLIMIT_FREE_INODE(inode); |
2207 |
+ } |
2208 |
+ |
2209 |
+ es = EXT2_SB(sb)->s_es; |
2210 |
+@@ -454,6 +457,11 @@ struct inode *ext2_new_inode(struct inod |
2211 |
+ if (!inode) |
2212 |
+ return ERR_PTR(-ENOMEM); |
2213 |
+ |
2214 |
++ inode->i_tag = dx_current_fstag(sb); |
2215 |
++ if (DLIMIT_ALLOC_INODE(inode)) { |
2216 |
++ err = -ENOSPC; |
2217 |
++ goto fail_dlim; |
2218 |
++ } |
2219 |
+ ei = EXT2_I(inode); |
2220 |
+ sbi = EXT2_SB(sb); |
2221 |
+ es = sbi->s_es; |
2222 |
+@@ -609,6 +617,7 @@ fail_free_drop: |
2223 |
+ |
2224 |
+ fail_drop: |
2225 |
+ DQUOT_DROP(inode); |
2226 |
++ DLIMIT_FREE_INODE(inode); |
2227 |
+ inode->i_flags |= S_NOQUOTA; |
2228 |
+ inode->i_nlink = 0; |
2229 |
+ unlock_new_inode(inode); |
2230 |
+@@ -616,6 +625,8 @@ fail_drop: |
2231 |
+ return ERR_PTR(err); |
2232 |
+ |
2233 |
+ fail: |
2234 |
++ DLIMIT_FREE_INODE(inode); |
2235 |
++fail_dlim: |
2236 |
+ make_bad_inode(inode); |
2237 |
+ iput(inode); |
2238 |
+ return ERR_PTR(err); |
2239 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext2/inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/inode.c |
2240 |
+--- linux-2.6.29.4/fs/ext2/inode.c 2009-03-24 14:22:25.000000000 +0100 |
2241 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/inode.c 2009-03-24 15:41:38.000000000 +0100 |
2242 |
+@@ -33,6 +33,7 @@ |
2243 |
+ #include <linux/mpage.h> |
2244 |
+ #include <linux/fiemap.h> |
2245 |
+ #include <linux/namei.h> |
2246 |
++#include <linux/vs_tag.h> |
2247 |
+ #include "ext2.h" |
2248 |
+ #include "acl.h" |
2249 |
+ #include "xip.h" |
2250 |
+@@ -1018,7 +1019,7 @@ void ext2_truncate(struct inode *inode) |
2251 |
+ return; |
2252 |
+ if (ext2_inode_is_fast_symlink(inode)) |
2253 |
+ return; |
2254 |
+- if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
2255 |
++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode)) |
2256 |
+ return; |
2257 |
+ |
2258 |
+ blocksize = inode->i_sb->s_blocksize; |
2259 |
+@@ -1156,38 +1157,72 @@ void ext2_set_inode_flags(struct inode * |
2260 |
+ { |
2261 |
+ unsigned int flags = EXT2_I(inode)->i_flags; |
2262 |
+ |
2263 |
+- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); |
2264 |
++ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK | |
2265 |
++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC); |
2266 |
++ |
2267 |
++ |
2268 |
++ if (flags & EXT2_IMMUTABLE_FL) |
2269 |
++ inode->i_flags |= S_IMMUTABLE; |
2270 |
++ if (flags & EXT2_IXUNLINK_FL) |
2271 |
++ inode->i_flags |= S_IXUNLINK; |
2272 |
++ |
2273 |
+ if (flags & EXT2_SYNC_FL) |
2274 |
+ inode->i_flags |= S_SYNC; |
2275 |
+ if (flags & EXT2_APPEND_FL) |
2276 |
+ inode->i_flags |= S_APPEND; |
2277 |
+- if (flags & EXT2_IMMUTABLE_FL) |
2278 |
+- inode->i_flags |= S_IMMUTABLE; |
2279 |
+ if (flags & EXT2_NOATIME_FL) |
2280 |
+ inode->i_flags |= S_NOATIME; |
2281 |
+ if (flags & EXT2_DIRSYNC_FL) |
2282 |
+ inode->i_flags |= S_DIRSYNC; |
2283 |
++ |
2284 |
++ inode->i_vflags &= ~(V_BARRIER | V_COW); |
2285 |
++ |
2286 |
++ if (flags & EXT2_BARRIER_FL) |
2287 |
++ inode->i_vflags |= V_BARRIER; |
2288 |
++ if (flags & EXT2_COW_FL) |
2289 |
++ inode->i_vflags |= V_COW; |
2290 |
+ } |
2291 |
+ |
2292 |
+ /* Propagate flags from i_flags to EXT2_I(inode)->i_flags */ |
2293 |
+ void ext2_get_inode_flags(struct ext2_inode_info *ei) |
2294 |
+ { |
2295 |
+ unsigned int flags = ei->vfs_inode.i_flags; |
2296 |
++ unsigned int vflags = ei->vfs_inode.i_vflags; |
2297 |
++ |
2298 |
++ ei->i_flags &= ~(EXT2_SYNC_FL | EXT2_APPEND_FL | |
2299 |
++ EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL | |
2300 |
++ EXT2_NOATIME_FL | EXT2_DIRSYNC_FL | |
2301 |
++ EXT2_BARRIER_FL | EXT2_COW_FL); |
2302 |
++ |
2303 |
++ if (flags & S_IMMUTABLE) |
2304 |
++ ei->i_flags |= EXT2_IMMUTABLE_FL; |
2305 |
++ if (flags & S_IXUNLINK) |
2306 |
++ ei->i_flags |= EXT2_IXUNLINK_FL; |
2307 |
+ |
2308 |
+- ei->i_flags &= ~(EXT2_SYNC_FL|EXT2_APPEND_FL| |
2309 |
+- EXT2_IMMUTABLE_FL|EXT2_NOATIME_FL|EXT2_DIRSYNC_FL); |
2310 |
+ if (flags & S_SYNC) |
2311 |
+ ei->i_flags |= EXT2_SYNC_FL; |
2312 |
+ if (flags & S_APPEND) |
2313 |
+ ei->i_flags |= EXT2_APPEND_FL; |
2314 |
+- if (flags & S_IMMUTABLE) |
2315 |
+- ei->i_flags |= EXT2_IMMUTABLE_FL; |
2316 |
+ if (flags & S_NOATIME) |
2317 |
+ ei->i_flags |= EXT2_NOATIME_FL; |
2318 |
+ if (flags & S_DIRSYNC) |
2319 |
+ ei->i_flags |= EXT2_DIRSYNC_FL; |
2320 |
++ |
2321 |
++ if (vflags & V_BARRIER) |
2322 |
++ ei->i_flags |= EXT2_BARRIER_FL; |
2323 |
++ if (vflags & V_COW) |
2324 |
++ ei->i_flags |= EXT2_COW_FL; |
2325 |
+ } |
2326 |
+ |
2327 |
++int ext2_sync_flags(struct inode *inode) |
2328 |
++{ |
2329 |
++ ext2_get_inode_flags(EXT2_I(inode)); |
2330 |
++ inode->i_ctime = CURRENT_TIME; |
2331 |
++ mark_inode_dirty(inode); |
2332 |
++ return 0; |
2333 |
++} |
2334 |
++ |
2335 |
++ |
2336 |
+ struct inode *ext2_iget (struct super_block *sb, unsigned long ino) |
2337 |
+ { |
2338 |
+ struct ext2_inode_info *ei; |
2339 |
+@@ -1195,6 +1230,8 @@ struct inode *ext2_iget (struct super_bl |
2340 |
+ struct ext2_inode *raw_inode; |
2341 |
+ struct inode *inode; |
2342 |
+ long ret = -EIO; |
2343 |
++ uid_t uid; |
2344 |
++ gid_t gid; |
2345 |
+ int n; |
2346 |
+ |
2347 |
+ inode = iget_locked(sb, ino); |
2348 |
+@@ -1217,12 +1254,17 @@ struct inode *ext2_iget (struct super_bl |
2349 |
+ } |
2350 |
+ |
2351 |
+ inode->i_mode = le16_to_cpu(raw_inode->i_mode); |
2352 |
+- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); |
2353 |
+- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); |
2354 |
++ uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); |
2355 |
++ gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); |
2356 |
+ if (!(test_opt (inode->i_sb, NO_UID32))) { |
2357 |
+- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; |
2358 |
+- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; |
2359 |
++ uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; |
2360 |
++ gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; |
2361 |
+ } |
2362 |
++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid); |
2363 |
++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid); |
2364 |
++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid, |
2365 |
++ le16_to_cpu(raw_inode->i_raw_tag)); |
2366 |
++ |
2367 |
+ inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); |
2368 |
+ inode->i_size = le32_to_cpu(raw_inode->i_size); |
2369 |
+ inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime); |
2370 |
+@@ -1320,8 +1362,8 @@ static int ext2_update_inode(struct inod |
2371 |
+ struct ext2_inode_info *ei = EXT2_I(inode); |
2372 |
+ struct super_block *sb = inode->i_sb; |
2373 |
+ ino_t ino = inode->i_ino; |
2374 |
+- uid_t uid = inode->i_uid; |
2375 |
+- gid_t gid = inode->i_gid; |
2376 |
++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag); |
2377 |
++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag); |
2378 |
+ struct buffer_head * bh; |
2379 |
+ struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh); |
2380 |
+ int n; |
2381 |
+@@ -1357,6 +1399,9 @@ static int ext2_update_inode(struct inod |
2382 |
+ raw_inode->i_uid_high = 0; |
2383 |
+ raw_inode->i_gid_high = 0; |
2384 |
+ } |
2385 |
++#ifdef CONFIG_TAGGING_INTERN |
2386 |
++ raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag); |
2387 |
++#endif |
2388 |
+ raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); |
2389 |
+ raw_inode->i_size = cpu_to_le32(inode->i_size); |
2390 |
+ raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); |
2391 |
+@@ -1443,7 +1488,8 @@ int ext2_setattr(struct dentry *dentry, |
2392 |
+ if (error) |
2393 |
+ return error; |
2394 |
+ if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || |
2395 |
+- (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { |
2396 |
++ (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) || |
2397 |
++ (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) { |
2398 |
+ error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0; |
2399 |
+ if (error) |
2400 |
+ return error; |
2401 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext2/ioctl.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/ioctl.c |
2402 |
+--- linux-2.6.29.4/fs/ext2/ioctl.c 2009-03-24 14:22:25.000000000 +0100 |
2403 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/ioctl.c 2009-03-24 14:48:35.000000000 +0100 |
2404 |
+@@ -14,6 +14,7 @@ |
2405 |
+ #include <linux/compat.h> |
2406 |
+ #include <linux/mount.h> |
2407 |
+ #include <linux/smp_lock.h> |
2408 |
++#include <linux/mount.h> |
2409 |
+ #include <asm/current.h> |
2410 |
+ #include <asm/uaccess.h> |
2411 |
+ |
2412 |
+@@ -52,6 +53,11 @@ long ext2_ioctl(struct file *filp, unsig |
2413 |
+ |
2414 |
+ flags = ext2_mask_flags(inode->i_mode, flags); |
2415 |
+ |
2416 |
++ if (IS_BARRIER(inode)) { |
2417 |
++ vxwprintk_task(1, "messing with the barrier."); |
2418 |
++ return -EACCES; |
2419 |
++ } |
2420 |
++ |
2421 |
+ mutex_lock(&inode->i_mutex); |
2422 |
+ /* Is it quota file? Do not allow user to mess with it */ |
2423 |
+ if (IS_NOQUOTA(inode)) { |
2424 |
+@@ -67,7 +73,9 @@ long ext2_ioctl(struct file *filp, unsig |
2425 |
+ * |
2426 |
+ * This test looks nicer. Thanks to Pauline Middelink |
2427 |
+ */ |
2428 |
+- if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) { |
2429 |
++ if ((oldflags & EXT2_IMMUTABLE_FL) || |
2430 |
++ ((flags ^ oldflags) & (EXT2_APPEND_FL | |
2431 |
++ EXT2_IMMUTABLE_FL | EXT2_IXUNLINK_FL))) { |
2432 |
+ if (!capable(CAP_LINUX_IMMUTABLE)) { |
2433 |
+ mutex_unlock(&inode->i_mutex); |
2434 |
+ ret = -EPERM; |
2435 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext2/namei.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/namei.c |
2436 |
+--- linux-2.6.29.4/fs/ext2/namei.c 2009-03-24 14:22:25.000000000 +0100 |
2437 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/namei.c 2009-03-24 14:48:35.000000000 +0100 |
2438 |
+@@ -31,6 +31,7 @@ |
2439 |
+ */ |
2440 |
+ |
2441 |
+ #include <linux/pagemap.h> |
2442 |
++#include <linux/vs_tag.h> |
2443 |
+ #include "ext2.h" |
2444 |
+ #include "xattr.h" |
2445 |
+ #include "acl.h" |
2446 |
+@@ -68,6 +69,7 @@ static struct dentry *ext2_lookup(struct |
2447 |
+ inode = ext2_iget(dir->i_sb, ino); |
2448 |
+ if (IS_ERR(inode)) |
2449 |
+ return ERR_CAST(inode); |
2450 |
++ dx_propagate_tag(nd, inode); |
2451 |
+ } |
2452 |
+ return d_splice_alias(inode, dentry); |
2453 |
+ } |
2454 |
+@@ -388,6 +390,7 @@ const struct inode_operations ext2_dir_i |
2455 |
+ #endif |
2456 |
+ .setattr = ext2_setattr, |
2457 |
+ .permission = ext2_permission, |
2458 |
++ .sync_flags = ext2_sync_flags, |
2459 |
+ }; |
2460 |
+ |
2461 |
+ const struct inode_operations ext2_special_inode_operations = { |
2462 |
+@@ -399,4 +402,5 @@ const struct inode_operations ext2_speci |
2463 |
+ #endif |
2464 |
+ .setattr = ext2_setattr, |
2465 |
+ .permission = ext2_permission, |
2466 |
++ .sync_flags = ext2_sync_flags, |
2467 |
+ }; |
2468 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext2/super.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/super.c |
2469 |
+--- linux-2.6.29.4/fs/ext2/super.c 2009-03-24 14:22:25.000000000 +0100 |
2470 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/super.c 2009-03-24 14:48:35.000000000 +0100 |
2471 |
+@@ -391,7 +391,8 @@ enum { |
2472 |
+ Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug, |
2473 |
+ Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr, |
2474 |
+ Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota, |
2475 |
+- Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation |
2476 |
++ Opt_usrquota, Opt_grpquota, Opt_reservation, Opt_noreservation, |
2477 |
++ Opt_tag, Opt_notag, Opt_tagid |
2478 |
+ }; |
2479 |
+ |
2480 |
+ static const match_table_t tokens = { |
2481 |
+@@ -419,6 +420,9 @@ static const match_table_t tokens = { |
2482 |
+ {Opt_acl, "acl"}, |
2483 |
+ {Opt_noacl, "noacl"}, |
2484 |
+ {Opt_xip, "xip"}, |
2485 |
++ {Opt_tag, "tag"}, |
2486 |
++ {Opt_notag, "notag"}, |
2487 |
++ {Opt_tagid, "tagid=%u"}, |
2488 |
+ {Opt_grpquota, "grpquota"}, |
2489 |
+ {Opt_ignore, "noquota"}, |
2490 |
+ {Opt_quota, "quota"}, |
2491 |
+@@ -489,6 +493,20 @@ static int parse_options (char * options |
2492 |
+ case Opt_nouid32: |
2493 |
+ set_opt (sbi->s_mount_opt, NO_UID32); |
2494 |
+ break; |
2495 |
++#ifndef CONFIG_TAGGING_NONE |
2496 |
++ case Opt_tag: |
2497 |
++ set_opt (sbi->s_mount_opt, TAGGED); |
2498 |
++ break; |
2499 |
++ case Opt_notag: |
2500 |
++ clear_opt (sbi->s_mount_opt, TAGGED); |
2501 |
++ break; |
2502 |
++#endif |
2503 |
++#ifdef CONFIG_PROPAGATE |
2504 |
++ case Opt_tagid: |
2505 |
++ /* use args[0] */ |
2506 |
++ set_opt (sbi->s_mount_opt, TAGGED); |
2507 |
++ break; |
2508 |
++#endif |
2509 |
+ case Opt_nocheck: |
2510 |
+ clear_opt (sbi->s_mount_opt, CHECK); |
2511 |
+ break; |
2512 |
+@@ -838,6 +856,8 @@ static int ext2_fill_super(struct super_ |
2513 |
+ if (!parse_options ((char *) data, sbi)) |
2514 |
+ goto failed_mount; |
2515 |
+ |
2516 |
++ if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED) |
2517 |
++ sb->s_flags |= MS_TAGGED; |
2518 |
+ sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
2519 |
+ ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? |
2520 |
+ MS_POSIXACL : 0); |
2521 |
+@@ -1170,6 +1190,13 @@ static int ext2_remount (struct super_bl |
2522 |
+ goto restore_opts; |
2523 |
+ } |
2524 |
+ |
2525 |
++ if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) && |
2526 |
++ !(sb->s_flags & MS_TAGGED)) { |
2527 |
++ printk("EXT2-fs: %s: tagging not permitted on remount.\n", |
2528 |
++ sb->s_id); |
2529 |
++ return -EINVAL; |
2530 |
++ } |
2531 |
++ |
2532 |
+ sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
2533 |
+ ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); |
2534 |
+ |
2535 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext2/symlink.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/symlink.c |
2536 |
+--- linux-2.6.29.4/fs/ext2/symlink.c 2008-12-25 00:26:37.000000000 +0100 |
2537 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/symlink.c 2009-02-22 22:54:25.000000000 +0100 |
2538 |
+@@ -38,6 +38,7 @@ const struct inode_operations ext2_symli |
2539 |
+ .listxattr = ext2_listxattr, |
2540 |
+ .removexattr = generic_removexattr, |
2541 |
+ #endif |
2542 |
++ .sync_flags = ext2_sync_flags, |
2543 |
+ }; |
2544 |
+ |
2545 |
+ const struct inode_operations ext2_fast_symlink_inode_operations = { |
2546 |
+@@ -49,4 +50,5 @@ const struct inode_operations ext2_fast_ |
2547 |
+ .listxattr = ext2_listxattr, |
2548 |
+ .removexattr = generic_removexattr, |
2549 |
+ #endif |
2550 |
++ .sync_flags = ext2_sync_flags, |
2551 |
+ }; |
2552 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext2/xattr.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/xattr.c |
2553 |
+--- linux-2.6.29.4/fs/ext2/xattr.c 2008-12-25 00:26:37.000000000 +0100 |
2554 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext2/xattr.c 2009-02-22 22:54:25.000000000 +0100 |
2555 |
+@@ -60,6 +60,7 @@ |
2556 |
+ #include <linux/mbcache.h> |
2557 |
+ #include <linux/quotaops.h> |
2558 |
+ #include <linux/rwsem.h> |
2559 |
++#include <linux/vs_dlimit.h> |
2560 |
+ #include "ext2.h" |
2561 |
+ #include "xattr.h" |
2562 |
+ #include "acl.h" |
2563 |
+@@ -641,8 +642,12 @@ ext2_xattr_set2(struct inode *inode, str |
2564 |
+ the inode. */ |
2565 |
+ ea_bdebug(new_bh, "reusing block"); |
2566 |
+ |
2567 |
++ error = -ENOSPC; |
2568 |
++ if (DLIMIT_ALLOC_BLOCK(inode, 1)) |
2569 |
++ goto cleanup; |
2570 |
+ error = -EDQUOT; |
2571 |
+ if (DQUOT_ALLOC_BLOCK(inode, 1)) { |
2572 |
++ DLIMIT_FREE_BLOCK(inode, 1); |
2573 |
+ unlock_buffer(new_bh); |
2574 |
+ goto cleanup; |
2575 |
+ } |
2576 |
+@@ -731,6 +736,7 @@ ext2_xattr_set2(struct inode *inode, str |
2577 |
+ le32_add_cpu(&HDR(old_bh)->h_refcount, -1); |
2578 |
+ if (ce) |
2579 |
+ mb_cache_entry_release(ce); |
2580 |
++ DLIMIT_FREE_BLOCK(inode, 1); |
2581 |
+ DQUOT_FREE_BLOCK(inode, 1); |
2582 |
+ mark_buffer_dirty(old_bh); |
2583 |
+ ea_bdebug(old_bh, "refcount now=%d", |
2584 |
+@@ -794,6 +800,7 @@ ext2_xattr_delete_inode(struct inode *in |
2585 |
+ mark_buffer_dirty(bh); |
2586 |
+ if (IS_SYNC(inode)) |
2587 |
+ sync_dirty_buffer(bh); |
2588 |
++ DLIMIT_FREE_BLOCK(inode, 1); |
2589 |
+ DQUOT_FREE_BLOCK(inode, 1); |
2590 |
+ } |
2591 |
+ EXT2_I(inode)->i_file_acl = 0; |
2592 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext3/balloc.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/balloc.c |
2593 |
+--- linux-2.6.29.4/fs/ext3/balloc.c 2009-03-24 14:22:25.000000000 +0100 |
2594 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/balloc.c 2009-03-25 00:53:20.000000000 +0100 |
2595 |
+@@ -19,6 +19,8 @@ |
2596 |
+ #include <linux/ext3_jbd.h> |
2597 |
+ #include <linux/quotaops.h> |
2598 |
+ #include <linux/buffer_head.h> |
2599 |
++#include <linux/vs_dlimit.h> |
2600 |
++#include <linux/vs_tag.h> |
2601 |
+ |
2602 |
+ /* |
2603 |
+ * balloc.c contains the blocks allocation and deallocation routines |
2604 |
+@@ -675,8 +677,10 @@ void ext3_free_blocks(handle_t *handle, |
2605 |
+ return; |
2606 |
+ } |
2607 |
+ ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks); |
2608 |
+- if (dquot_freed_blocks) |
2609 |
++ if (dquot_freed_blocks) { |
2610 |
++ DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks); |
2611 |
+ DQUOT_FREE_BLOCK(inode, dquot_freed_blocks); |
2612 |
++ } |
2613 |
+ return; |
2614 |
+ } |
2615 |
+ |
2616 |
+@@ -1415,18 +1419,33 @@ out: |
2617 |
+ * |
2618 |
+ * Check if filesystem has at least 1 free block available for allocation. |
2619 |
+ */ |
2620 |
+-static int ext3_has_free_blocks(struct ext3_sb_info *sbi) |
2621 |
++static int ext3_has_free_blocks(struct super_block *sb) |
2622 |
+ { |
2623 |
+- ext3_fsblk_t free_blocks, root_blocks; |
2624 |
++ struct ext3_sb_info *sbi = EXT3_SB(sb); |
2625 |
++ unsigned long long free_blocks, root_blocks; |
2626 |
++ int cond; |
2627 |
+ |
2628 |
+ free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
2629 |
+ root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); |
2630 |
+- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && |
2631 |
++ |
2632 |
++ vxdprintk(VXD_CBIT(dlim, 3), |
2633 |
++ "ext3_has_free_blocks(%p): free=%llu, root=%llu", |
2634 |
++ sb, free_blocks, root_blocks); |
2635 |
++ |
2636 |
++ DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks); |
2637 |
++ |
2638 |
++ cond = (free_blocks < root_blocks + 1 && |
2639 |
++ !capable(CAP_SYS_RESOURCE) && |
2640 |
+ sbi->s_resuid != current_fsuid() && |
2641 |
+- (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { |
2642 |
+- return 0; |
2643 |
+- } |
2644 |
+- return 1; |
2645 |
++ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))); |
2646 |
++ |
2647 |
++ vxdprintk(VXD_CBIT(dlim, 3), |
2648 |
++ "ext3_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d", |
2649 |
++ sb, free_blocks, root_blocks, |
2650 |
++ !capable(CAP_SYS_RESOURCE)?'1':'0', |
2651 |
++ sbi->s_resuid, current_fsuid(), cond?0:1); |
2652 |
++ |
2653 |
++ return (cond ? 0 : 1); |
2654 |
+ } |
2655 |
+ |
2656 |
+ /** |
2657 |
+@@ -1443,7 +1462,7 @@ static int ext3_has_free_blocks(struct e |
2658 |
+ */ |
2659 |
+ int ext3_should_retry_alloc(struct super_block *sb, int *retries) |
2660 |
+ { |
2661 |
+- if (!ext3_has_free_blocks(EXT3_SB(sb)) || (*retries)++ > 3) |
2662 |
++ if (!ext3_has_free_blocks(sb) || (*retries)++ > 3) |
2663 |
+ return 0; |
2664 |
+ |
2665 |
+ jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); |
2666 |
+@@ -1506,6 +1525,8 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h |
2667 |
+ *errp = -EDQUOT; |
2668 |
+ return 0; |
2669 |
+ } |
2670 |
++ if (DLIMIT_ALLOC_BLOCK(inode, num)) |
2671 |
++ goto out_dlimit; |
2672 |
+ |
2673 |
+ sbi = EXT3_SB(sb); |
2674 |
+ es = EXT3_SB(sb)->s_es; |
2675 |
+@@ -1522,7 +1543,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h |
2676 |
+ if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0)) |
2677 |
+ my_rsv = &block_i->rsv_window_node; |
2678 |
+ |
2679 |
+- if (!ext3_has_free_blocks(sbi)) { |
2680 |
++ if (!ext3_has_free_blocks(sb)) { |
2681 |
+ *errp = -ENOSPC; |
2682 |
+ goto out; |
2683 |
+ } |
2684 |
+@@ -1715,12 +1736,16 @@ allocated: |
2685 |
+ *errp = 0; |
2686 |
+ brelse(bitmap_bh); |
2687 |
+ DQUOT_FREE_BLOCK(inode, *count-num); |
2688 |
++ DLIMIT_FREE_BLOCK(inode, *count-num); |
2689 |
+ *count = num; |
2690 |
+ return ret_block; |
2691 |
+ |
2692 |
+ io_error: |
2693 |
+ *errp = -EIO; |
2694 |
+ out: |
2695 |
++ if (!performed_allocation) |
2696 |
++ DLIMIT_FREE_BLOCK(inode, *count); |
2697 |
++out_dlimit: |
2698 |
+ if (fatal) { |
2699 |
+ *errp = fatal; |
2700 |
+ ext3_std_error(sb, fatal); |
2701 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext3/file.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/file.c |
2702 |
+--- linux-2.6.29.4/fs/ext3/file.c 2008-12-25 00:26:37.000000000 +0100 |
2703 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/file.c 2009-02-22 22:54:25.000000000 +0100 |
2704 |
+@@ -135,5 +135,6 @@ const struct inode_operations ext3_file_ |
2705 |
+ #endif |
2706 |
+ .permission = ext3_permission, |
2707 |
+ .fiemap = ext3_fiemap, |
2708 |
++ .sync_flags = ext3_sync_flags, |
2709 |
+ }; |
2710 |
+ |
2711 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext3/ialloc.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/ialloc.c |
2712 |
+--- linux-2.6.29.4/fs/ext3/ialloc.c 2009-03-24 14:22:25.000000000 +0100 |
2713 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/ialloc.c 2009-03-24 15:44:06.000000000 +0100 |
2714 |
+@@ -23,6 +23,8 @@ |
2715 |
+ #include <linux/buffer_head.h> |
2716 |
+ #include <linux/random.h> |
2717 |
+ #include <linux/bitops.h> |
2718 |
++#include <linux/vs_dlimit.h> |
2719 |
++#include <linux/vs_tag.h> |
2720 |
+ |
2721 |
+ #include <asm/byteorder.h> |
2722 |
+ |
2723 |
+@@ -127,6 +129,7 @@ void ext3_free_inode (handle_t *handle, |
2724 |
+ ext3_xattr_delete_inode(handle, inode); |
2725 |
+ DQUOT_FREE_INODE(inode); |
2726 |
+ DQUOT_DROP(inode); |
2727 |
++ DLIMIT_FREE_INODE(inode); |
2728 |
+ |
2729 |
+ is_directory = S_ISDIR(inode->i_mode); |
2730 |
+ |
2731 |
+@@ -440,6 +443,12 @@ struct inode *ext3_new_inode(handle_t *h |
2732 |
+ inode = new_inode(sb); |
2733 |
+ if (!inode) |
2734 |
+ return ERR_PTR(-ENOMEM); |
2735 |
++ |
2736 |
++ inode->i_tag = dx_current_fstag(sb); |
2737 |
++ if (DLIMIT_ALLOC_INODE(inode)) { |
2738 |
++ err = -ENOSPC; |
2739 |
++ goto out_dlimit; |
2740 |
++ } |
2741 |
+ ei = EXT3_I(inode); |
2742 |
+ |
2743 |
+ sbi = EXT3_SB(sb); |
2744 |
+@@ -613,6 +622,8 @@ got: |
2745 |
+ fail: |
2746 |
+ ext3_std_error(sb, err); |
2747 |
+ out: |
2748 |
++ DLIMIT_FREE_INODE(inode); |
2749 |
++out_dlimit: |
2750 |
+ iput(inode); |
2751 |
+ ret = ERR_PTR(err); |
2752 |
+ really_out: |
2753 |
+@@ -624,6 +635,7 @@ fail_free_drop: |
2754 |
+ |
2755 |
+ fail_drop: |
2756 |
+ DQUOT_DROP(inode); |
2757 |
++ DLIMIT_FREE_INODE(inode); |
2758 |
+ inode->i_flags |= S_NOQUOTA; |
2759 |
+ inode->i_nlink = 0; |
2760 |
+ unlock_new_inode(inode); |
2761 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext3/inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/inode.c |
2762 |
+--- linux-2.6.29.4/fs/ext3/inode.c 2009-03-24 14:22:25.000000000 +0100 |
2763 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/inode.c 2009-03-24 15:44:29.000000000 +0100 |
2764 |
+@@ -38,6 +38,7 @@ |
2765 |
+ #include <linux/bio.h> |
2766 |
+ #include <linux/fiemap.h> |
2767 |
+ #include <linux/namei.h> |
2768 |
++#include <linux/vs_tag.h> |
2769 |
+ #include "xattr.h" |
2770 |
+ #include "acl.h" |
2771 |
+ |
2772 |
+@@ -2288,7 +2289,7 @@ static void ext3_free_branches(handle_t |
2773 |
+ |
2774 |
+ int ext3_can_truncate(struct inode *inode) |
2775 |
+ { |
2776 |
+- if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
2777 |
++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode)) |
2778 |
+ return 0; |
2779 |
+ if (S_ISREG(inode->i_mode)) |
2780 |
+ return 1; |
2781 |
+@@ -2662,36 +2663,84 @@ void ext3_set_inode_flags(struct inode * |
2782 |
+ { |
2783 |
+ unsigned int flags = EXT3_I(inode)->i_flags; |
2784 |
+ |
2785 |
+- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); |
2786 |
++ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK | |
2787 |
++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC); |
2788 |
++ |
2789 |
++ if (flags & EXT3_IMMUTABLE_FL) |
2790 |
++ inode->i_flags |= S_IMMUTABLE; |
2791 |
++ if (flags & EXT3_IXUNLINK_FL) |
2792 |
++ inode->i_flags |= S_IXUNLINK; |
2793 |
++ |
2794 |
+ if (flags & EXT3_SYNC_FL) |
2795 |
+ inode->i_flags |= S_SYNC; |
2796 |
+ if (flags & EXT3_APPEND_FL) |
2797 |
+ inode->i_flags |= S_APPEND; |
2798 |
+- if (flags & EXT3_IMMUTABLE_FL) |
2799 |
+- inode->i_flags |= S_IMMUTABLE; |
2800 |
+ if (flags & EXT3_NOATIME_FL) |
2801 |
+ inode->i_flags |= S_NOATIME; |
2802 |
+ if (flags & EXT3_DIRSYNC_FL) |
2803 |
+ inode->i_flags |= S_DIRSYNC; |
2804 |
++ |
2805 |
++ inode->i_vflags &= ~(V_BARRIER | V_COW); |
2806 |
++ |
2807 |
++ if (flags & EXT3_BARRIER_FL) |
2808 |
++ inode->i_vflags |= V_BARRIER; |
2809 |
++ if (flags & EXT3_COW_FL) |
2810 |
++ inode->i_vflags |= V_COW; |
2811 |
+ } |
2812 |
+ |
2813 |
+ /* Propagate flags from i_flags to EXT3_I(inode)->i_flags */ |
2814 |
+ void ext3_get_inode_flags(struct ext3_inode_info *ei) |
2815 |
+ { |
2816 |
+ unsigned int flags = ei->vfs_inode.i_flags; |
2817 |
++ unsigned int vflags = ei->vfs_inode.i_vflags; |
2818 |
++ |
2819 |
++ ei->i_flags &= ~(EXT3_SYNC_FL | EXT3_APPEND_FL | |
2820 |
++ EXT3_IMMUTABLE_FL | EXT3_IXUNLINK_FL | |
2821 |
++ EXT3_NOATIME_FL | EXT3_DIRSYNC_FL | |
2822 |
++ EXT3_BARRIER_FL | EXT3_COW_FL); |
2823 |
++ |
2824 |
++ if (flags & S_IMMUTABLE) |
2825 |
++ ei->i_flags |= EXT3_IMMUTABLE_FL; |
2826 |
++ if (flags & S_IXUNLINK) |
2827 |
++ ei->i_flags |= EXT3_IXUNLINK_FL; |
2828 |
+ |
2829 |
+- ei->i_flags &= ~(EXT3_SYNC_FL|EXT3_APPEND_FL| |
2830 |
+- EXT3_IMMUTABLE_FL|EXT3_NOATIME_FL|EXT3_DIRSYNC_FL); |
2831 |
+ if (flags & S_SYNC) |
2832 |
+ ei->i_flags |= EXT3_SYNC_FL; |
2833 |
+ if (flags & S_APPEND) |
2834 |
+ ei->i_flags |= EXT3_APPEND_FL; |
2835 |
+- if (flags & S_IMMUTABLE) |
2836 |
+- ei->i_flags |= EXT3_IMMUTABLE_FL; |
2837 |
+ if (flags & S_NOATIME) |
2838 |
+ ei->i_flags |= EXT3_NOATIME_FL; |
2839 |
+ if (flags & S_DIRSYNC) |
2840 |
+ ei->i_flags |= EXT3_DIRSYNC_FL; |
2841 |
++ |
2842 |
++ if (vflags & V_BARRIER) |
2843 |
++ ei->i_flags |= EXT3_BARRIER_FL; |
2844 |
++ if (vflags & V_COW) |
2845 |
++ ei->i_flags |= EXT3_COW_FL; |
2846 |
++} |
2847 |
++ |
2848 |
++int ext3_sync_flags(struct inode *inode) |
2849 |
++{ |
2850 |
++ struct ext3_iloc iloc; |
2851 |
++ handle_t *handle; |
2852 |
++ int err; |
2853 |
++ |
2854 |
++ handle = ext3_journal_start(inode, 1); |
2855 |
++ if (IS_ERR(handle)) |
2856 |
++ return PTR_ERR(handle); |
2857 |
++ if (IS_SYNC(inode)) |
2858 |
++ handle->h_sync = 1; |
2859 |
++ err = ext3_reserve_inode_write(handle, inode, &iloc); |
2860 |
++ if (err) |
2861 |
++ goto flags_err; |
2862 |
++ |
2863 |
++ ext3_get_inode_flags(EXT3_I(inode)); |
2864 |
++ inode->i_ctime = CURRENT_TIME; |
2865 |
++ |
2866 |
++ err = ext3_mark_iloc_dirty(handle, inode, &iloc); |
2867 |
++flags_err: |
2868 |
++ ext3_journal_stop(handle); |
2869 |
++ return err; |
2870 |
+ } |
2871 |
+ |
2872 |
+ struct inode *ext3_iget(struct super_block *sb, unsigned long ino) |
2873 |
+@@ -2703,6 +2752,8 @@ struct inode *ext3_iget(struct super_blo |
2874 |
+ struct inode *inode; |
2875 |
+ long ret; |
2876 |
+ int block; |
2877 |
++ uid_t uid; |
2878 |
++ gid_t gid; |
2879 |
+ |
2880 |
+ inode = iget_locked(sb, ino); |
2881 |
+ if (!inode) |
2882 |
+@@ -2723,12 +2774,17 @@ struct inode *ext3_iget(struct super_blo |
2883 |
+ bh = iloc.bh; |
2884 |
+ raw_inode = ext3_raw_inode(&iloc); |
2885 |
+ inode->i_mode = le16_to_cpu(raw_inode->i_mode); |
2886 |
+- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); |
2887 |
+- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); |
2888 |
++ uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); |
2889 |
++ gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); |
2890 |
+ if(!(test_opt (inode->i_sb, NO_UID32))) { |
2891 |
+- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; |
2892 |
+- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; |
2893 |
++ uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; |
2894 |
++ gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; |
2895 |
+ } |
2896 |
++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid); |
2897 |
++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid); |
2898 |
++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid, |
2899 |
++ le16_to_cpu(raw_inode->i_raw_tag)); |
2900 |
++ |
2901 |
+ inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); |
2902 |
+ inode->i_size = le32_to_cpu(raw_inode->i_size); |
2903 |
+ inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime); |
2904 |
+@@ -2859,6 +2915,8 @@ static int ext3_do_update_inode(handle_t |
2905 |
+ struct ext3_inode *raw_inode = ext3_raw_inode(iloc); |
2906 |
+ struct ext3_inode_info *ei = EXT3_I(inode); |
2907 |
+ struct buffer_head *bh = iloc->bh; |
2908 |
++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag); |
2909 |
++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag); |
2910 |
+ int err = 0, rc, block; |
2911 |
+ |
2912 |
+ /* For fields not not tracking in the in-memory inode, |
2913 |
+@@ -2869,29 +2927,32 @@ static int ext3_do_update_inode(handle_t |
2914 |
+ ext3_get_inode_flags(ei); |
2915 |
+ raw_inode->i_mode = cpu_to_le16(inode->i_mode); |
2916 |
+ if(!(test_opt(inode->i_sb, NO_UID32))) { |
2917 |
+- raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); |
2918 |
+- raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid)); |
2919 |
++ raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid)); |
2920 |
++ raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid)); |
2921 |
+ /* |
2922 |
+ * Fix up interoperability with old kernels. Otherwise, old inodes get |
2923 |
+ * re-used with the upper 16 bits of the uid/gid intact |
2924 |
+ */ |
2925 |
+ if(!ei->i_dtime) { |
2926 |
+ raw_inode->i_uid_high = |
2927 |
+- cpu_to_le16(high_16_bits(inode->i_uid)); |
2928 |
++ cpu_to_le16(high_16_bits(uid)); |
2929 |
+ raw_inode->i_gid_high = |
2930 |
+- cpu_to_le16(high_16_bits(inode->i_gid)); |
2931 |
++ cpu_to_le16(high_16_bits(gid)); |
2932 |
+ } else { |
2933 |
+ raw_inode->i_uid_high = 0; |
2934 |
+ raw_inode->i_gid_high = 0; |
2935 |
+ } |
2936 |
+ } else { |
2937 |
+ raw_inode->i_uid_low = |
2938 |
+- cpu_to_le16(fs_high2lowuid(inode->i_uid)); |
2939 |
++ cpu_to_le16(fs_high2lowuid(uid)); |
2940 |
+ raw_inode->i_gid_low = |
2941 |
+- cpu_to_le16(fs_high2lowgid(inode->i_gid)); |
2942 |
++ cpu_to_le16(fs_high2lowgid(gid)); |
2943 |
+ raw_inode->i_uid_high = 0; |
2944 |
+ raw_inode->i_gid_high = 0; |
2945 |
+ } |
2946 |
++#ifdef CONFIG_TAGGING_INTERN |
2947 |
++ raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag); |
2948 |
++#endif |
2949 |
+ raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); |
2950 |
+ raw_inode->i_size = cpu_to_le32(ei->i_disksize); |
2951 |
+ raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); |
2952 |
+@@ -3044,7 +3105,8 @@ int ext3_setattr(struct dentry *dentry, |
2953 |
+ return error; |
2954 |
+ |
2955 |
+ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || |
2956 |
+- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { |
2957 |
++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) || |
2958 |
++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) { |
2959 |
+ handle_t *handle; |
2960 |
+ |
2961 |
+ /* (user+group)*(old+new) structure, inode write (sb, |
2962 |
+@@ -3066,6 +3128,8 @@ int ext3_setattr(struct dentry *dentry, |
2963 |
+ inode->i_uid = attr->ia_uid; |
2964 |
+ if (attr->ia_valid & ATTR_GID) |
2965 |
+ inode->i_gid = attr->ia_gid; |
2966 |
++ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode)) |
2967 |
++ inode->i_tag = attr->ia_tag; |
2968 |
+ error = ext3_mark_inode_dirty(handle, inode); |
2969 |
+ ext3_journal_stop(handle); |
2970 |
+ } |
2971 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext3/ioctl.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/ioctl.c |
2972 |
+--- linux-2.6.29.4/fs/ext3/ioctl.c 2009-03-24 14:22:25.000000000 +0100 |
2973 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/ioctl.c 2009-03-24 14:48:35.000000000 +0100 |
2974 |
+@@ -8,6 +8,7 @@ |
2975 |
+ */ |
2976 |
+ |
2977 |
+ #include <linux/fs.h> |
2978 |
++#include <linux/mount.h> |
2979 |
+ #include <linux/jbd.h> |
2980 |
+ #include <linux/capability.h> |
2981 |
+ #include <linux/ext3_fs.h> |
2982 |
+@@ -16,6 +17,7 @@ |
2983 |
+ #include <linux/time.h> |
2984 |
+ #include <linux/compat.h> |
2985 |
+ #include <linux/smp_lock.h> |
2986 |
++#include <linux/vs_tag.h> |
2987 |
+ #include <asm/uaccess.h> |
2988 |
+ |
2989 |
+ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, |
2990 |
+@@ -55,6 +57,11 @@ int ext3_ioctl (struct inode * inode, st |
2991 |
+ |
2992 |
+ flags = ext3_mask_flags(inode->i_mode, flags); |
2993 |
+ |
2994 |
++ if (IS_BARRIER(inode)) { |
2995 |
++ vxwprintk_task(1, "messing with the barrier."); |
2996 |
++ return -EACCES; |
2997 |
++ } |
2998 |
++ |
2999 |
+ mutex_lock(&inode->i_mutex); |
3000 |
+ /* Is it quota file? Do not allow user to mess with it */ |
3001 |
+ if (IS_NOQUOTA(inode)) { |
3002 |
+@@ -73,7 +80,9 @@ int ext3_ioctl (struct inode * inode, st |
3003 |
+ * |
3004 |
+ * This test looks nicer. Thanks to Pauline Middelink |
3005 |
+ */ |
3006 |
+- if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) { |
3007 |
++ if ((oldflags & EXT3_IMMUTABLE_FL) || |
3008 |
++ ((flags ^ oldflags) & (EXT3_APPEND_FL | |
3009 |
++ EXT3_IMMUTABLE_FL | EXT3_IXUNLINK_FL))) { |
3010 |
+ if (!capable(CAP_LINUX_IMMUTABLE)) { |
3011 |
+ mutex_unlock(&inode->i_mutex); |
3012 |
+ err = -EPERM; |
3013 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext3/namei.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/namei.c |
3014 |
+--- linux-2.6.29.4/fs/ext3/namei.c 2009-03-24 14:22:25.000000000 +0100 |
3015 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/namei.c 2009-03-24 14:48:35.000000000 +0100 |
3016 |
+@@ -36,6 +36,7 @@ |
3017 |
+ #include <linux/quotaops.h> |
3018 |
+ #include <linux/buffer_head.h> |
3019 |
+ #include <linux/bio.h> |
3020 |
++#include <linux/vs_tag.h> |
3021 |
+ |
3022 |
+ #include "namei.h" |
3023 |
+ #include "xattr.h" |
3024 |
+@@ -912,6 +913,7 @@ restart: |
3025 |
+ if (bh) |
3026 |
+ ll_rw_block(READ_META, 1, &bh); |
3027 |
+ } |
3028 |
++ dx_propagate_tag(nd, inode); |
3029 |
+ } |
3030 |
+ if ((bh = bh_use[ra_ptr++]) == NULL) |
3031 |
+ goto next; |
3032 |
+@@ -2433,6 +2435,7 @@ const struct inode_operations ext3_dir_i |
3033 |
+ .removexattr = generic_removexattr, |
3034 |
+ #endif |
3035 |
+ .permission = ext3_permission, |
3036 |
++ .sync_flags = ext3_sync_flags, |
3037 |
+ }; |
3038 |
+ |
3039 |
+ const struct inode_operations ext3_special_inode_operations = { |
3040 |
+@@ -2444,4 +2447,5 @@ const struct inode_operations ext3_speci |
3041 |
+ .removexattr = generic_removexattr, |
3042 |
+ #endif |
3043 |
+ .permission = ext3_permission, |
3044 |
++ .sync_flags = ext3_sync_flags, |
3045 |
+ }; |
3046 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext3/super.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/super.c |
3047 |
+--- linux-2.6.29.4/fs/ext3/super.c 2009-03-24 14:22:25.000000000 +0100 |
3048 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/super.c 2009-03-24 14:48:35.000000000 +0100 |
3049 |
+@@ -790,7 +790,7 @@ enum { |
3050 |
+ Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
3051 |
+ Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
3052 |
+ Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, |
3053 |
+- Opt_grpquota |
3054 |
++ Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid |
3055 |
+ }; |
3056 |
+ |
3057 |
+ static const match_table_t tokens = { |
3058 |
+@@ -843,6 +843,9 @@ static const match_table_t tokens = { |
3059 |
+ {Opt_usrquota, "usrquota"}, |
3060 |
+ {Opt_barrier, "barrier=%u"}, |
3061 |
+ {Opt_resize, "resize"}, |
3062 |
++ {Opt_tag, "tag"}, |
3063 |
++ {Opt_notag, "notag"}, |
3064 |
++ {Opt_tagid, "tagid=%u"}, |
3065 |
+ {Opt_err, NULL}, |
3066 |
+ }; |
3067 |
+ |
3068 |
+@@ -935,6 +938,20 @@ static int parse_options (char *options, |
3069 |
+ case Opt_nouid32: |
3070 |
+ set_opt (sbi->s_mount_opt, NO_UID32); |
3071 |
+ break; |
3072 |
++#ifndef CONFIG_TAGGING_NONE |
3073 |
++ case Opt_tag: |
3074 |
++ set_opt (sbi->s_mount_opt, TAGGED); |
3075 |
++ break; |
3076 |
++ case Opt_notag: |
3077 |
++ clear_opt (sbi->s_mount_opt, TAGGED); |
3078 |
++ break; |
3079 |
++#endif |
3080 |
++#ifdef CONFIG_PROPAGATE |
3081 |
++ case Opt_tagid: |
3082 |
++ /* use args[0] */ |
3083 |
++ set_opt (sbi->s_mount_opt, TAGGED); |
3084 |
++ break; |
3085 |
++#endif |
3086 |
+ case Opt_nocheck: |
3087 |
+ clear_opt (sbi->s_mount_opt, CHECK); |
3088 |
+ break; |
3089 |
+@@ -1653,6 +1670,9 @@ static int ext3_fill_super (struct super |
3090 |
+ NULL, 0)) |
3091 |
+ goto failed_mount; |
3092 |
+ |
3093 |
++ if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAGGED) |
3094 |
++ sb->s_flags |= MS_TAGGED; |
3095 |
++ |
3096 |
+ sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
3097 |
+ ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); |
3098 |
+ |
3099 |
+@@ -2527,6 +2547,13 @@ static int ext3_remount (struct super_bl |
3100 |
+ if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) |
3101 |
+ ext3_abort(sb, __func__, "Abort forced by user"); |
3102 |
+ |
3103 |
++ if ((sbi->s_mount_opt & EXT3_MOUNT_TAGGED) && |
3104 |
++ !(sb->s_flags & MS_TAGGED)) { |
3105 |
++ printk("EXT3-fs: %s: tagging not permitted on remount.\n", |
3106 |
++ sb->s_id); |
3107 |
++ return -EINVAL; |
3108 |
++ } |
3109 |
++ |
3110 |
+ sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
3111 |
+ ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); |
3112 |
+ |
3113 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext3/symlink.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/symlink.c |
3114 |
+--- linux-2.6.29.4/fs/ext3/symlink.c 2008-12-25 00:26:37.000000000 +0100 |
3115 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/symlink.c 2009-02-22 22:54:25.000000000 +0100 |
3116 |
+@@ -40,6 +40,7 @@ const struct inode_operations ext3_symli |
3117 |
+ .listxattr = ext3_listxattr, |
3118 |
+ .removexattr = generic_removexattr, |
3119 |
+ #endif |
3120 |
++ .sync_flags = ext3_sync_flags, |
3121 |
+ }; |
3122 |
+ |
3123 |
+ const struct inode_operations ext3_fast_symlink_inode_operations = { |
3124 |
+@@ -51,4 +52,5 @@ const struct inode_operations ext3_fast_ |
3125 |
+ .listxattr = ext3_listxattr, |
3126 |
+ .removexattr = generic_removexattr, |
3127 |
+ #endif |
3128 |
++ .sync_flags = ext3_sync_flags, |
3129 |
+ }; |
3130 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext3/xattr.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/xattr.c |
3131 |
+--- linux-2.6.29.4/fs/ext3/xattr.c 2008-12-25 00:26:37.000000000 +0100 |
3132 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext3/xattr.c 2009-02-22 22:54:25.000000000 +0100 |
3133 |
+@@ -58,6 +58,7 @@ |
3134 |
+ #include <linux/mbcache.h> |
3135 |
+ #include <linux/quotaops.h> |
3136 |
+ #include <linux/rwsem.h> |
3137 |
++#include <linux/vs_dlimit.h> |
3138 |
+ #include "xattr.h" |
3139 |
+ #include "acl.h" |
3140 |
+ |
3141 |
+@@ -498,6 +499,7 @@ ext3_xattr_release_block(handle_t *handl |
3142 |
+ error = ext3_journal_dirty_metadata(handle, bh); |
3143 |
+ if (IS_SYNC(inode)) |
3144 |
+ handle->h_sync = 1; |
3145 |
++ DLIMIT_FREE_BLOCK(inode, 1); |
3146 |
+ DQUOT_FREE_BLOCK(inode, 1); |
3147 |
+ ea_bdebug(bh, "refcount now=%d; releasing", |
3148 |
+ le32_to_cpu(BHDR(bh)->h_refcount)); |
3149 |
+@@ -771,11 +773,14 @@ inserted: |
3150 |
+ if (new_bh == bs->bh) |
3151 |
+ ea_bdebug(new_bh, "keeping"); |
3152 |
+ else { |
3153 |
++ error = -ENOSPC; |
3154 |
++ if (DLIMIT_ALLOC_BLOCK(inode, 1)) |
3155 |
++ goto cleanup; |
3156 |
+ /* The old block is released after updating |
3157 |
+ the inode. */ |
3158 |
+ error = -EDQUOT; |
3159 |
+ if (DQUOT_ALLOC_BLOCK(inode, 1)) |
3160 |
+- goto cleanup; |
3161 |
++ goto cleanup_dlimit; |
3162 |
+ error = ext3_journal_get_write_access(handle, |
3163 |
+ new_bh); |
3164 |
+ if (error) |
3165 |
+@@ -849,6 +854,8 @@ cleanup: |
3166 |
+ |
3167 |
+ cleanup_dquot: |
3168 |
+ DQUOT_FREE_BLOCK(inode, 1); |
3169 |
++cleanup_dlimit: |
3170 |
++ DLIMIT_FREE_BLOCK(inode, 1); |
3171 |
+ goto cleanup; |
3172 |
+ |
3173 |
+ bad_block: |
3174 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext4/balloc.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/balloc.c |
3175 |
+--- linux-2.6.29.4/fs/ext4/balloc.c 2009-03-24 14:22:25.000000000 +0100 |
3176 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/balloc.c 2009-03-24 14:48:35.000000000 +0100 |
3177 |
+@@ -17,6 +17,8 @@ |
3178 |
+ #include <linux/jbd2.h> |
3179 |
+ #include <linux/quotaops.h> |
3180 |
+ #include <linux/buffer_head.h> |
3181 |
++#include <linux/vs_dlimit.h> |
3182 |
++#include <linux/vs_tag.h> |
3183 |
+ #include "ext4.h" |
3184 |
+ #include "ext4_jbd2.h" |
3185 |
+ #include "group.h" |
3186 |
+@@ -535,8 +537,10 @@ void ext4_free_blocks(handle_t *handle, |
3187 |
+ |
3188 |
+ ext4_mb_free_blocks(handle, inode, block, count, |
3189 |
+ metadata, &dquot_freed_blocks); |
3190 |
+- if (dquot_freed_blocks) |
3191 |
++ if (dquot_freed_blocks) { |
3192 |
++ DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks); |
3193 |
+ DQUOT_FREE_BLOCK(inode, dquot_freed_blocks); |
3194 |
++ } |
3195 |
+ return; |
3196 |
+ } |
3197 |
+ |
3198 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext4/ext4.h linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/ext4.h |
3199 |
+--- linux-2.6.29.4/fs/ext4/ext4.h 2009-05-23 23:16:52.000000000 +0200 |
3200 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/ext4.h 2009-05-23 23:19:11.000000000 +0200 |
3201 |
+@@ -243,8 +243,12 @@ struct flex_groups { |
3202 |
+ #define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */ |
3203 |
+ #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ |
3204 |
+ #define EXT4_EXT_MIGRATE 0x00100000 /* Inode is migrating */ |
3205 |
++#define EXT4_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */ |
3206 |
+ #define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */ |
3207 |
+ |
3208 |
++#define EXT4_BARRIER_FL 0x04000000 /* Barrier for chroot() */ |
3209 |
++#define EXT4_COW_FL 0x20000000 /* Copy on Write marker */ |
3210 |
++ |
3211 |
+ #define EXT4_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */ |
3212 |
+ #define EXT4_FL_USER_MODIFIABLE 0x000B80FF /* User modifiable flags */ |
3213 |
+ |
3214 |
+@@ -541,6 +545,7 @@ do { \ |
3215 |
+ #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ |
3216 |
+ #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ |
3217 |
+ #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ |
3218 |
++#define EXT4_MOUNT_TAGGED (1<<24) /* Enable Context Tags */ |
3219 |
+ |
3220 |
+ /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */ |
3221 |
+ #ifndef _LINUX_EXT2_FS_H |
3222 |
+@@ -1076,6 +1081,7 @@ struct buffer_head *ext4_bread(handle_t |
3223 |
+ ext4_lblk_t, int, int *); |
3224 |
+ int ext4_get_block(struct inode *inode, sector_t iblock, |
3225 |
+ struct buffer_head *bh_result, int create); |
3226 |
++extern int ext4_sync_flags(struct inode *inode); |
3227 |
+ |
3228 |
+ extern struct inode *ext4_iget(struct super_block *, unsigned long); |
3229 |
+ extern int ext4_write_inode(struct inode *, int); |
3230 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext4/file.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/file.c |
3231 |
+--- linux-2.6.29.4/fs/ext4/file.c 2009-03-24 14:22:25.000000000 +0100 |
3232 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/file.c 2009-03-24 14:48:35.000000000 +0100 |
3233 |
+@@ -171,5 +171,6 @@ const struct inode_operations ext4_file_ |
3234 |
+ .permission = ext4_permission, |
3235 |
+ .fallocate = ext4_fallocate, |
3236 |
+ .fiemap = ext4_fiemap, |
3237 |
++ .sync_flags = ext4_sync_flags, |
3238 |
+ }; |
3239 |
+ |
3240 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext4/ialloc.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/ialloc.c |
3241 |
+--- linux-2.6.29.4/fs/ext4/ialloc.c 2009-03-24 14:22:25.000000000 +0100 |
3242 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/ialloc.c 2009-03-24 14:48:35.000000000 +0100 |
3243 |
+@@ -22,6 +22,8 @@ |
3244 |
+ #include <linux/random.h> |
3245 |
+ #include <linux/bitops.h> |
3246 |
+ #include <linux/blkdev.h> |
3247 |
++#include <linux/vs_dlimit.h> |
3248 |
++#include <linux/vs_tag.h> |
3249 |
+ #include <asm/byteorder.h> |
3250 |
+ #include "ext4.h" |
3251 |
+ #include "ext4_jbd2.h" |
3252 |
+@@ -224,6 +226,7 @@ void ext4_free_inode(handle_t *handle, s |
3253 |
+ ext4_xattr_delete_inode(handle, inode); |
3254 |
+ DQUOT_FREE_INODE(inode); |
3255 |
+ DQUOT_DROP(inode); |
3256 |
++ DLIMIT_FREE_INODE(inode); |
3257 |
+ |
3258 |
+ is_directory = S_ISDIR(inode->i_mode); |
3259 |
+ |
3260 |
+@@ -711,6 +714,12 @@ struct inode *ext4_new_inode(handle_t *h |
3261 |
+ inode = new_inode(sb); |
3262 |
+ if (!inode) |
3263 |
+ return ERR_PTR(-ENOMEM); |
3264 |
++ |
3265 |
++ inode->i_tag = dx_current_fstag(sb); |
3266 |
++ if (DLIMIT_ALLOC_INODE(inode)) { |
3267 |
++ err = -ENOSPC; |
3268 |
++ goto out_dlimit; |
3269 |
++ } |
3270 |
+ ei = EXT4_I(inode); |
3271 |
+ |
3272 |
+ sbi = EXT4_SB(sb); |
3273 |
+@@ -889,7 +898,8 @@ got: |
3274 |
+ * newly created directory and file only if -o extent mount option is |
3275 |
+ * specified |
3276 |
+ */ |
3277 |
+- ei->i_flags = EXT4_I(dir)->i_flags & ~(EXT4_INDEX_FL|EXT4_EXTENTS_FL); |
3278 |
++ ei->i_flags = EXT4_I(dir)->i_flags & |
3279 |
++ ~(EXT4_INDEX_FL|EXT4_EXTENTS_FL|EXT4_IXUNLINK_FL|EXT4_BARRIER_FL); |
3280 |
+ if (S_ISLNK(mode)) |
3281 |
+ ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL); |
3282 |
+ /* dirsync only applies to directories */ |
3283 |
+@@ -949,6 +959,8 @@ got: |
3284 |
+ fail: |
3285 |
+ ext4_std_error(sb, err); |
3286 |
+ out: |
3287 |
++ DLIMIT_FREE_INODE(inode); |
3288 |
++out_dlimit: |
3289 |
+ iput(inode); |
3290 |
+ ret = ERR_PTR(err); |
3291 |
+ really_out: |
3292 |
+@@ -960,6 +972,7 @@ fail_free_drop: |
3293 |
+ |
3294 |
+ fail_drop: |
3295 |
+ DQUOT_DROP(inode); |
3296 |
++ DLIMIT_FREE_INODE(inode); |
3297 |
+ inode->i_flags |= S_NOQUOTA; |
3298 |
+ inode->i_nlink = 0; |
3299 |
+ unlock_new_inode(inode); |
3300 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext4/inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/inode.c |
3301 |
+--- linux-2.6.29.4/fs/ext4/inode.c 2009-05-23 23:16:52.000000000 +0200 |
3302 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/inode.c 2009-05-23 23:19:11.000000000 +0200 |
3303 |
+@@ -37,6 +37,7 @@ |
3304 |
+ #include <linux/namei.h> |
3305 |
+ #include <linux/uio.h> |
3306 |
+ #include <linux/bio.h> |
3307 |
++#include <linux/vs_tag.h> |
3308 |
+ #include "ext4_jbd2.h" |
3309 |
+ #include "xattr.h" |
3310 |
+ #include "acl.h" |
3311 |
+@@ -3781,7 +3782,7 @@ static void ext4_free_branches(handle_t |
3312 |
+ |
3313 |
+ int ext4_can_truncate(struct inode *inode) |
3314 |
+ { |
3315 |
+- if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
3316 |
++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode)) |
3317 |
+ return 0; |
3318 |
+ if (S_ISREG(inode->i_mode)) |
3319 |
+ return 1; |
3320 |
+@@ -4134,37 +4135,86 @@ void ext4_set_inode_flags(struct inode * |
3321 |
+ { |
3322 |
+ unsigned int flags = EXT4_I(inode)->i_flags; |
3323 |
+ |
3324 |
+- inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); |
3325 |
++ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK | |
3326 |
++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC); |
3327 |
++ |
3328 |
++ if (flags & EXT4_IMMUTABLE_FL) |
3329 |
++ inode->i_flags |= S_IMMUTABLE; |
3330 |
++ if (flags & EXT4_IXUNLINK_FL) |
3331 |
++ inode->i_flags |= S_IXUNLINK; |
3332 |
++ |
3333 |
+ if (flags & EXT4_SYNC_FL) |
3334 |
+ inode->i_flags |= S_SYNC; |
3335 |
+ if (flags & EXT4_APPEND_FL) |
3336 |
+ inode->i_flags |= S_APPEND; |
3337 |
+- if (flags & EXT4_IMMUTABLE_FL) |
3338 |
+- inode->i_flags |= S_IMMUTABLE; |
3339 |
+ if (flags & EXT4_NOATIME_FL) |
3340 |
+ inode->i_flags |= S_NOATIME; |
3341 |
+ if (flags & EXT4_DIRSYNC_FL) |
3342 |
+ inode->i_flags |= S_DIRSYNC; |
3343 |
++ |
3344 |
++ inode->i_vflags &= ~(V_BARRIER | V_COW); |
3345 |
++ |
3346 |
++ if (flags & EXT4_BARRIER_FL) |
3347 |
++ inode->i_vflags |= V_BARRIER; |
3348 |
++ if (flags & EXT4_COW_FL) |
3349 |
++ inode->i_vflags |= V_COW; |
3350 |
+ } |
3351 |
+ |
3352 |
+ /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ |
3353 |
+ void ext4_get_inode_flags(struct ext4_inode_info *ei) |
3354 |
+ { |
3355 |
+ unsigned int flags = ei->vfs_inode.i_flags; |
3356 |
++ unsigned int vflags = ei->vfs_inode.i_vflags; |
3357 |
++ |
3358 |
++ ei->i_flags &= ~(EXT4_SYNC_FL | EXT4_APPEND_FL | |
3359 |
++ EXT4_IMMUTABLE_FL | EXT4_IXUNLINK_FL | |
3360 |
++ EXT4_NOATIME_FL | EXT4_DIRSYNC_FL | |
3361 |
++ EXT4_BARRIER_FL | EXT4_COW_FL); |
3362 |
++ |
3363 |
++ if (flags & S_IMMUTABLE) |
3364 |
++ ei->i_flags |= EXT4_IMMUTABLE_FL; |
3365 |
++ if (flags & S_IXUNLINK) |
3366 |
++ ei->i_flags |= EXT4_IXUNLINK_FL; |
3367 |
+ |
3368 |
+- ei->i_flags &= ~(EXT4_SYNC_FL|EXT4_APPEND_FL| |
3369 |
+- EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|EXT4_DIRSYNC_FL); |
3370 |
+ if (flags & S_SYNC) |
3371 |
+ ei->i_flags |= EXT4_SYNC_FL; |
3372 |
+ if (flags & S_APPEND) |
3373 |
+ ei->i_flags |= EXT4_APPEND_FL; |
3374 |
+- if (flags & S_IMMUTABLE) |
3375 |
+- ei->i_flags |= EXT4_IMMUTABLE_FL; |
3376 |
+ if (flags & S_NOATIME) |
3377 |
+ ei->i_flags |= EXT4_NOATIME_FL; |
3378 |
+ if (flags & S_DIRSYNC) |
3379 |
+ ei->i_flags |= EXT4_DIRSYNC_FL; |
3380 |
++ |
3381 |
++ if (vflags & V_BARRIER) |
3382 |
++ ei->i_flags |= EXT4_BARRIER_FL; |
3383 |
++ if (vflags & V_COW) |
3384 |
++ ei->i_flags |= EXT4_COW_FL; |
3385 |
++} |
3386 |
++ |
3387 |
++int ext4_sync_flags(struct inode *inode) |
3388 |
++{ |
3389 |
++ struct ext4_iloc iloc; |
3390 |
++ handle_t *handle; |
3391 |
++ int err; |
3392 |
++ |
3393 |
++ handle = ext4_journal_start(inode, 1); |
3394 |
++ if (IS_ERR(handle)) |
3395 |
++ return PTR_ERR(handle); |
3396 |
++ if (IS_SYNC(inode)) |
3397 |
++ handle->h_sync = 1; |
3398 |
++ err = ext4_reserve_inode_write(handle, inode, &iloc); |
3399 |
++ if (err) |
3400 |
++ goto flags_err; |
3401 |
++ |
3402 |
++ ext4_get_inode_flags(EXT4_I(inode)); |
3403 |
++ inode->i_ctime = CURRENT_TIME; |
3404 |
++ |
3405 |
++ err = ext4_mark_iloc_dirty(handle, inode, &iloc); |
3406 |
++flags_err: |
3407 |
++ ext4_journal_stop(handle); |
3408 |
++ return err; |
3409 |
+ } |
3410 |
++ |
3411 |
+ static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode, |
3412 |
+ struct ext4_inode_info *ei) |
3413 |
+ { |
3414 |
+@@ -4197,6 +4247,8 @@ struct inode *ext4_iget(struct super_blo |
3415 |
+ struct inode *inode; |
3416 |
+ long ret; |
3417 |
+ int block; |
3418 |
++ uid_t uid; |
3419 |
++ gid_t gid; |
3420 |
+ |
3421 |
+ inode = iget_locked(sb, ino); |
3422 |
+ if (!inode) |
3423 |
+@@ -4216,12 +4268,16 @@ struct inode *ext4_iget(struct super_blo |
3424 |
+ bh = iloc.bh; |
3425 |
+ raw_inode = ext4_raw_inode(&iloc); |
3426 |
+ inode->i_mode = le16_to_cpu(raw_inode->i_mode); |
3427 |
+- inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); |
3428 |
+- inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); |
3429 |
++ uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); |
3430 |
++ gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); |
3431 |
+ if (!(test_opt(inode->i_sb, NO_UID32))) { |
3432 |
+- inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; |
3433 |
+- inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; |
3434 |
++ uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; |
3435 |
++ gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; |
3436 |
+ } |
3437 |
++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid); |
3438 |
++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid); |
3439 |
++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid, |
3440 |
++ le16_to_cpu(raw_inode->i_raw_tag)); |
3441 |
+ inode->i_nlink = le16_to_cpu(raw_inode->i_links_count); |
3442 |
+ |
3443 |
+ ei->i_state = 0; |
3444 |
+@@ -4387,6 +4443,8 @@ static int ext4_do_update_inode(handle_t |
3445 |
+ struct ext4_inode *raw_inode = ext4_raw_inode(iloc); |
3446 |
+ struct ext4_inode_info *ei = EXT4_I(inode); |
3447 |
+ struct buffer_head *bh = iloc->bh; |
3448 |
++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag); |
3449 |
++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag); |
3450 |
+ int err = 0, rc, block; |
3451 |
+ |
3452 |
+ /* For fields not not tracking in the in-memory inode, |
3453 |
+@@ -4397,29 +4455,32 @@ static int ext4_do_update_inode(handle_t |
3454 |
+ ext4_get_inode_flags(ei); |
3455 |
+ raw_inode->i_mode = cpu_to_le16(inode->i_mode); |
3456 |
+ if (!(test_opt(inode->i_sb, NO_UID32))) { |
3457 |
+- raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); |
3458 |
+- raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid)); |
3459 |
++ raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid)); |
3460 |
++ raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid)); |
3461 |
+ /* |
3462 |
+ * Fix up interoperability with old kernels. Otherwise, old inodes get |
3463 |
+ * re-used with the upper 16 bits of the uid/gid intact |
3464 |
+ */ |
3465 |
+ if (!ei->i_dtime) { |
3466 |
+ raw_inode->i_uid_high = |
3467 |
+- cpu_to_le16(high_16_bits(inode->i_uid)); |
3468 |
++ cpu_to_le16(high_16_bits(uid)); |
3469 |
+ raw_inode->i_gid_high = |
3470 |
+- cpu_to_le16(high_16_bits(inode->i_gid)); |
3471 |
++ cpu_to_le16(high_16_bits(gid)); |
3472 |
+ } else { |
3473 |
+ raw_inode->i_uid_high = 0; |
3474 |
+ raw_inode->i_gid_high = 0; |
3475 |
+ } |
3476 |
+ } else { |
3477 |
+ raw_inode->i_uid_low = |
3478 |
+- cpu_to_le16(fs_high2lowuid(inode->i_uid)); |
3479 |
++ cpu_to_le16(fs_high2lowuid(uid)); |
3480 |
+ raw_inode->i_gid_low = |
3481 |
+- cpu_to_le16(fs_high2lowgid(inode->i_gid)); |
3482 |
++ cpu_to_le16(fs_high2lowgid(gid)); |
3483 |
+ raw_inode->i_uid_high = 0; |
3484 |
+ raw_inode->i_gid_high = 0; |
3485 |
+ } |
3486 |
++#ifdef CONFIG_TAGGING_INTERN |
3487 |
++ raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag); |
3488 |
++#endif |
3489 |
+ raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); |
3490 |
+ |
3491 |
+ EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode); |
3492 |
+@@ -4601,7 +4662,8 @@ int ext4_setattr(struct dentry *dentry, |
3493 |
+ return error; |
3494 |
+ |
3495 |
+ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || |
3496 |
+- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { |
3497 |
++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) || |
3498 |
++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) { |
3499 |
+ handle_t *handle; |
3500 |
+ |
3501 |
+ /* (user+group)*(old+new) structure, inode write (sb, |
3502 |
+@@ -4623,6 +4685,8 @@ int ext4_setattr(struct dentry *dentry, |
3503 |
+ inode->i_uid = attr->ia_uid; |
3504 |
+ if (attr->ia_valid & ATTR_GID) |
3505 |
+ inode->i_gid = attr->ia_gid; |
3506 |
++ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode)) |
3507 |
++ inode->i_tag = attr->ia_tag; |
3508 |
+ error = ext4_mark_inode_dirty(handle, inode); |
3509 |
+ ext4_journal_stop(handle); |
3510 |
+ } |
3511 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext4/ioctl.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/ioctl.c |
3512 |
+--- linux-2.6.29.4/fs/ext4/ioctl.c 2009-03-24 14:22:25.000000000 +0100 |
3513 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/ioctl.c 2009-03-24 14:48:35.000000000 +0100 |
3514 |
+@@ -8,12 +8,14 @@ |
3515 |
+ */ |
3516 |
+ |
3517 |
+ #include <linux/fs.h> |
3518 |
++#include <linux/mount.h> |
3519 |
+ #include <linux/jbd2.h> |
3520 |
+ #include <linux/capability.h> |
3521 |
+ #include <linux/time.h> |
3522 |
+ #include <linux/compat.h> |
3523 |
+ #include <linux/smp_lock.h> |
3524 |
+ #include <linux/mount.h> |
3525 |
++#include <linux/vs_tag.h> |
3526 |
+ #include <asm/uaccess.h> |
3527 |
+ #include "ext4_jbd2.h" |
3528 |
+ #include "ext4.h" |
3529 |
+@@ -51,6 +53,11 @@ long ext4_ioctl(struct file *filp, unsig |
3530 |
+ if (!S_ISDIR(inode->i_mode)) |
3531 |
+ flags &= ~EXT4_DIRSYNC_FL; |
3532 |
+ |
3533 |
++ if (IS_BARRIER(inode)) { |
3534 |
++ vxwprintk_task(1, "messing with the barrier."); |
3535 |
++ return -EACCES; |
3536 |
++ } |
3537 |
++ |
3538 |
+ err = -EPERM; |
3539 |
+ mutex_lock(&inode->i_mutex); |
3540 |
+ /* Is it quota file? Do not allow user to mess with it */ |
3541 |
+@@ -68,7 +75,9 @@ long ext4_ioctl(struct file *filp, unsig |
3542 |
+ * |
3543 |
+ * This test looks nicer. Thanks to Pauline Middelink |
3544 |
+ */ |
3545 |
+- if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) { |
3546 |
++ if ((oldflags & EXT4_IMMUTABLE_FL) || |
3547 |
++ ((flags ^ oldflags) & (EXT4_APPEND_FL | |
3548 |
++ EXT4_IMMUTABLE_FL | EXT4_IXUNLINK_FL))) { |
3549 |
+ if (!capable(CAP_LINUX_IMMUTABLE)) |
3550 |
+ goto flags_out; |
3551 |
+ } |
3552 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext4/namei.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/namei.c |
3553 |
+--- linux-2.6.29.4/fs/ext4/namei.c 2009-03-24 14:22:25.000000000 +0100 |
3554 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/namei.c 2009-03-24 14:48:35.000000000 +0100 |
3555 |
+@@ -34,6 +34,7 @@ |
3556 |
+ #include <linux/quotaops.h> |
3557 |
+ #include <linux/buffer_head.h> |
3558 |
+ #include <linux/bio.h> |
3559 |
++#include <linux/vs_tag.h> |
3560 |
+ #include "ext4.h" |
3561 |
+ #include "ext4_jbd2.h" |
3562 |
+ |
3563 |
+@@ -917,6 +918,7 @@ restart: |
3564 |
+ if (bh) |
3565 |
+ ll_rw_block(READ_META, 1, &bh); |
3566 |
+ } |
3567 |
++ dx_propagate_tag(nd, inode); |
3568 |
+ } |
3569 |
+ if ((bh = bh_use[ra_ptr++]) == NULL) |
3570 |
+ goto next; |
3571 |
+@@ -2481,6 +2483,7 @@ const struct inode_operations ext4_dir_i |
3572 |
+ .removexattr = generic_removexattr, |
3573 |
+ #endif |
3574 |
+ .permission = ext4_permission, |
3575 |
++ .sync_flags = ext4_sync_flags, |
3576 |
+ }; |
3577 |
+ |
3578 |
+ const struct inode_operations ext4_special_inode_operations = { |
3579 |
+@@ -2492,4 +2495,5 @@ const struct inode_operations ext4_speci |
3580 |
+ .removexattr = generic_removexattr, |
3581 |
+ #endif |
3582 |
+ .permission = ext4_permission, |
3583 |
++ .sync_flags = ext4_sync_flags, |
3584 |
+ }; |
3585 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext4/super.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/super.c |
3586 |
+--- linux-2.6.29.4/fs/ext4/super.c 2009-03-24 14:22:25.000000000 +0100 |
3587 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/super.c 2009-03-24 15:46:48.000000000 +0100 |
3588 |
+@@ -1013,7 +1013,8 @@ enum { |
3589 |
+ Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, |
3590 |
+ Opt_grpquota, Opt_i_version, |
3591 |
+ Opt_stripe, Opt_delalloc, Opt_nodelalloc, |
3592 |
+- Opt_inode_readahead_blks, Opt_journal_ioprio |
3593 |
++ Opt_inode_readahead_blks, Opt_journal_ioprio, |
3594 |
++ Opt_tag, Opt_notag, Opt_tagid |
3595 |
+ }; |
3596 |
+ |
3597 |
+ static const match_table_t tokens = { |
3598 |
+@@ -1073,6 +1074,9 @@ static const match_table_t tokens = { |
3599 |
+ {Opt_nodelalloc, "nodelalloc"}, |
3600 |
+ {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, |
3601 |
+ {Opt_journal_ioprio, "journal_ioprio=%u"}, |
3602 |
++ {Opt_tag, "tag"}, |
3603 |
++ {Opt_notag, "notag"}, |
3604 |
++ {Opt_tagid, "tagid=%u"}, |
3605 |
+ {Opt_err, NULL}, |
3606 |
+ }; |
3607 |
+ |
3608 |
+@@ -1168,6 +1172,20 @@ static int parse_options(char *options, |
3609 |
+ case Opt_nouid32: |
3610 |
+ set_opt(sbi->s_mount_opt, NO_UID32); |
3611 |
+ break; |
3612 |
++#ifndef CONFIG_TAGGING_NONE |
3613 |
++ case Opt_tag: |
3614 |
++ set_opt (sbi->s_mount_opt, TAGGED); |
3615 |
++ break; |
3616 |
++ case Opt_notag: |
3617 |
++ clear_opt (sbi->s_mount_opt, TAGGED); |
3618 |
++ break; |
3619 |
++#endif |
3620 |
++#ifdef CONFIG_PROPAGATE |
3621 |
++ case Opt_tagid: |
3622 |
++ /* use args[0] */ |
3623 |
++ set_opt (sbi->s_mount_opt, TAGGED); |
3624 |
++ break; |
3625 |
++#endif |
3626 |
+ case Opt_debug: |
3627 |
+ set_opt(sbi->s_mount_opt, DEBUG); |
3628 |
+ break; |
3629 |
+@@ -2113,6 +2131,9 @@ static int ext4_fill_super(struct super_ |
3630 |
+ &journal_ioprio, NULL, 0)) |
3631 |
+ goto failed_mount; |
3632 |
+ |
3633 |
++ if (EXT4_SB(sb)->s_mount_opt & EXT4_MOUNT_TAGGED) |
3634 |
++ sb->s_flags |= MS_TAGGED; |
3635 |
++ |
3636 |
+ sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
3637 |
+ ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); |
3638 |
+ |
3639 |
+@@ -3160,6 +3181,13 @@ static int ext4_remount(struct super_blo |
3640 |
+ if (sbi->s_mount_opt & EXT4_MOUNT_ABORT) |
3641 |
+ ext4_abort(sb, __func__, "Abort forced by user"); |
3642 |
+ |
3643 |
++ if ((sbi->s_mount_opt & EXT4_MOUNT_TAGGED) && |
3644 |
++ !(sb->s_flags & MS_TAGGED)) { |
3645 |
++ printk("EXT4-fs: %s: tagging not permitted on remount.\n", |
3646 |
++ sb->s_id); |
3647 |
++ return -EINVAL; |
3648 |
++ } |
3649 |
++ |
3650 |
+ sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
3651 |
+ ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); |
3652 |
+ |
3653 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext4/symlink.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/symlink.c |
3654 |
+--- linux-2.6.29.4/fs/ext4/symlink.c 2008-12-25 00:26:37.000000000 +0100 |
3655 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/symlink.c 2009-02-22 22:54:25.000000000 +0100 |
3656 |
+@@ -40,6 +40,7 @@ const struct inode_operations ext4_symli |
3657 |
+ .listxattr = ext4_listxattr, |
3658 |
+ .removexattr = generic_removexattr, |
3659 |
+ #endif |
3660 |
++ .sync_flags = ext4_sync_flags, |
3661 |
+ }; |
3662 |
+ |
3663 |
+ const struct inode_operations ext4_fast_symlink_inode_operations = { |
3664 |
+@@ -51,4 +52,5 @@ const struct inode_operations ext4_fast_ |
3665 |
+ .listxattr = ext4_listxattr, |
3666 |
+ .removexattr = generic_removexattr, |
3667 |
+ #endif |
3668 |
++ .sync_flags = ext4_sync_flags, |
3669 |
+ }; |
3670 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ext4/xattr.c linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/xattr.c |
3671 |
+--- linux-2.6.29.4/fs/ext4/xattr.c 2009-03-24 14:22:25.000000000 +0100 |
3672 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ext4/xattr.c 2009-03-24 15:47:44.000000000 +0100 |
3673 |
+@@ -56,6 +56,7 @@ |
3674 |
+ #include <linux/mbcache.h> |
3675 |
+ #include <linux/quotaops.h> |
3676 |
+ #include <linux/rwsem.h> |
3677 |
++#include <linux/vs_dlimit.h> |
3678 |
+ #include "ext4_jbd2.h" |
3679 |
+ #include "ext4.h" |
3680 |
+ #include "xattr.h" |
3681 |
+@@ -490,6 +491,7 @@ ext4_xattr_release_block(handle_t *handl |
3682 |
+ error = ext4_handle_dirty_metadata(handle, inode, bh); |
3683 |
+ if (IS_SYNC(inode)) |
3684 |
+ ext4_handle_sync(handle); |
3685 |
++ DLIMIT_FREE_BLOCK(inode, 1); |
3686 |
+ DQUOT_FREE_BLOCK(inode, 1); |
3687 |
+ ea_bdebug(bh, "refcount now=%d; releasing", |
3688 |
+ le32_to_cpu(BHDR(bh)->h_refcount)); |
3689 |
+@@ -781,11 +783,14 @@ inserted: |
3690 |
+ if (new_bh == bs->bh) |
3691 |
+ ea_bdebug(new_bh, "keeping"); |
3692 |
+ else { |
3693 |
++ error = -ENOSPC; |
3694 |
++ if (DLIMIT_ALLOC_BLOCK(inode, 1)) |
3695 |
++ goto cleanup; |
3696 |
+ /* The old block is released after updating |
3697 |
+ the inode. */ |
3698 |
+ error = -EDQUOT; |
3699 |
+ if (DQUOT_ALLOC_BLOCK(inode, 1)) |
3700 |
+- goto cleanup; |
3701 |
++ goto cleanup_dlimit; |
3702 |
+ error = ext4_journal_get_write_access(handle, |
3703 |
+ new_bh); |
3704 |
+ if (error) |
3705 |
+@@ -861,6 +866,8 @@ cleanup: |
3706 |
+ |
3707 |
+ cleanup_dquot: |
3708 |
+ DQUOT_FREE_BLOCK(inode, 1); |
3709 |
++cleanup_dlimit: |
3710 |
++ DLIMIT_FREE_BLOCK(inode, 1); |
3711 |
+ goto cleanup; |
3712 |
+ |
3713 |
+ bad_block: |
3714 |
+diff -NurpP --minimal linux-2.6.29.4/fs/fcntl.c linux-2.6.29.4-vs2.3.0.36.14/fs/fcntl.c |
3715 |
+--- linux-2.6.29.4/fs/fcntl.c 2009-05-23 23:16:52.000000000 +0200 |
3716 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/fcntl.c 2009-05-23 23:19:11.000000000 +0200 |
3717 |
+@@ -20,6 +20,7 @@ |
3718 |
+ #include <linux/rcupdate.h> |
3719 |
+ #include <linux/pid_namespace.h> |
3720 |
+ #include <linux/smp_lock.h> |
3721 |
++#include <linux/vs_limit.h> |
3722 |
+ |
3723 |
+ #include <asm/poll.h> |
3724 |
+ #include <asm/siginfo.h> |
3725 |
+@@ -103,6 +104,8 @@ SYSCALL_DEFINE3(dup3, unsigned int, oldf |
3726 |
+ |
3727 |
+ if (tofree) |
3728 |
+ filp_close(tofree, files); |
3729 |
++ else |
3730 |
++ vx_openfd_inc(newfd); /* fd was unused */ |
3731 |
+ |
3732 |
+ return newfd; |
3733 |
+ |
3734 |
+@@ -345,6 +348,8 @@ SYSCALL_DEFINE3(fcntl, unsigned int, fd, |
3735 |
+ filp = fget(fd); |
3736 |
+ if (!filp) |
3737 |
+ goto out; |
3738 |
++ if (!vx_files_avail(1)) |
3739 |
++ goto out; |
3740 |
+ |
3741 |
+ err = security_file_fcntl(filp, cmd, arg); |
3742 |
+ if (err) { |
3743 |
+diff -NurpP --minimal linux-2.6.29.4/fs/file.c linux-2.6.29.4-vs2.3.0.36.14/fs/file.c |
3744 |
+--- linux-2.6.29.4/fs/file.c 2008-12-25 00:26:37.000000000 +0100 |
3745 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/file.c 2009-02-22 22:54:25.000000000 +0100 |
3746 |
+@@ -19,6 +19,7 @@ |
3747 |
+ #include <linux/spinlock.h> |
3748 |
+ #include <linux/rcupdate.h> |
3749 |
+ #include <linux/workqueue.h> |
3750 |
++#include <linux/vs_limit.h> |
3751 |
+ |
3752 |
+ struct fdtable_defer { |
3753 |
+ spinlock_t lock; |
3754 |
+@@ -367,6 +368,8 @@ struct files_struct *dup_fd(struct files |
3755 |
+ struct file *f = *old_fds++; |
3756 |
+ if (f) { |
3757 |
+ get_file(f); |
3758 |
++ /* TODO: sum it first for check and performance */ |
3759 |
++ vx_openfd_inc(open_files - i); |
3760 |
+ } else { |
3761 |
+ /* |
3762 |
+ * The fd may be claimed in the fd bitmap but not yet |
3763 |
+@@ -475,6 +478,7 @@ repeat: |
3764 |
+ else |
3765 |
+ FD_CLR(fd, fdt->close_on_exec); |
3766 |
+ error = fd; |
3767 |
++ vx_openfd_inc(fd); |
3768 |
+ #if 1 |
3769 |
+ /* Sanity check */ |
3770 |
+ if (rcu_dereference(fdt->fd[fd]) != NULL) { |
3771 |
+diff -NurpP --minimal linux-2.6.29.4/fs/file_table.c linux-2.6.29.4-vs2.3.0.36.14/fs/file_table.c |
3772 |
+--- linux-2.6.29.4/fs/file_table.c 2009-03-24 14:22:25.000000000 +0100 |
3773 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/file_table.c 2009-03-24 14:48:35.000000000 +0100 |
3774 |
+@@ -21,6 +21,8 @@ |
3775 |
+ #include <linux/fsnotify.h> |
3776 |
+ #include <linux/sysctl.h> |
3777 |
+ #include <linux/percpu_counter.h> |
3778 |
++#include <linux/vs_limit.h> |
3779 |
++#include <linux/vs_context.h> |
3780 |
+ |
3781 |
+ #include <asm/atomic.h> |
3782 |
+ |
3783 |
+@@ -129,6 +131,8 @@ struct file *get_empty_filp(void) |
3784 |
+ f->f_cred = get_cred(cred); |
3785 |
+ eventpoll_init_file(f); |
3786 |
+ /* f->f_version: 0 */ |
3787 |
++ f->f_xid = vx_current_xid(); |
3788 |
++ vx_files_inc(f); |
3789 |
+ return f; |
3790 |
+ |
3791 |
+ over: |
3792 |
+@@ -283,6 +287,8 @@ void __fput(struct file *file) |
3793 |
+ cdev_put(inode->i_cdev); |
3794 |
+ fops_put(file->f_op); |
3795 |
+ put_pid(file->f_owner.pid); |
3796 |
++ vx_files_dec(file); |
3797 |
++ file->f_xid = 0; |
3798 |
+ file_kill(file); |
3799 |
+ if (file->f_mode & FMODE_WRITE) |
3800 |
+ drop_file_write_access(file); |
3801 |
+@@ -350,6 +356,8 @@ void put_filp(struct file *file) |
3802 |
+ { |
3803 |
+ if (atomic_long_dec_and_test(&file->f_count)) { |
3804 |
+ security_file_free(file); |
3805 |
++ vx_files_dec(file); |
3806 |
++ file->f_xid = 0; |
3807 |
+ file_kill(file); |
3808 |
+ file_free(file); |
3809 |
+ } |
3810 |
+diff -NurpP --minimal linux-2.6.29.4/fs/fs_struct.c linux-2.6.29.4-vs2.3.0.36.14/fs/fs_struct.c |
3811 |
+--- linux-2.6.29.4/fs/fs_struct.c 2009-05-23 23:16:52.000000000 +0200 |
3812 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/fs_struct.c 2009-05-20 01:29:56.000000000 +0200 |
3813 |
+@@ -3,6 +3,7 @@ |
3814 |
+ #include <linux/fs.h> |
3815 |
+ #include <linux/path.h> |
3816 |
+ #include <linux/slab.h> |
3817 |
++#include <linux/vserver/global.h> |
3818 |
+ |
3819 |
+ /* |
3820 |
+ * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. |
3821 |
+@@ -76,6 +77,7 @@ void free_fs_struct(struct fs_struct *fs |
3822 |
+ { |
3823 |
+ path_put(&fs->root); |
3824 |
+ path_put(&fs->pwd); |
3825 |
++ atomic_dec(&vs_global_fs); |
3826 |
+ kmem_cache_free(fs_cachep, fs); |
3827 |
+ } |
3828 |
+ |
3829 |
+@@ -111,6 +113,7 @@ struct fs_struct *copy_fs_struct(struct |
3830 |
+ fs->pwd = old->pwd; |
3831 |
+ path_get(&old->pwd); |
3832 |
+ read_unlock(&old->lock); |
3833 |
++ atomic_inc(&vs_global_fs); |
3834 |
+ } |
3835 |
+ return fs; |
3836 |
+ } |
3837 |
+diff -NurpP --minimal linux-2.6.29.4/fs/hfsplus/ioctl.c linux-2.6.29.4-vs2.3.0.36.14/fs/hfsplus/ioctl.c |
3838 |
+--- linux-2.6.29.4/fs/hfsplus/ioctl.c 2008-12-25 00:26:37.000000000 +0100 |
3839 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/hfsplus/ioctl.c 2009-02-22 22:54:25.000000000 +0100 |
3840 |
+@@ -17,6 +17,7 @@ |
3841 |
+ #include <linux/mount.h> |
3842 |
+ #include <linux/sched.h> |
3843 |
+ #include <linux/xattr.h> |
3844 |
++#include <linux/mount.h> |
3845 |
+ #include <asm/uaccess.h> |
3846 |
+ #include "hfsplus_fs.h" |
3847 |
+ |
3848 |
+diff -NurpP --minimal linux-2.6.29.4/fs/inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/inode.c |
3849 |
+--- linux-2.6.29.4/fs/inode.c 2009-03-24 14:22:26.000000000 +0100 |
3850 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/inode.c 2009-03-25 00:51:55.000000000 +0100 |
3851 |
+@@ -126,6 +126,9 @@ struct inode *inode_init_always(struct s |
3852 |
+ struct address_space * const mapping = &inode->i_data; |
3853 |
+ |
3854 |
+ inode->i_sb = sb; |
3855 |
++ |
3856 |
++ /* essential because of inode slab reuse */ |
3857 |
++ inode->i_tag = 0; |
3858 |
+ inode->i_blkbits = sb->s_blocksize_bits; |
3859 |
+ inode->i_flags = 0; |
3860 |
+ atomic_set(&inode->i_count, 1); |
3861 |
+@@ -146,6 +149,7 @@ struct inode *inode_init_always(struct s |
3862 |
+ inode->i_bdev = NULL; |
3863 |
+ inode->i_cdev = NULL; |
3864 |
+ inode->i_rdev = 0; |
3865 |
++ inode->i_mdev = 0; |
3866 |
+ inode->dirtied_when = 0; |
3867 |
+ if (security_inode_alloc(inode)) { |
3868 |
+ if (inode->i_sb->s_op->destroy_inode) |
3869 |
+@@ -267,6 +271,8 @@ void __iget(struct inode * inode) |
3870 |
+ inodes_stat.nr_unused--; |
3871 |
+ } |
3872 |
+ |
3873 |
++EXPORT_SYMBOL_GPL(__iget); |
3874 |
++ |
3875 |
+ /** |
3876 |
+ * clear_inode - clear an inode |
3877 |
+ * @inode: inode to clear |
3878 |
+@@ -1539,9 +1545,11 @@ void init_special_inode(struct inode *in |
3879 |
+ if (S_ISCHR(mode)) { |
3880 |
+ inode->i_fop = &def_chr_fops; |
3881 |
+ inode->i_rdev = rdev; |
3882 |
++ inode->i_mdev = rdev; |
3883 |
+ } else if (S_ISBLK(mode)) { |
3884 |
+ inode->i_fop = &def_blk_fops; |
3885 |
+ inode->i_rdev = rdev; |
3886 |
++ inode->i_mdev = rdev; |
3887 |
+ } else if (S_ISFIFO(mode)) |
3888 |
+ inode->i_fop = &def_fifo_fops; |
3889 |
+ else if (S_ISSOCK(mode)) |
3890 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ioctl.c linux-2.6.29.4-vs2.3.0.36.14/fs/ioctl.c |
3891 |
+--- linux-2.6.29.4/fs/ioctl.c 2009-05-23 23:16:52.000000000 +0200 |
3892 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ioctl.c 2009-05-23 23:19:11.000000000 +0200 |
3893 |
+@@ -15,6 +15,9 @@ |
3894 |
+ #include <linux/uaccess.h> |
3895 |
+ #include <linux/writeback.h> |
3896 |
+ #include <linux/buffer_head.h> |
3897 |
++#include <linux/proc_fs.h> |
3898 |
++#include <linux/vserver/inode.h> |
3899 |
++#include <linux/vs_tag.h> |
3900 |
+ |
3901 |
+ #include <asm/ioctls.h> |
3902 |
+ |
3903 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ioprio.c linux-2.6.29.4-vs2.3.0.36.14/fs/ioprio.c |
3904 |
+--- linux-2.6.29.4/fs/ioprio.c 2009-03-24 14:22:26.000000000 +0100 |
3905 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ioprio.c 2009-03-24 14:48:35.000000000 +0100 |
3906 |
+@@ -26,6 +26,7 @@ |
3907 |
+ #include <linux/syscalls.h> |
3908 |
+ #include <linux/security.h> |
3909 |
+ #include <linux/pid_namespace.h> |
3910 |
++#include <linux/vs_base.h> |
3911 |
+ |
3912 |
+ int set_task_ioprio(struct task_struct *task, int ioprio) |
3913 |
+ { |
3914 |
+@@ -123,6 +124,8 @@ SYSCALL_DEFINE3(ioprio_set, int, which, |
3915 |
+ else |
3916 |
+ pgrp = find_vpid(who); |
3917 |
+ do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { |
3918 |
++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT)) |
3919 |
++ continue; |
3920 |
+ ret = set_task_ioprio(p, ioprio); |
3921 |
+ if (ret) |
3922 |
+ break; |
3923 |
+@@ -212,6 +215,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which, |
3924 |
+ else |
3925 |
+ pgrp = find_vpid(who); |
3926 |
+ do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { |
3927 |
++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT)) |
3928 |
++ continue; |
3929 |
+ tmpio = get_task_ioprio(p); |
3930 |
+ if (tmpio < 0) |
3931 |
+ continue; |
3932 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/acl.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/acl.c |
3933 |
+--- linux-2.6.29.4/fs/jfs/acl.c 2008-12-25 00:26:37.000000000 +0100 |
3934 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/acl.c 2009-02-22 22:54:25.000000000 +0100 |
3935 |
+@@ -232,7 +232,8 @@ int jfs_setattr(struct dentry *dentry, s |
3936 |
+ return rc; |
3937 |
+ |
3938 |
+ if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || |
3939 |
+- (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { |
3940 |
++ (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) || |
3941 |
++ (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) { |
3942 |
+ if (DQUOT_TRANSFER(inode, iattr)) |
3943 |
+ return -EDQUOT; |
3944 |
+ } |
3945 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/file.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/file.c |
3946 |
+--- linux-2.6.29.4/fs/jfs/file.c 2008-12-25 00:26:37.000000000 +0100 |
3947 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/file.c 2009-02-22 22:54:25.000000000 +0100 |
3948 |
+@@ -98,6 +98,7 @@ const struct inode_operations jfs_file_i |
3949 |
+ .setattr = jfs_setattr, |
3950 |
+ .permission = jfs_permission, |
3951 |
+ #endif |
3952 |
++ .sync_flags = jfs_sync_flags, |
3953 |
+ }; |
3954 |
+ |
3955 |
+ const struct file_operations jfs_file_operations = { |
3956 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/inode.c |
3957 |
+--- linux-2.6.29.4/fs/jfs/inode.c 2009-03-24 14:22:26.000000000 +0100 |
3958 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/inode.c 2009-03-24 14:48:35.000000000 +0100 |
3959 |
+@@ -22,6 +22,7 @@ |
3960 |
+ #include <linux/buffer_head.h> |
3961 |
+ #include <linux/pagemap.h> |
3962 |
+ #include <linux/quotaops.h> |
3963 |
++#include <linux/vs_dlimit.h> |
3964 |
+ #include "jfs_incore.h" |
3965 |
+ #include "jfs_inode.h" |
3966 |
+ #include "jfs_filsys.h" |
3967 |
+@@ -161,6 +162,7 @@ void jfs_delete_inode(struct inode *inod |
3968 |
+ DQUOT_INIT(inode); |
3969 |
+ DQUOT_FREE_INODE(inode); |
3970 |
+ DQUOT_DROP(inode); |
3971 |
++ DLIMIT_FREE_INODE(inode); |
3972 |
+ } |
3973 |
+ |
3974 |
+ clear_inode(inode); |
3975 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/ioctl.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/ioctl.c |
3976 |
+--- linux-2.6.29.4/fs/jfs/ioctl.c 2008-12-25 00:26:37.000000000 +0100 |
3977 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/ioctl.c 2009-02-22 22:54:25.000000000 +0100 |
3978 |
+@@ -11,6 +11,7 @@ |
3979 |
+ #include <linux/mount.h> |
3980 |
+ #include <linux/time.h> |
3981 |
+ #include <linux/sched.h> |
3982 |
++#include <linux/mount.h> |
3983 |
+ #include <asm/current.h> |
3984 |
+ #include <asm/uaccess.h> |
3985 |
+ |
3986 |
+@@ -85,6 +86,11 @@ long jfs_ioctl(struct file *filp, unsign |
3987 |
+ if (!S_ISDIR(inode->i_mode)) |
3988 |
+ flags &= ~JFS_DIRSYNC_FL; |
3989 |
+ |
3990 |
++ if (IS_BARRIER(inode)) { |
3991 |
++ vxwprintk_task(1, "messing with the barrier."); |
3992 |
++ return -EACCES; |
3993 |
++ } |
3994 |
++ |
3995 |
+ /* Is it quota file? Do not allow user to mess with it */ |
3996 |
+ if (IS_NOQUOTA(inode)) { |
3997 |
+ err = -EPERM; |
3998 |
+@@ -102,8 +108,8 @@ long jfs_ioctl(struct file *filp, unsign |
3999 |
+ * the relevant capability. |
4000 |
+ */ |
4001 |
+ if ((oldflags & JFS_IMMUTABLE_FL) || |
4002 |
+- ((flags ^ oldflags) & |
4003 |
+- (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) { |
4004 |
++ ((flags ^ oldflags) & (JFS_APPEND_FL | |
4005 |
++ JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL))) { |
4006 |
+ if (!capable(CAP_LINUX_IMMUTABLE)) { |
4007 |
+ mutex_unlock(&inode->i_mutex); |
4008 |
+ err = -EPERM; |
4009 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/jfs_dinode.h linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_dinode.h |
4010 |
+--- linux-2.6.29.4/fs/jfs/jfs_dinode.h 2008-12-25 00:26:37.000000000 +0100 |
4011 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_dinode.h 2009-02-22 22:54:25.000000000 +0100 |
4012 |
+@@ -161,9 +161,13 @@ struct dinode { |
4013 |
+ |
4014 |
+ #define JFS_APPEND_FL 0x01000000 /* writes to file may only append */ |
4015 |
+ #define JFS_IMMUTABLE_FL 0x02000000 /* Immutable file */ |
4016 |
++#define JFS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */ |
4017 |
+ |
4018 |
+-#define JFS_FL_USER_VISIBLE 0x03F80000 |
4019 |
+-#define JFS_FL_USER_MODIFIABLE 0x03F80000 |
4020 |
++#define JFS_BARRIER_FL 0x04000000 /* Barrier for chroot() */ |
4021 |
++#define JFS_COW_FL 0x20000000 /* Copy on Write marker */ |
4022 |
++ |
4023 |
++#define JFS_FL_USER_VISIBLE 0x07F80000 |
4024 |
++#define JFS_FL_USER_MODIFIABLE 0x07F80000 |
4025 |
+ #define JFS_FL_INHERIT 0x03C80000 |
4026 |
+ |
4027 |
+ /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */ |
4028 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/jfs_dtree.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_dtree.c |
4029 |
+--- linux-2.6.29.4/fs/jfs/jfs_dtree.c 2008-12-25 00:26:37.000000000 +0100 |
4030 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_dtree.c 2009-02-22 22:54:25.000000000 +0100 |
4031 |
+@@ -102,6 +102,7 @@ |
4032 |
+ |
4033 |
+ #include <linux/fs.h> |
4034 |
+ #include <linux/quotaops.h> |
4035 |
++#include <linux/vs_dlimit.h> |
4036 |
+ #include "jfs_incore.h" |
4037 |
+ #include "jfs_superblock.h" |
4038 |
+ #include "jfs_filsys.h" |
4039 |
+@@ -383,10 +384,10 @@ static u32 add_index(tid_t tid, struct i |
4040 |
+ */ |
4041 |
+ if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage)) |
4042 |
+ goto clean_up; |
4043 |
+- if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) { |
4044 |
+- DQUOT_FREE_BLOCK(ip, sbi->nbperpage); |
4045 |
+- goto clean_up; |
4046 |
+- } |
4047 |
++ if (DLIMIT_ALLOC_BLOCK(ip, sbi->nbperpage)) |
4048 |
++ goto clean_up_dquot; |
4049 |
++ if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) |
4050 |
++ goto clean_up_dlimit; |
4051 |
+ |
4052 |
+ /* |
4053 |
+ * Save the table, we're going to overwrite it with the |
4054 |
+@@ -480,6 +481,12 @@ static u32 add_index(tid_t tid, struct i |
4055 |
+ |
4056 |
+ return index; |
4057 |
+ |
4058 |
++ clean_up_dlimit: |
4059 |
++ DLIMIT_FREE_BLOCK(ip, sbi->nbperpage); |
4060 |
++ |
4061 |
++ clean_up_dquot: |
4062 |
++ DQUOT_FREE_BLOCK(ip, sbi->nbperpage); |
4063 |
++ |
4064 |
+ clean_up: |
4065 |
+ |
4066 |
+ jfs_ip->next_index--; |
4067 |
+@@ -951,6 +958,7 @@ static int dtSplitUp(tid_t tid, |
4068 |
+ struct tlock *tlck; |
4069 |
+ struct lv *lv; |
4070 |
+ int quota_allocation = 0; |
4071 |
++ int dlimit_allocation = 0; |
4072 |
+ |
4073 |
+ /* get split page */ |
4074 |
+ smp = split->mp; |
4075 |
+@@ -1033,6 +1041,12 @@ static int dtSplitUp(tid_t tid, |
4076 |
+ } |
4077 |
+ quota_allocation += n; |
4078 |
+ |
4079 |
++ if (DLIMIT_ALLOC_BLOCK(ip, n)) { |
4080 |
++ rc = -ENOSPC; |
4081 |
++ goto extendOut; |
4082 |
++ } |
4083 |
++ dlimit_allocation += n; |
4084 |
++ |
4085 |
+ if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen, |
4086 |
+ (s64) n, &nxaddr))) |
4087 |
+ goto extendOut; |
4088 |
+@@ -1306,6 +1320,9 @@ static int dtSplitUp(tid_t tid, |
4089 |
+ freeKeyName: |
4090 |
+ kfree(key.name); |
4091 |
+ |
4092 |
++ /* Rollback dlimit allocation */ |
4093 |
++ if (rc && dlimit_allocation) |
4094 |
++ DLIMIT_FREE_BLOCK(ip, dlimit_allocation); |
4095 |
+ /* Rollback quota allocation */ |
4096 |
+ if (rc && quota_allocation) |
4097 |
+ DQUOT_FREE_BLOCK(ip, quota_allocation); |
4098 |
+@@ -1373,6 +1390,12 @@ static int dtSplitPage(tid_t tid, struct |
4099 |
+ release_metapage(rmp); |
4100 |
+ return -EDQUOT; |
4101 |
+ } |
4102 |
++ /* Allocate blocks to dlimit. */ |
4103 |
++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { |
4104 |
++ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd)); |
4105 |
++ release_metapage(rmp); |
4106 |
++ return -ENOSPC; |
4107 |
++ } |
4108 |
+ |
4109 |
+ jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp); |
4110 |
+ |
4111 |
+@@ -1920,6 +1943,12 @@ static int dtSplitRoot(tid_t tid, |
4112 |
+ release_metapage(rmp); |
4113 |
+ return -EDQUOT; |
4114 |
+ } |
4115 |
++ /* Allocate blocks to dlimit. */ |
4116 |
++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { |
4117 |
++ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd)); |
4118 |
++ release_metapage(rmp); |
4119 |
++ return -ENOSPC; |
4120 |
++ } |
4121 |
+ |
4122 |
+ BT_MARK_DIRTY(rmp, ip); |
4123 |
+ /* |
4124 |
+@@ -2286,6 +2315,8 @@ static int dtDeleteUp(tid_t tid, struct |
4125 |
+ |
4126 |
+ xlen = lengthPXD(&fp->header.self); |
4127 |
+ |
4128 |
++ /* Free dlimit allocation. */ |
4129 |
++ DLIMIT_FREE_BLOCK(ip, xlen); |
4130 |
+ /* Free quota allocation. */ |
4131 |
+ DQUOT_FREE_BLOCK(ip, xlen); |
4132 |
+ |
4133 |
+@@ -2362,6 +2393,8 @@ static int dtDeleteUp(tid_t tid, struct |
4134 |
+ |
4135 |
+ xlen = lengthPXD(&p->header.self); |
4136 |
+ |
4137 |
++ /* Free dlimit allocation */ |
4138 |
++ DLIMIT_FREE_BLOCK(ip, xlen); |
4139 |
+ /* Free quota allocation */ |
4140 |
+ DQUOT_FREE_BLOCK(ip, xlen); |
4141 |
+ |
4142 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/jfs_extent.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_extent.c |
4143 |
+--- linux-2.6.29.4/fs/jfs/jfs_extent.c 2008-12-25 00:26:37.000000000 +0100 |
4144 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_extent.c 2009-02-22 22:54:25.000000000 +0100 |
4145 |
+@@ -18,6 +18,7 @@ |
4146 |
+ |
4147 |
+ #include <linux/fs.h> |
4148 |
+ #include <linux/quotaops.h> |
4149 |
++#include <linux/vs_dlimit.h> |
4150 |
+ #include "jfs_incore.h" |
4151 |
+ #include "jfs_inode.h" |
4152 |
+ #include "jfs_superblock.h" |
4153 |
+@@ -147,6 +148,14 @@ extAlloc(struct inode *ip, s64 xlen, s64 |
4154 |
+ return -EDQUOT; |
4155 |
+ } |
4156 |
+ |
4157 |
++ /* Allocate blocks to dlimit. */ |
4158 |
++ if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) { |
4159 |
++ DQUOT_FREE_BLOCK(ip, nxlen); |
4160 |
++ dbFree(ip, nxaddr, (s64) nxlen); |
4161 |
++ mutex_unlock(&JFS_IP(ip)->commit_mutex); |
4162 |
++ return -ENOSPC; |
4163 |
++ } |
4164 |
++ |
4165 |
+ /* determine the value of the extent flag */ |
4166 |
+ xflag = abnr ? XAD_NOTRECORDED : 0; |
4167 |
+ |
4168 |
+@@ -164,6 +173,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 |
4169 |
+ */ |
4170 |
+ if (rc) { |
4171 |
+ dbFree(ip, nxaddr, nxlen); |
4172 |
++ DLIMIT_FREE_BLOCK(ip, nxlen); |
4173 |
+ DQUOT_FREE_BLOCK(ip, nxlen); |
4174 |
+ mutex_unlock(&JFS_IP(ip)->commit_mutex); |
4175 |
+ return (rc); |
4176 |
+@@ -261,6 +271,13 @@ int extRealloc(struct inode *ip, s64 nxl |
4177 |
+ mutex_unlock(&JFS_IP(ip)->commit_mutex); |
4178 |
+ return -EDQUOT; |
4179 |
+ } |
4180 |
++ /* Allocate blocks to dlimit. */ |
4181 |
++ if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) { |
4182 |
++ DQUOT_FREE_BLOCK(ip, nxlen); |
4183 |
++ dbFree(ip, nxaddr, (s64) nxlen); |
4184 |
++ up(&JFS_IP(ip)->commit_sem); |
4185 |
++ return -ENOSPC; |
4186 |
++ } |
4187 |
+ |
4188 |
+ delta = nxlen - xlen; |
4189 |
+ |
4190 |
+@@ -297,6 +314,7 @@ int extRealloc(struct inode *ip, s64 nxl |
4191 |
+ /* extend the extent */ |
4192 |
+ if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) { |
4193 |
+ dbFree(ip, xaddr + xlen, delta); |
4194 |
++ DLIMIT_FREE_BLOCK(ip, nxlen); |
4195 |
+ DQUOT_FREE_BLOCK(ip, nxlen); |
4196 |
+ goto exit; |
4197 |
+ } |
4198 |
+@@ -308,6 +326,7 @@ int extRealloc(struct inode *ip, s64 nxl |
4199 |
+ */ |
4200 |
+ if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) { |
4201 |
+ dbFree(ip, nxaddr, nxlen); |
4202 |
++ DLIMIT_FREE_BLOCK(ip, nxlen); |
4203 |
+ DQUOT_FREE_BLOCK(ip, nxlen); |
4204 |
+ goto exit; |
4205 |
+ } |
4206 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/jfs_filsys.h linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_filsys.h |
4207 |
+--- linux-2.6.29.4/fs/jfs/jfs_filsys.h 2008-12-25 00:26:37.000000000 +0100 |
4208 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_filsys.h 2009-02-22 22:54:25.000000000 +0100 |
4209 |
+@@ -263,6 +263,7 @@ |
4210 |
+ #define JFS_NAME_MAX 255 |
4211 |
+ #define JFS_PATH_MAX BPSIZE |
4212 |
+ |
4213 |
++#define JFS_TAGGED 0x00800000 /* Context Tagging */ |
4214 |
+ |
4215 |
+ /* |
4216 |
+ * file system state (superblock state) |
4217 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/jfs_imap.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_imap.c |
4218 |
+--- linux-2.6.29.4/fs/jfs/jfs_imap.c 2009-03-24 14:22:26.000000000 +0100 |
4219 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_imap.c 2009-03-24 14:48:35.000000000 +0100 |
4220 |
+@@ -45,6 +45,7 @@ |
4221 |
+ #include <linux/buffer_head.h> |
4222 |
+ #include <linux/pagemap.h> |
4223 |
+ #include <linux/quotaops.h> |
4224 |
++#include <linux/vs_tag.h> |
4225 |
+ |
4226 |
+ #include "jfs_incore.h" |
4227 |
+ #include "jfs_inode.h" |
4228 |
+@@ -3062,6 +3063,8 @@ static int copy_from_dinode(struct dinod |
4229 |
+ { |
4230 |
+ struct jfs_inode_info *jfs_ip = JFS_IP(ip); |
4231 |
+ struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); |
4232 |
++ uid_t uid; |
4233 |
++ gid_t gid; |
4234 |
+ |
4235 |
+ jfs_ip->fileset = le32_to_cpu(dip->di_fileset); |
4236 |
+ jfs_ip->mode2 = le32_to_cpu(dip->di_mode); |
4237 |
+@@ -3082,14 +3085,18 @@ static int copy_from_dinode(struct dinod |
4238 |
+ } |
4239 |
+ ip->i_nlink = le32_to_cpu(dip->di_nlink); |
4240 |
+ |
4241 |
+- jfs_ip->saved_uid = le32_to_cpu(dip->di_uid); |
4242 |
++ uid = le32_to_cpu(dip->di_uid); |
4243 |
++ gid = le32_to_cpu(dip->di_gid); |
4244 |
++ ip->i_tag = INOTAG_TAG(DX_TAG(ip), uid, gid, 0); |
4245 |
++ |
4246 |
++ jfs_ip->saved_uid = INOTAG_UID(DX_TAG(ip), uid, gid); |
4247 |
+ if (sbi->uid == -1) |
4248 |
+ ip->i_uid = jfs_ip->saved_uid; |
4249 |
+ else { |
4250 |
+ ip->i_uid = sbi->uid; |
4251 |
+ } |
4252 |
+ |
4253 |
+- jfs_ip->saved_gid = le32_to_cpu(dip->di_gid); |
4254 |
++ jfs_ip->saved_gid = INOTAG_GID(DX_TAG(ip), uid, gid); |
4255 |
+ if (sbi->gid == -1) |
4256 |
+ ip->i_gid = jfs_ip->saved_gid; |
4257 |
+ else { |
4258 |
+@@ -3154,14 +3161,12 @@ static void copy_to_dinode(struct dinode |
4259 |
+ dip->di_size = cpu_to_le64(ip->i_size); |
4260 |
+ dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); |
4261 |
+ dip->di_nlink = cpu_to_le32(ip->i_nlink); |
4262 |
+- if (sbi->uid == -1) |
4263 |
+- dip->di_uid = cpu_to_le32(ip->i_uid); |
4264 |
+- else |
4265 |
+- dip->di_uid = cpu_to_le32(jfs_ip->saved_uid); |
4266 |
+- if (sbi->gid == -1) |
4267 |
+- dip->di_gid = cpu_to_le32(ip->i_gid); |
4268 |
+- else |
4269 |
+- dip->di_gid = cpu_to_le32(jfs_ip->saved_gid); |
4270 |
++ |
4271 |
++ dip->di_uid = cpu_to_le32(TAGINO_UID(DX_TAG(ip), |
4272 |
++ (sbi->uid == -1) ? ip->i_uid : jfs_ip->saved_uid, ip->i_tag)); |
4273 |
++ dip->di_gid = cpu_to_le32(TAGINO_GID(DX_TAG(ip), |
4274 |
++ (sbi->gid == -1) ? ip->i_gid : jfs_ip->saved_gid, ip->i_tag)); |
4275 |
++ |
4276 |
+ jfs_get_inode_flags(jfs_ip); |
4277 |
+ /* |
4278 |
+ * mode2 is only needed for storing the higher order bits. |
4279 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/jfs_inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_inode.c |
4280 |
+--- linux-2.6.29.4/fs/jfs/jfs_inode.c 2009-03-24 14:22:26.000000000 +0100 |
4281 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_inode.c 2009-03-24 15:58:01.000000000 +0100 |
4282 |
+@@ -18,6 +18,8 @@ |
4283 |
+ |
4284 |
+ #include <linux/fs.h> |
4285 |
+ #include <linux/quotaops.h> |
4286 |
++#include <linux/vs_dlimit.h> |
4287 |
++#include <linux/vs_tag.h> |
4288 |
+ #include "jfs_incore.h" |
4289 |
+ #include "jfs_inode.h" |
4290 |
+ #include "jfs_filsys.h" |
4291 |
+@@ -30,29 +32,46 @@ void jfs_set_inode_flags(struct inode *i |
4292 |
+ { |
4293 |
+ unsigned int flags = JFS_IP(inode)->mode2; |
4294 |
+ |
4295 |
+- inode->i_flags &= ~(S_IMMUTABLE | S_APPEND | |
4296 |
+- S_NOATIME | S_DIRSYNC | S_SYNC); |
4297 |
++ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK | |
4298 |
++ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC); |
4299 |
+ |
4300 |
+ if (flags & JFS_IMMUTABLE_FL) |
4301 |
+ inode->i_flags |= S_IMMUTABLE; |
4302 |
++ if (flags & JFS_IXUNLINK_FL) |
4303 |
++ inode->i_flags |= S_IXUNLINK; |
4304 |
++ |
4305 |
++ if (flags & JFS_SYNC_FL) |
4306 |
++ inode->i_flags |= S_SYNC; |
4307 |
+ if (flags & JFS_APPEND_FL) |
4308 |
+ inode->i_flags |= S_APPEND; |
4309 |
+ if (flags & JFS_NOATIME_FL) |
4310 |
+ inode->i_flags |= S_NOATIME; |
4311 |
+ if (flags & JFS_DIRSYNC_FL) |
4312 |
+ inode->i_flags |= S_DIRSYNC; |
4313 |
+- if (flags & JFS_SYNC_FL) |
4314 |
+- inode->i_flags |= S_SYNC; |
4315 |
++ |
4316 |
++ inode->i_vflags &= ~(V_BARRIER | V_COW); |
4317 |
++ |
4318 |
++ if (flags & JFS_BARRIER_FL) |
4319 |
++ inode->i_vflags |= V_BARRIER; |
4320 |
++ if (flags & JFS_COW_FL) |
4321 |
++ inode->i_vflags |= V_COW; |
4322 |
+ } |
4323 |
+ |
4324 |
+ void jfs_get_inode_flags(struct jfs_inode_info *jfs_ip) |
4325 |
+ { |
4326 |
+ unsigned int flags = jfs_ip->vfs_inode.i_flags; |
4327 |
++ unsigned int vflags = jfs_ip->vfs_inode.i_vflags; |
4328 |
++ |
4329 |
++ jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_IXUNLINK_FL | |
4330 |
++ JFS_APPEND_FL | JFS_NOATIME_FL | |
4331 |
++ JFS_DIRSYNC_FL | JFS_SYNC_FL | |
4332 |
++ JFS_BARRIER_FL | JFS_COW_FL); |
4333 |
+ |
4334 |
+- jfs_ip->mode2 &= ~(JFS_IMMUTABLE_FL | JFS_APPEND_FL | JFS_NOATIME_FL | |
4335 |
+- JFS_DIRSYNC_FL | JFS_SYNC_FL); |
4336 |
+ if (flags & S_IMMUTABLE) |
4337 |
+ jfs_ip->mode2 |= JFS_IMMUTABLE_FL; |
4338 |
++ if (flags & S_IXUNLINK) |
4339 |
++ jfs_ip->mode2 |= JFS_IXUNLINK_FL; |
4340 |
++ |
4341 |
+ if (flags & S_APPEND) |
4342 |
+ jfs_ip->mode2 |= JFS_APPEND_FL; |
4343 |
+ if (flags & S_NOATIME) |
4344 |
+@@ -61,6 +80,19 @@ void jfs_get_inode_flags(struct jfs_inod |
4345 |
+ jfs_ip->mode2 |= JFS_DIRSYNC_FL; |
4346 |
+ if (flags & S_SYNC) |
4347 |
+ jfs_ip->mode2 |= JFS_SYNC_FL; |
4348 |
++ |
4349 |
++ if (vflags & V_BARRIER) |
4350 |
++ jfs_ip->mode2 |= JFS_BARRIER_FL; |
4351 |
++ if (vflags & V_COW) |
4352 |
++ jfs_ip->mode2 |= JFS_COW_FL; |
4353 |
++} |
4354 |
++ |
4355 |
++int jfs_sync_flags(struct inode *inode) |
4356 |
++{ |
4357 |
++ jfs_get_inode_flags(JFS_IP(inode)); |
4358 |
++ inode->i_ctime = CURRENT_TIME; |
4359 |
++ mark_inode_dirty(inode); |
4360 |
++ return 0; |
4361 |
+ } |
4362 |
+ |
4363 |
+ /* |
4364 |
+@@ -113,6 +145,12 @@ struct inode *ialloc(struct inode *paren |
4365 |
+ jfs_inode->saved_uid = inode->i_uid; |
4366 |
+ jfs_inode->saved_gid = inode->i_gid; |
4367 |
+ |
4368 |
++ inode->i_tag = dx_current_fstag(sb); |
4369 |
++ if (DLIMIT_ALLOC_INODE(inode)) { |
4370 |
++ rc = -ENOSPC; |
4371 |
++ goto fail_drop2; |
4372 |
++ } |
4373 |
++ |
4374 |
+ /* |
4375 |
+ * Allocate inode to quota. |
4376 |
+ */ |
4377 |
+@@ -162,6 +200,8 @@ struct inode *ialloc(struct inode *paren |
4378 |
+ return inode; |
4379 |
+ |
4380 |
+ fail_drop: |
4381 |
++ DLIMIT_FREE_INODE(inode); |
4382 |
++fail_drop2: |
4383 |
+ DQUOT_DROP(inode); |
4384 |
+ inode->i_flags |= S_NOQUOTA; |
4385 |
+ fail_unlock: |
4386 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/jfs_inode.h linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_inode.h |
4387 |
+--- linux-2.6.29.4/fs/jfs/jfs_inode.h 2008-12-25 00:26:37.000000000 +0100 |
4388 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_inode.h 2009-02-22 22:54:25.000000000 +0100 |
4389 |
+@@ -39,6 +39,7 @@ extern struct dentry *jfs_fh_to_dentry(s |
4390 |
+ extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid, |
4391 |
+ int fh_len, int fh_type); |
4392 |
+ extern void jfs_set_inode_flags(struct inode *); |
4393 |
++extern int jfs_sync_flags(struct inode *); |
4394 |
+ extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int); |
4395 |
+ |
4396 |
+ extern const struct address_space_operations jfs_aops; |
4397 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/jfs_xtree.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_xtree.c |
4398 |
+--- linux-2.6.29.4/fs/jfs/jfs_xtree.c 2008-12-25 00:26:37.000000000 +0100 |
4399 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/jfs_xtree.c 2009-02-22 22:54:25.000000000 +0100 |
4400 |
+@@ -23,6 +23,7 @@ |
4401 |
+ #include <linux/module.h> |
4402 |
+ #include <linux/quotaops.h> |
4403 |
+ #include <linux/seq_file.h> |
4404 |
++#include <linux/vs_dlimit.h> |
4405 |
+ #include "jfs_incore.h" |
4406 |
+ #include "jfs_filsys.h" |
4407 |
+ #include "jfs_metapage.h" |
4408 |
+@@ -848,7 +849,12 @@ int xtInsert(tid_t tid, /* transaction |
4409 |
+ hint = 0; |
4410 |
+ if ((rc = DQUOT_ALLOC_BLOCK(ip, xlen))) |
4411 |
+ goto out; |
4412 |
++ if ((rc = DLIMIT_ALLOC_BLOCK(ip, xlen))) { |
4413 |
++ DQUOT_FREE_BLOCK(ip, xlen); |
4414 |
++ goto out; |
4415 |
++ } |
4416 |
+ if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) { |
4417 |
++ DLIMIT_FREE_BLOCK(ip, xlen); |
4418 |
+ DQUOT_FREE_BLOCK(ip, xlen); |
4419 |
+ goto out; |
4420 |
+ } |
4421 |
+@@ -878,6 +884,7 @@ int xtInsert(tid_t tid, /* transaction |
4422 |
+ /* undo data extent allocation */ |
4423 |
+ if (*xaddrp == 0) { |
4424 |
+ dbFree(ip, xaddr, (s64) xlen); |
4425 |
++ DLIMIT_FREE_BLOCK(ip, xlen); |
4426 |
+ DQUOT_FREE_BLOCK(ip, xlen); |
4427 |
+ } |
4428 |
+ return rc; |
4429 |
+@@ -1234,6 +1241,7 @@ xtSplitPage(tid_t tid, struct inode *ip, |
4430 |
+ struct tlock *tlck; |
4431 |
+ struct xtlock *sxtlck = NULL, *rxtlck = NULL; |
4432 |
+ int quota_allocation = 0; |
4433 |
++ int dlimit_allocation = 0; |
4434 |
+ |
4435 |
+ smp = split->mp; |
4436 |
+ sp = XT_PAGE(ip, smp); |
4437 |
+@@ -1253,6 +1261,13 @@ xtSplitPage(tid_t tid, struct inode *ip, |
4438 |
+ |
4439 |
+ quota_allocation += lengthPXD(pxd); |
4440 |
+ |
4441 |
++ /* Allocate blocks to dlimit. */ |
4442 |
++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { |
4443 |
++ rc = -ENOSPC; |
4444 |
++ goto clean_up; |
4445 |
++ } |
4446 |
++ dlimit_allocation += lengthPXD(pxd); |
4447 |
++ |
4448 |
+ /* |
4449 |
+ * allocate the new right page for the split |
4450 |
+ */ |
4451 |
+@@ -1454,6 +1469,9 @@ xtSplitPage(tid_t tid, struct inode *ip, |
4452 |
+ |
4453 |
+ clean_up: |
4454 |
+ |
4455 |
++ /* Rollback dlimit allocation. */ |
4456 |
++ if (dlimit_allocation) |
4457 |
++ DLIMIT_FREE_BLOCK(ip, dlimit_allocation); |
4458 |
+ /* Rollback quota allocation. */ |
4459 |
+ if (quota_allocation) |
4460 |
+ DQUOT_FREE_BLOCK(ip, quota_allocation); |
4461 |
+@@ -1517,6 +1535,12 @@ xtSplitRoot(tid_t tid, |
4462 |
+ release_metapage(rmp); |
4463 |
+ return -EDQUOT; |
4464 |
+ } |
4465 |
++ /* Allocate blocks to dlimit. */ |
4466 |
++ if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) { |
4467 |
++ DQUOT_FREE_BLOCK(ip, lengthPXD(pxd)); |
4468 |
++ release_metapage(rmp); |
4469 |
++ return -ENOSPC; |
4470 |
++ } |
4471 |
+ |
4472 |
+ jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp); |
4473 |
+ |
4474 |
+@@ -3940,6 +3964,8 @@ s64 xtTruncate(tid_t tid, struct inode * |
4475 |
+ else |
4476 |
+ ip->i_size = newsize; |
4477 |
+ |
4478 |
++ /* update dlimit allocation to reflect freed blocks */ |
4479 |
++ DLIMIT_FREE_BLOCK(ip, nfreed); |
4480 |
+ /* update quota allocation to reflect freed blocks */ |
4481 |
+ DQUOT_FREE_BLOCK(ip, nfreed); |
4482 |
+ |
4483 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/namei.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/namei.c |
4484 |
+--- linux-2.6.29.4/fs/jfs/namei.c 2009-03-24 14:22:26.000000000 +0100 |
4485 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/namei.c 2009-03-24 14:48:35.000000000 +0100 |
4486 |
+@@ -21,6 +21,7 @@ |
4487 |
+ #include <linux/ctype.h> |
4488 |
+ #include <linux/quotaops.h> |
4489 |
+ #include <linux/exportfs.h> |
4490 |
++#include <linux/vs_tag.h> |
4491 |
+ #include "jfs_incore.h" |
4492 |
+ #include "jfs_superblock.h" |
4493 |
+ #include "jfs_inode.h" |
4494 |
+@@ -1476,6 +1477,7 @@ static struct dentry *jfs_lookup(struct |
4495 |
+ return ERR_CAST(ip); |
4496 |
+ } |
4497 |
+ |
4498 |
++ dx_propagate_tag(nd, ip); |
4499 |
+ dentry = d_splice_alias(ip, dentry); |
4500 |
+ |
4501 |
+ if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)) |
4502 |
+@@ -1545,6 +1547,7 @@ const struct inode_operations jfs_dir_in |
4503 |
+ .setattr = jfs_setattr, |
4504 |
+ .permission = jfs_permission, |
4505 |
+ #endif |
4506 |
++ .sync_flags = jfs_sync_flags, |
4507 |
+ }; |
4508 |
+ |
4509 |
+ const struct file_operations jfs_dir_operations = { |
4510 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/super.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/super.c |
4511 |
+--- linux-2.6.29.4/fs/jfs/super.c 2009-03-24 14:22:26.000000000 +0100 |
4512 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/super.c 2009-03-24 14:48:35.000000000 +0100 |
4513 |
+@@ -196,7 +196,8 @@ static void jfs_put_super(struct super_b |
4514 |
+ enum { |
4515 |
+ Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize, |
4516 |
+ Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota, |
4517 |
+- Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask |
4518 |
++ Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask, |
4519 |
++ Opt_tag, Opt_notag, Opt_tagid |
4520 |
+ }; |
4521 |
+ |
4522 |
+ static const match_table_t tokens = { |
4523 |
+@@ -206,6 +207,10 @@ static const match_table_t tokens = { |
4524 |
+ {Opt_resize, "resize=%u"}, |
4525 |
+ {Opt_resize_nosize, "resize"}, |
4526 |
+ {Opt_errors, "errors=%s"}, |
4527 |
++ {Opt_tag, "tag"}, |
4528 |
++ {Opt_notag, "notag"}, |
4529 |
++ {Opt_tagid, "tagid=%u"}, |
4530 |
++ {Opt_tag, "tagxid"}, |
4531 |
+ {Opt_ignore, "noquota"}, |
4532 |
+ {Opt_ignore, "quota"}, |
4533 |
+ {Opt_usrquota, "usrquota"}, |
4534 |
+@@ -340,6 +345,20 @@ static int parse_options(char *options, |
4535 |
+ } |
4536 |
+ break; |
4537 |
+ } |
4538 |
++#ifndef CONFIG_TAGGING_NONE |
4539 |
++ case Opt_tag: |
4540 |
++ *flag |= JFS_TAGGED; |
4541 |
++ break; |
4542 |
++ case Opt_notag: |
4543 |
++ *flag &= JFS_TAGGED; |
4544 |
++ break; |
4545 |
++#endif |
4546 |
++#ifdef CONFIG_PROPAGATE |
4547 |
++ case Opt_tagid: |
4548 |
++ /* use args[0] */ |
4549 |
++ *flag |= JFS_TAGGED; |
4550 |
++ break; |
4551 |
++#endif |
4552 |
+ default: |
4553 |
+ printk("jfs: Unrecognized mount option \"%s\" " |
4554 |
+ " or missing value\n", p); |
4555 |
+@@ -370,6 +389,13 @@ static int jfs_remount(struct super_bloc |
4556 |
+ if (!parse_options(data, sb, &newLVSize, &flag)) { |
4557 |
+ return -EINVAL; |
4558 |
+ } |
4559 |
++ |
4560 |
++ if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) { |
4561 |
++ printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n", |
4562 |
++ sb->s_id); |
4563 |
++ return -EINVAL; |
4564 |
++ } |
4565 |
++ |
4566 |
+ if (newLVSize) { |
4567 |
+ if (sb->s_flags & MS_RDONLY) { |
4568 |
+ printk(KERN_ERR |
4569 |
+@@ -441,6 +467,9 @@ static int jfs_fill_super(struct super_b |
4570 |
+ #ifdef CONFIG_JFS_POSIX_ACL |
4571 |
+ sb->s_flags |= MS_POSIXACL; |
4572 |
+ #endif |
4573 |
++ /* map mount option tagxid */ |
4574 |
++ if (sbi->flag & JFS_TAGGED) |
4575 |
++ sb->s_flags |= MS_TAGGED; |
4576 |
+ |
4577 |
+ if (newLVSize) { |
4578 |
+ printk(KERN_ERR "resize option for remount only\n"); |
4579 |
+diff -NurpP --minimal linux-2.6.29.4/fs/jfs/xattr.c linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/xattr.c |
4580 |
+--- linux-2.6.29.4/fs/jfs/xattr.c 2008-12-25 00:26:37.000000000 +0100 |
4581 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/jfs/xattr.c 2009-02-22 22:54:25.000000000 +0100 |
4582 |
+@@ -23,6 +23,7 @@ |
4583 |
+ #include <linux/posix_acl_xattr.h> |
4584 |
+ #include <linux/quotaops.h> |
4585 |
+ #include <linux/security.h> |
4586 |
++#include <linux/vs_dlimit.h> |
4587 |
+ #include "jfs_incore.h" |
4588 |
+ #include "jfs_superblock.h" |
4589 |
+ #include "jfs_dmap.h" |
4590 |
+@@ -263,9 +264,16 @@ static int ea_write(struct inode *ip, st |
4591 |
+ if (DQUOT_ALLOC_BLOCK(ip, nblocks)) { |
4592 |
+ return -EDQUOT; |
4593 |
+ } |
4594 |
++ /* Allocate new blocks to dlimit. */ |
4595 |
++ if (DLIMIT_ALLOC_BLOCK(ip, nblocks)) { |
4596 |
++ DQUOT_FREE_BLOCK(ip, nblocks); |
4597 |
++ return -ENOSPC; |
4598 |
++ } |
4599 |
+ |
4600 |
+ rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno); |
4601 |
+ if (rc) { |
4602 |
++ /*Rollback dlimit allocation. */ |
4603 |
++ DLIMIT_FREE_BLOCK(ip, nblocks); |
4604 |
+ /*Rollback quota allocation. */ |
4605 |
+ DQUOT_FREE_BLOCK(ip, nblocks); |
4606 |
+ return rc; |
4607 |
+@@ -332,6 +340,8 @@ static int ea_write(struct inode *ip, st |
4608 |
+ |
4609 |
+ failed: |
4610 |
+ /* Rollback quota allocation. */ |
4611 |
++ DLIMIT_FREE_BLOCK(ip, nblocks); |
4612 |
++ /* Rollback quota allocation. */ |
4613 |
+ DQUOT_FREE_BLOCK(ip, nblocks); |
4614 |
+ |
4615 |
+ dbFree(ip, blkno, nblocks); |
4616 |
+@@ -468,6 +478,7 @@ static int ea_get(struct inode *inode, s |
4617 |
+ s64 blkno; |
4618 |
+ int rc; |
4619 |
+ int quota_allocation = 0; |
4620 |
++ int dlimit_allocation = 0; |
4621 |
+ |
4622 |
+ /* When fsck.jfs clears a bad ea, it doesn't clear the size */ |
4623 |
+ if (ji->ea.flag == 0) |
4624 |
+@@ -543,6 +554,12 @@ static int ea_get(struct inode *inode, s |
4625 |
+ |
4626 |
+ quota_allocation = blocks_needed; |
4627 |
+ |
4628 |
++ /* Allocate new blocks to dlimit. */ |
4629 |
++ rc = -ENOSPC; |
4630 |
++ if (DLIMIT_ALLOC_BLOCK(inode, blocks_needed)) |
4631 |
++ goto clean_up; |
4632 |
++ dlimit_allocation = blocks_needed; |
4633 |
++ |
4634 |
+ rc = dbAlloc(inode, INOHINT(inode), (s64) blocks_needed, |
4635 |
+ &blkno); |
4636 |
+ if (rc) |
4637 |
+@@ -600,6 +617,9 @@ static int ea_get(struct inode *inode, s |
4638 |
+ return ea_size; |
4639 |
+ |
4640 |
+ clean_up: |
4641 |
++ /* Rollback dlimit allocation */ |
4642 |
++ if (dlimit_allocation) |
4643 |
++ DLIMIT_FREE_BLOCK(inode, dlimit_allocation); |
4644 |
+ /* Rollback quota allocation */ |
4645 |
+ if (quota_allocation) |
4646 |
+ DQUOT_FREE_BLOCK(inode, quota_allocation); |
4647 |
+@@ -676,8 +696,10 @@ static int ea_put(tid_t tid, struct inod |
4648 |
+ } |
4649 |
+ |
4650 |
+ /* If old blocks exist, they must be removed from quota allocation. */ |
4651 |
+- if (old_blocks) |
4652 |
++ if (old_blocks) { |
4653 |
++ DLIMIT_FREE_BLOCK(inode, old_blocks); |
4654 |
+ DQUOT_FREE_BLOCK(inode, old_blocks); |
4655 |
++ } |
4656 |
+ |
4657 |
+ inode->i_ctime = CURRENT_TIME; |
4658 |
+ |
4659 |
+diff -NurpP --minimal linux-2.6.29.4/fs/libfs.c linux-2.6.29.4-vs2.3.0.36.14/fs/libfs.c |
4660 |
+--- linux-2.6.29.4/fs/libfs.c 2009-03-24 14:22:26.000000000 +0100 |
4661 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/libfs.c 2009-03-24 14:48:35.000000000 +0100 |
4662 |
+@@ -125,7 +125,8 @@ static inline unsigned char dt_type(stru |
4663 |
+ * both impossible due to the lock on directory. |
4664 |
+ */ |
4665 |
+ |
4666 |
+-int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) |
4667 |
++static inline int do_dcache_readdir_filter(struct file *filp, |
4668 |
++ void *dirent, filldir_t filldir, int (*filter)(struct dentry *dentry)) |
4669 |
+ { |
4670 |
+ struct dentry *dentry = filp->f_path.dentry; |
4671 |
+ struct dentry *cursor = filp->private_data; |
4672 |
+@@ -158,6 +159,8 @@ int dcache_readdir(struct file * filp, v |
4673 |
+ next = list_entry(p, struct dentry, d_u.d_child); |
4674 |
+ if (d_unhashed(next) || !next->d_inode) |
4675 |
+ continue; |
4676 |
++ if (filter && !filter(next)) |
4677 |
++ continue; |
4678 |
+ |
4679 |
+ spin_unlock(&dcache_lock); |
4680 |
+ if (filldir(dirent, next->d_name.name, |
4681 |
+@@ -176,6 +179,18 @@ int dcache_readdir(struct file * filp, v |
4682 |
+ return 0; |
4683 |
+ } |
4684 |
+ |
4685 |
++int dcache_readdir(struct file *filp, void *dirent, filldir_t filldir) |
4686 |
++{ |
4687 |
++ return do_dcache_readdir_filter(filp, dirent, filldir, NULL); |
4688 |
++} |
4689 |
++ |
4690 |
++int dcache_readdir_filter(struct file *filp, void *dirent, filldir_t filldir, |
4691 |
++ int (*filter)(struct dentry *)) |
4692 |
++{ |
4693 |
++ return do_dcache_readdir_filter(filp, dirent, filldir, filter); |
4694 |
++} |
4695 |
++ |
4696 |
++ |
4697 |
+ ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos) |
4698 |
+ { |
4699 |
+ return -EISDIR; |
4700 |
+@@ -796,6 +811,7 @@ EXPORT_SYMBOL(dcache_dir_close); |
4701 |
+ EXPORT_SYMBOL(dcache_dir_lseek); |
4702 |
+ EXPORT_SYMBOL(dcache_dir_open); |
4703 |
+ EXPORT_SYMBOL(dcache_readdir); |
4704 |
++EXPORT_SYMBOL(dcache_readdir_filter); |
4705 |
+ EXPORT_SYMBOL(generic_read_dir); |
4706 |
+ EXPORT_SYMBOL(get_sb_pseudo); |
4707 |
+ EXPORT_SYMBOL(simple_write_begin); |
4708 |
+diff -NurpP --minimal linux-2.6.29.4/fs/locks.c linux-2.6.29.4-vs2.3.0.36.14/fs/locks.c |
4709 |
+--- linux-2.6.29.4/fs/locks.c 2009-03-24 14:22:26.000000000 +0100 |
4710 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/locks.c 2009-03-24 14:48:35.000000000 +0100 |
4711 |
+@@ -127,6 +127,8 @@ |
4712 |
+ #include <linux/time.h> |
4713 |
+ #include <linux/rcupdate.h> |
4714 |
+ #include <linux/pid_namespace.h> |
4715 |
++#include <linux/vs_base.h> |
4716 |
++#include <linux/vs_limit.h> |
4717 |
+ |
4718 |
+ #include <asm/uaccess.h> |
4719 |
+ |
4720 |
+@@ -148,6 +150,8 @@ static struct kmem_cache *filelock_cache |
4721 |
+ /* Allocate an empty lock structure. */ |
4722 |
+ static struct file_lock *locks_alloc_lock(void) |
4723 |
+ { |
4724 |
++ if (!vx_locks_avail(1)) |
4725 |
++ return NULL; |
4726 |
+ return kmem_cache_alloc(filelock_cache, GFP_KERNEL); |
4727 |
+ } |
4728 |
+ |
4729 |
+@@ -173,6 +177,7 @@ static void locks_free_lock(struct file_ |
4730 |
+ BUG_ON(!list_empty(&fl->fl_block)); |
4731 |
+ BUG_ON(!list_empty(&fl->fl_link)); |
4732 |
+ |
4733 |
++ vx_locks_dec(fl); |
4734 |
+ locks_release_private(fl); |
4735 |
+ kmem_cache_free(filelock_cache, fl); |
4736 |
+ } |
4737 |
+@@ -193,6 +198,7 @@ void locks_init_lock(struct file_lock *f |
4738 |
+ fl->fl_start = fl->fl_end = 0; |
4739 |
+ fl->fl_ops = NULL; |
4740 |
+ fl->fl_lmops = NULL; |
4741 |
++ fl->fl_xid = -1; |
4742 |
+ } |
4743 |
+ |
4744 |
+ EXPORT_SYMBOL(locks_init_lock); |
4745 |
+@@ -247,6 +253,7 @@ void locks_copy_lock(struct file_lock *n |
4746 |
+ new->fl_file = fl->fl_file; |
4747 |
+ new->fl_ops = fl->fl_ops; |
4748 |
+ new->fl_lmops = fl->fl_lmops; |
4749 |
++ new->fl_xid = fl->fl_xid; |
4750 |
+ |
4751 |
+ locks_copy_private(new, fl); |
4752 |
+ } |
4753 |
+@@ -285,6 +292,11 @@ static int flock_make_lock(struct file * |
4754 |
+ fl->fl_flags = FL_FLOCK; |
4755 |
+ fl->fl_type = type; |
4756 |
+ fl->fl_end = OFFSET_MAX; |
4757 |
++ |
4758 |
++ vxd_assert(filp->f_xid == vx_current_xid(), |
4759 |
++ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid()); |
4760 |
++ fl->fl_xid = filp->f_xid; |
4761 |
++ vx_locks_inc(fl); |
4762 |
+ |
4763 |
+ *lock = fl; |
4764 |
+ return 0; |
4765 |
+@@ -450,6 +462,7 @@ static int lease_init(struct file *filp, |
4766 |
+ |
4767 |
+ fl->fl_owner = current->files; |
4768 |
+ fl->fl_pid = current->tgid; |
4769 |
++ fl->fl_xid = vx_current_xid(); |
4770 |
+ |
4771 |
+ fl->fl_file = filp; |
4772 |
+ fl->fl_flags = FL_LEASE; |
4773 |
+@@ -469,6 +482,11 @@ static struct file_lock *lease_alloc(str |
4774 |
+ if (fl == NULL) |
4775 |
+ return ERR_PTR(error); |
4776 |
+ |
4777 |
++ fl->fl_xid = vx_current_xid(); |
4778 |
++ if (filp) |
4779 |
++ vxd_assert(filp->f_xid == fl->fl_xid, |
4780 |
++ "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid); |
4781 |
++ vx_locks_inc(fl); |
4782 |
+ error = lease_init(filp, type, fl); |
4783 |
+ if (error) { |
4784 |
+ locks_free_lock(fl); |
4785 |
+@@ -769,6 +787,7 @@ static int flock_lock_file(struct file * |
4786 |
+ if (found) |
4787 |
+ cond_resched_bkl(); |
4788 |
+ |
4789 |
++ new_fl->fl_xid = -1; |
4790 |
+ find_conflict: |
4791 |
+ for_each_lock(inode, before) { |
4792 |
+ struct file_lock *fl = *before; |
4793 |
+@@ -789,6 +808,7 @@ find_conflict: |
4794 |
+ goto out; |
4795 |
+ locks_copy_lock(new_fl, request); |
4796 |
+ locks_insert_lock(before, new_fl); |
4797 |
++ vx_locks_inc(new_fl); |
4798 |
+ new_fl = NULL; |
4799 |
+ error = 0; |
4800 |
+ |
4801 |
+@@ -799,7 +819,8 @@ out: |
4802 |
+ return error; |
4803 |
+ } |
4804 |
+ |
4805 |
+-static int __posix_lock_file(struct inode *inode, struct file_lock *request, struct file_lock *conflock) |
4806 |
++static int __posix_lock_file(struct inode *inode, struct file_lock *request, |
4807 |
++ struct file_lock *conflock, xid_t xid) |
4808 |
+ { |
4809 |
+ struct file_lock *fl; |
4810 |
+ struct file_lock *new_fl = NULL; |
4811 |
+@@ -809,6 +830,8 @@ static int __posix_lock_file(struct inod |
4812 |
+ struct file_lock **before; |
4813 |
+ int error, added = 0; |
4814 |
+ |
4815 |
++ vxd_assert(xid == vx_current_xid(), |
4816 |
++ "xid(%d) == current(%d)", xid, vx_current_xid()); |
4817 |
+ /* |
4818 |
+ * We may need two file_lock structures for this operation, |
4819 |
+ * so we get them in advance to avoid races. |
4820 |
+@@ -819,7 +842,11 @@ static int __posix_lock_file(struct inod |
4821 |
+ (request->fl_type != F_UNLCK || |
4822 |
+ request->fl_start != 0 || request->fl_end != OFFSET_MAX)) { |
4823 |
+ new_fl = locks_alloc_lock(); |
4824 |
++ new_fl->fl_xid = xid; |
4825 |
++ vx_locks_inc(new_fl); |
4826 |
+ new_fl2 = locks_alloc_lock(); |
4827 |
++ new_fl2->fl_xid = xid; |
4828 |
++ vx_locks_inc(new_fl2); |
4829 |
+ } |
4830 |
+ |
4831 |
+ lock_kernel(); |
4832 |
+@@ -1018,7 +1045,8 @@ static int __posix_lock_file(struct inod |
4833 |
+ int posix_lock_file(struct file *filp, struct file_lock *fl, |
4834 |
+ struct file_lock *conflock) |
4835 |
+ { |
4836 |
+- return __posix_lock_file(filp->f_path.dentry->d_inode, fl, conflock); |
4837 |
++ return __posix_lock_file(filp->f_path.dentry->d_inode, |
4838 |
++ fl, conflock, filp->f_xid); |
4839 |
+ } |
4840 |
+ EXPORT_SYMBOL(posix_lock_file); |
4841 |
+ |
4842 |
+@@ -1108,7 +1136,7 @@ int locks_mandatory_area(int read_write, |
4843 |
+ fl.fl_end = offset + count - 1; |
4844 |
+ |
4845 |
+ for (;;) { |
4846 |
+- error = __posix_lock_file(inode, &fl, NULL); |
4847 |
++ error = __posix_lock_file(inode, &fl, NULL, filp->f_xid); |
4848 |
+ if (error != FILE_LOCK_DEFERRED) |
4849 |
+ break; |
4850 |
+ error = wait_event_interruptible(fl.fl_wait, !fl.fl_next); |
4851 |
+@@ -1423,6 +1451,7 @@ int generic_setlease(struct file *filp, |
4852 |
+ |
4853 |
+ locks_copy_lock(new_fl, lease); |
4854 |
+ locks_insert_lock(before, new_fl); |
4855 |
++ vx_locks_inc(new_fl); |
4856 |
+ |
4857 |
+ *flp = new_fl; |
4858 |
+ return 0; |
4859 |
+@@ -1778,6 +1807,11 @@ int fcntl_setlk(unsigned int fd, struct |
4860 |
+ if (file_lock == NULL) |
4861 |
+ return -ENOLCK; |
4862 |
+ |
4863 |
++ vxd_assert(filp->f_xid == vx_current_xid(), |
4864 |
++ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid()); |
4865 |
++ file_lock->fl_xid = filp->f_xid; |
4866 |
++ vx_locks_inc(file_lock); |
4867 |
++ |
4868 |
+ /* |
4869 |
+ * This might block, so we do it before checking the inode. |
4870 |
+ */ |
4871 |
+@@ -1896,6 +1930,11 @@ int fcntl_setlk64(unsigned int fd, struc |
4872 |
+ if (file_lock == NULL) |
4873 |
+ return -ENOLCK; |
4874 |
+ |
4875 |
++ vxd_assert(filp->f_xid == vx_current_xid(), |
4876 |
++ "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid()); |
4877 |
++ file_lock->fl_xid = filp->f_xid; |
4878 |
++ vx_locks_inc(file_lock); |
4879 |
++ |
4880 |
+ /* |
4881 |
+ * This might block, so we do it before checking the inode. |
4882 |
+ */ |
4883 |
+@@ -2161,8 +2200,11 @@ static int locks_show(struct seq_file *f |
4884 |
+ |
4885 |
+ lock_get_status(f, fl, (long)f->private, ""); |
4886 |
+ |
4887 |
+- list_for_each_entry(bfl, &fl->fl_block, fl_block) |
4888 |
++ list_for_each_entry(bfl, &fl->fl_block, fl_block) { |
4889 |
++ if (!vx_check(fl->fl_xid, VS_WATCH_P | VS_IDENT)) |
4890 |
++ continue; |
4891 |
+ lock_get_status(f, bfl, (long)f->private, " ->"); |
4892 |
++ } |
4893 |
+ |
4894 |
+ f->private++; |
4895 |
+ return 0; |
4896 |
+diff -NurpP --minimal linux-2.6.29.4/fs/namei.c linux-2.6.29.4-vs2.3.0.36.14/fs/namei.c |
4897 |
+--- linux-2.6.29.4/fs/namei.c 2009-05-23 23:16:52.000000000 +0200 |
4898 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/namei.c 2009-05-23 22:57:27.000000000 +0200 |
4899 |
+@@ -31,6 +31,14 @@ |
4900 |
+ #include <linux/file.h> |
4901 |
+ #include <linux/fcntl.h> |
4902 |
+ #include <linux/device_cgroup.h> |
4903 |
++#include <linux/proc_fs.h> |
4904 |
++#include <linux/vserver/inode.h> |
4905 |
++#include <linux/vs_base.h> |
4906 |
++#include <linux/vs_tag.h> |
4907 |
++#include <linux/vs_cowbl.h> |
4908 |
++#include <linux/vs_device.h> |
4909 |
++#include <linux/vs_context.h> |
4910 |
++#include <linux/pid_namespace.h> |
4911 |
+ #include <asm/uaccess.h> |
4912 |
+ |
4913 |
+ #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) |
4914 |
+@@ -167,6 +175,77 @@ void putname(const char *name) |
4915 |
+ EXPORT_SYMBOL(putname); |
4916 |
+ #endif |
4917 |
+ |
4918 |
++static inline int dx_barrier(struct inode *inode) |
4919 |
++{ |
4920 |
++ if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN | VS_WATCH)) { |
4921 |
++ vxwprintk_task(1, "did hit the barrier."); |
4922 |
++ return 1; |
4923 |
++ } |
4924 |
++ return 0; |
4925 |
++} |
4926 |
++ |
4927 |
++static int __dx_permission(struct inode *inode, int mask) |
4928 |
++{ |
4929 |
++ if (dx_barrier(inode)) |
4930 |
++ return -EACCES; |
4931 |
++ |
4932 |
++ if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) { |
4933 |
++ /* devpts is xid tagged */ |
4934 |
++ if (S_ISDIR(inode->i_mode) || |
4935 |
++ vx_check((xid_t)inode->i_tag, VS_IDENT | VS_WATCH_P)) |
4936 |
++ return 0; |
4937 |
++ } |
4938 |
++ else if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) { |
4939 |
++ struct proc_dir_entry *de = PDE(inode); |
4940 |
++ |
4941 |
++ if (de && !vx_hide_check(0, de->vx_flags)) |
4942 |
++ goto out; |
4943 |
++ |
4944 |
++ if ((mask & (MAY_WRITE | MAY_APPEND))) { |
4945 |
++ struct pid *pid; |
4946 |
++ struct task_struct *tsk; |
4947 |
++ |
4948 |
++ if (vx_check(0, VS_ADMIN | VS_WATCH_P) || |
4949 |
++ vx_flags(VXF_STATE_SETUP, 0)) |
4950 |
++ return 0; |
4951 |
++ |
4952 |
++ pid = PROC_I(inode)->pid; |
4953 |
++ if (!pid) |
4954 |
++ goto out; |
4955 |
++ |
4956 |
++ tsk = pid_task(pid, PIDTYPE_PID); |
4957 |
++ vxdprintk(VXD_CBIT(tag, 0), "accessing %p[#%u]", |
4958 |
++ tsk, (tsk ? vx_task_xid(tsk) : 0)); |
4959 |
++ if (tsk && vx_check(vx_task_xid(tsk), VS_IDENT | VS_WATCH_P)) |
4960 |
++ return 0; |
4961 |
++ } |
4962 |
++ else { |
4963 |
++ /* FIXME: Should we block some entries here? */ |
4964 |
++ return 0; |
4965 |
++ } |
4966 |
++ } |
4967 |
++ else { |
4968 |
++ if (dx_notagcheck(inode->i_sb) || |
4969 |
++ dx_check(inode->i_tag, DX_HOSTID | DX_ADMIN | DX_WATCH | |
4970 |
++ DX_IDENT)) |
4971 |
++ return 0; |
4972 |
++ } |
4973 |
++ |
4974 |
++out: |
4975 |
++ return -EACCES; |
4976 |
++} |
4977 |
++ |
4978 |
++int dx_permission(struct inode *inode, int mask) |
4979 |
++{ |
4980 |
++ int ret = __dx_permission(inode, mask); |
4981 |
++ if (unlikely(ret)) { |
4982 |
++ vxwprintk_task(1, "denied %x access to %s:%p[#%d,%lu]", |
4983 |
++ mask, inode->i_sb->s_id, inode, inode->i_tag, |
4984 |
++ inode->i_ino); |
4985 |
++ } |
4986 |
++ return ret; |
4987 |
++} |
4988 |
++ |
4989 |
+ |
4990 |
+ /** |
4991 |
+ * generic_permission - check for access rights on a Posix-like filesystem |
4992 |
+@@ -253,10 +332,14 @@ int inode_permission(struct inode *inode |
4993 |
+ /* |
4994 |
+ * Nobody gets write access to an immutable file. |
4995 |
+ */ |
4996 |
+- if (IS_IMMUTABLE(inode)) |
4997 |
++ if (IS_IMMUTABLE(inode) && !IS_COW(inode)) |
4998 |
+ return -EACCES; |
4999 |
+ } |
5000 |
+ |
5001 |
++ retval = dx_permission(inode, mask); |
5002 |
++ if (retval) |
5003 |
++ return retval; |
5004 |
++ |
5005 |
+ if (inode->i_op->permission) |
5006 |
+ retval = inode->i_op->permission(inode, mask); |
5007 |
+ else |
5008 |
+@@ -432,6 +515,8 @@ static int exec_permission_lite(struct i |
5009 |
+ { |
5010 |
+ umode_t mode = inode->i_mode; |
5011 |
+ |
5012 |
++ if (dx_barrier(inode)) |
5013 |
++ return -EACCES; |
5014 |
+ if (inode->i_op->permission) |
5015 |
+ return -EAGAIN; |
5016 |
+ |
5017 |
+@@ -749,7 +834,8 @@ static __always_inline void follow_dotdo |
5018 |
+ if (nd->path.dentry == fs->root.dentry && |
5019 |
+ nd->path.mnt == fs->root.mnt) { |
5020 |
+ read_unlock(&fs->lock); |
5021 |
+- break; |
5022 |
++ /* for sane '/' avoid follow_mount() */ |
5023 |
++ return; |
5024 |
+ } |
5025 |
+ read_unlock(&fs->lock); |
5026 |
+ spin_lock(&dcache_lock); |
5027 |
+@@ -786,16 +872,30 @@ static int do_lookup(struct nameidata *n |
5028 |
+ { |
5029 |
+ struct vfsmount *mnt = nd->path.mnt; |
5030 |
+ struct dentry *dentry = __d_lookup(nd->path.dentry, name); |
5031 |
++ struct inode *inode; |
5032 |
+ |
5033 |
+ if (!dentry) |
5034 |
+ goto need_lookup; |
5035 |
+ if (dentry->d_op && dentry->d_op->d_revalidate) |
5036 |
+ goto need_revalidate; |
5037 |
++ inode = dentry->d_inode; |
5038 |
++ if (!inode) |
5039 |
++ goto done; |
5040 |
++ |
5041 |
++ if (__dx_permission(inode, MAY_ACCESS)) |
5042 |
++ goto hidden; |
5043 |
++ |
5044 |
+ done: |
5045 |
+ path->mnt = mnt; |
5046 |
+ path->dentry = dentry; |
5047 |
+ __follow_mount(path); |
5048 |
+ return 0; |
5049 |
++hidden: |
5050 |
++ vxwprintk_task(1, "did lookup hidden %s:%p[#%d,%lu] »%s/%.*s«.", |
5051 |
++ inode->i_sb->s_id, inode, inode->i_tag, inode->i_ino, |
5052 |
++ vxd_path(&nd->path), name->len, name->name); |
5053 |
++ dput(dentry); |
5054 |
++ return -ENOENT; |
5055 |
+ |
5056 |
+ need_lookup: |
5057 |
+ dentry = real_lookup(nd->path.dentry, name, nd); |
5058 |
+@@ -1364,7 +1464,7 @@ static int may_delete(struct inode *dir, |
5059 |
+ if (IS_APPEND(dir)) |
5060 |
+ return -EPERM; |
5061 |
+ if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)|| |
5062 |
+- IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode)) |
5063 |
++ IS_IXORUNLINK(victim->d_inode) || IS_SWAPFILE(victim->d_inode)) |
5064 |
+ return -EPERM; |
5065 |
+ if (isdir) { |
5066 |
+ if (!S_ISDIR(victim->d_inode->i_mode)) |
5067 |
+@@ -1506,6 +1606,14 @@ int may_open(struct path *path, int acc_ |
5068 |
+ flag &= ~O_TRUNC; |
5069 |
+ } |
5070 |
+ |
5071 |
++#ifdef CONFIG_VSERVER_COWBL |
5072 |
++ if (IS_COW(inode) && (flag & FMODE_WRITE)) { |
5073 |
++ if (IS_COW_LINK(inode)) |
5074 |
++ return -EMLINK; |
5075 |
++ inode->i_flags &= ~(S_IXUNLINK|S_IMMUTABLE); |
5076 |
++ mark_inode_dirty(inode); |
5077 |
++ } |
5078 |
++#endif |
5079 |
+ error = inode_permission(inode, acc_mode); |
5080 |
+ if (error) |
5081 |
+ return error; |
5082 |
+@@ -1639,6 +1747,11 @@ struct file *do_filp_open(int dfd, const |
5083 |
+ int will_write; |
5084 |
+ int flag = open_to_namei_flags(open_flag); |
5085 |
+ |
5086 |
++#ifdef CONFIG_VSERVER_COWBL |
5087 |
++ int rflag = flag; |
5088 |
++ int rmode = mode; |
5089 |
++restart: |
5090 |
++#endif |
5091 |
+ acc_mode = MAY_OPEN | ACC_MODE(flag); |
5092 |
+ |
5093 |
+ /* O_TRUNC implies we need access checks for write permissions */ |
5094 |
+@@ -1771,6 +1884,25 @@ ok: |
5095 |
+ goto exit; |
5096 |
+ } |
5097 |
+ error = may_open(&nd.path, acc_mode, flag); |
5098 |
++#ifdef CONFIG_VSERVER_COWBL |
5099 |
++ if (error == -EMLINK) { |
5100 |
++ struct dentry *dentry; |
5101 |
++ dentry = cow_break_link(pathname); |
5102 |
++ if (IS_ERR(dentry)) { |
5103 |
++ error = PTR_ERR(dentry); |
5104 |
++ goto exit_cow; |
5105 |
++ } |
5106 |
++ dput(dentry); |
5107 |
++ if (will_write) |
5108 |
++ mnt_drop_write(nd.path.mnt); |
5109 |
++ release_open_intent(&nd); |
5110 |
++ path_put(&nd.path); |
5111 |
++ flag = rflag; |
5112 |
++ mode = rmode; |
5113 |
++ goto restart; |
5114 |
++ } |
5115 |
++exit_cow: |
5116 |
++#endif |
5117 |
+ if (error) { |
5118 |
+ if (will_write) |
5119 |
+ mnt_drop_write(nd.path.mnt); |
5120 |
+@@ -1924,9 +2056,17 @@ int vfs_mknod(struct inode *dir, struct |
5121 |
+ if (error) |
5122 |
+ return error; |
5123 |
+ |
5124 |
+- if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD)) |
5125 |
++ if (!(S_ISCHR(mode) || S_ISBLK(mode))) |
5126 |
++ goto okay; |
5127 |
++ |
5128 |
++ if (!capable(CAP_MKNOD)) |
5129 |
+ return -EPERM; |
5130 |
+ |
5131 |
++ if (S_ISCHR(mode) && !vs_chrdev_perm(dev, DATTR_CREATE)) |
5132 |
++ return -EPERM; |
5133 |
++ if (S_ISBLK(mode) && !vs_blkdev_perm(dev, DATTR_CREATE)) |
5134 |
++ return -EPERM; |
5135 |
++okay: |
5136 |
+ if (!dir->i_op->mknod) |
5137 |
+ return -EPERM; |
5138 |
+ |
5139 |
+@@ -2393,7 +2533,7 @@ int vfs_link(struct dentry *old_dentry, |
5140 |
+ /* |
5141 |
+ * A link to an append-only or immutable file cannot be created. |
5142 |
+ */ |
5143 |
+- if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
5144 |
++ if (IS_APPEND(inode) || IS_IXORUNLINK(inode)) |
5145 |
+ return -EPERM; |
5146 |
+ if (!dir->i_op->link) |
5147 |
+ return -EPERM; |
5148 |
+@@ -2766,6 +2906,219 @@ int vfs_follow_link(struct nameidata *nd |
5149 |
+ return __vfs_follow_link(nd, link); |
5150 |
+ } |
5151 |
+ |
5152 |
++ |
5153 |
++#ifdef CONFIG_VSERVER_COWBL |
5154 |
++ |
5155 |
++#include <linux/file.h> |
5156 |
++ |
5157 |
++static inline |
5158 |
++long do_cow_splice(struct file *in, struct file *out, size_t len) |
5159 |
++{ |
5160 |
++ loff_t ppos = 0; |
5161 |
++ |
5162 |
++ return do_splice_direct(in, &ppos, out, len, 0); |
5163 |
++} |
5164 |
++ |
5165 |
++struct dentry *cow_break_link(const char *pathname) |
5166 |
++{ |
5167 |
++ int ret, mode, pathlen, redo = 0; |
5168 |
++ struct nameidata old_nd, dir_nd; |
5169 |
++ struct path old_path, new_path; |
5170 |
++ struct dentry *dir, *res = NULL; |
5171 |
++ struct file *old_file; |
5172 |
++ struct file *new_file; |
5173 |
++ char *to, *path, pad='\251'; |
5174 |
++ loff_t size; |
5175 |
++ |
5176 |
++ vxdprintk(VXD_CBIT(misc, 1), "cow_break_link(»%s«)", pathname); |
5177 |
++ path = kmalloc(PATH_MAX, GFP_KERNEL); |
5178 |
++ ret = -ENOMEM; |
5179 |
++ if (!path) |
5180 |
++ goto out; |
5181 |
++ |
5182 |
++ /* old_nd will have refs to dentry and mnt */ |
5183 |
++ ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd); |
5184 |
++ vxdprintk(VXD_CBIT(misc, 2), "path_lookup(old): %d", ret); |
5185 |
++ if (ret < 0) |
5186 |
++ goto out_free_path; |
5187 |
++ |
5188 |
++ old_path = old_nd.path; |
5189 |
++ mode = old_path.dentry->d_inode->i_mode; |
5190 |
++ |
5191 |
++ to = d_path(&old_path, path, PATH_MAX-2); |
5192 |
++ pathlen = strlen(to); |
5193 |
++ vxdprintk(VXD_CBIT(misc, 2), "old path »%s« [»%.*s«:%d]", to, |
5194 |
++ old_path.dentry->d_name.len, old_path.dentry->d_name.name, |
5195 |
++ old_path.dentry->d_name.len); |
5196 |
++ |
5197 |
++ to[pathlen + 1] = 0; |
5198 |
++retry: |
5199 |
++ to[pathlen] = pad--; |
5200 |
++ ret = -EMLINK; |
5201 |
++ if (pad <= '\240') |
5202 |
++ goto out_rel_old; |
5203 |
++ |
5204 |
++ vxdprintk(VXD_CBIT(misc, 1), "temp copy »%s«", to); |
5205 |
++ /* dir_nd will have refs to dentry and mnt */ |
5206 |
++ ret = path_lookup(to, |
5207 |
++ LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE, &dir_nd); |
5208 |
++ vxdprintk(VXD_CBIT(misc, 2), |
5209 |
++ "path_lookup(new): %d", ret); |
5210 |
++ if (ret < 0) |
5211 |
++ goto retry; |
5212 |
++ |
5213 |
++ /* this puppy downs the inode mutex */ |
5214 |
++ new_path.dentry = lookup_create(&dir_nd, 0); |
5215 |
++ if (!new_path.dentry || IS_ERR(new_path.dentry)) { |
5216 |
++ vxdprintk(VXD_CBIT(misc, 2), |
5217 |
++ "lookup_create(new): %p", new_path.dentry); |
5218 |
++ mutex_unlock(&dir_nd.path.dentry->d_inode->i_mutex); |
5219 |
++ path_put(&dir_nd.path); |
5220 |
++ goto retry; |
5221 |
++ } |
5222 |
++ vxdprintk(VXD_CBIT(misc, 2), |
5223 |
++ "lookup_create(new): %p [»%.*s«:%d]", new_path.dentry, |
5224 |
++ new_path.dentry->d_name.len, new_path.dentry->d_name.name, |
5225 |
++ new_path.dentry->d_name.len); |
5226 |
++ dir = dir_nd.path.dentry; |
5227 |
++ |
5228 |
++ ret = vfs_create(dir_nd.path.dentry->d_inode, new_path.dentry, mode, &dir_nd); |
5229 |
++ vxdprintk(VXD_CBIT(misc, 2), |
5230 |
++ "vfs_create(new): %d", ret); |
5231 |
++ if (ret == -EEXIST) { |
5232 |
++ mutex_unlock(&dir->d_inode->i_mutex); |
5233 |
++ dput(new_path.dentry); |
5234 |
++ path_put(&dir_nd.path); |
5235 |
++ goto retry; |
5236 |
++ } |
5237 |
++ else if (ret < 0) |
5238 |
++ goto out_unlock_new; |
5239 |
++ |
5240 |
++ /* drop out early, ret passes ENOENT */ |
5241 |
++ ret = -ENOENT; |
5242 |
++ if ((redo = d_unhashed(old_path.dentry))) |
5243 |
++ goto out_unlock_new; |
5244 |
++ |
5245 |
++ new_path.mnt = dir_nd.path.mnt; |
5246 |
++ dget(old_path.dentry); |
5247 |
++ mntget(old_path.mnt); |
5248 |
++ /* this one cleans up the dentry/mnt in case of failure */ |
5249 |
++ old_file = dentry_open(old_path.dentry, old_path.mnt, |
5250 |
++ O_RDONLY, current_cred()); |
5251 |
++ vxdprintk(VXD_CBIT(misc, 2), |
5252 |
++ "dentry_open(old): %p", old_file); |
5253 |
++ if (!old_file || IS_ERR(old_file)) { |
5254 |
++ res = IS_ERR(old_file) ? (void *) old_file : res; |
5255 |
++ goto out_unlock_new; |
5256 |
++ } |
5257 |
++ |
5258 |
++ dget(new_path.dentry); |
5259 |
++ mntget(new_path.mnt); |
5260 |
++ /* this one cleans up the dentry/mnt in case of failure */ |
5261 |
++ new_file = dentry_open(new_path.dentry, new_path.mnt, |
5262 |
++ O_WRONLY, current_cred()); |
5263 |
++ vxdprintk(VXD_CBIT(misc, 2), |
5264 |
++ "dentry_open(new): %p", new_file); |
5265 |
++ |
5266 |
++ ret = IS_ERR(new_file) ? PTR_ERR(new_file) : -ENOENT; |
5267 |
++ if (!new_file || IS_ERR(new_file)) |
5268 |
++ goto out_fput_old; |
5269 |
++ |
5270 |
++ size = i_size_read(old_file->f_dentry->d_inode); |
5271 |
++ ret = do_cow_splice(old_file, new_file, size); |
5272 |
++ vxdprintk(VXD_CBIT(misc, 2), "do_splice_direct: %d", ret); |
5273 |
++ if (ret < 0) { |
5274 |
++ goto out_fput_both; |
5275 |
++ } else if (ret < size) { |
5276 |
++ ret = -ENOSPC; |
5277 |
++ goto out_fput_both; |
5278 |
++ } else { |
5279 |
++ struct inode *old_inode = old_path.dentry->d_inode; |
5280 |
++ struct inode *new_inode = new_path.dentry->d_inode; |
5281 |
++ struct iattr attr = { |
5282 |
++ .ia_uid = old_inode->i_uid, |
5283 |
++ .ia_gid = old_inode->i_gid, |
5284 |
++ .ia_valid = ATTR_UID | ATTR_GID |
5285 |
++ }; |
5286 |
++ |
5287 |
++ ret = inode_setattr(new_inode, &attr); |
5288 |
++ if (ret) |
5289 |
++ goto out_fput_both; |
5290 |
++ } |
5291 |
++ |
5292 |
++ mutex_lock(&old_path.dentry->d_inode->i_sb->s_vfs_rename_mutex); |
5293 |
++ |
5294 |
++ /* drop out late */ |
5295 |
++ ret = -ENOENT; |
5296 |
++ if ((redo = d_unhashed(old_path.dentry))) |
5297 |
++ goto out_unlock; |
5298 |
++ |
5299 |
++ vxdprintk(VXD_CBIT(misc, 2), |
5300 |
++ "vfs_rename: [»%*s«:%d] -> [»%*s«:%d]", |
5301 |
++ new_path.dentry->d_name.len, new_path.dentry->d_name.name, |
5302 |
++ new_path.dentry->d_name.len, |
5303 |
++ old_path.dentry->d_name.len, old_path.dentry->d_name.name, |
5304 |
++ old_path.dentry->d_name.len); |
5305 |
++ ret = vfs_rename(dir_nd.path.dentry->d_inode, new_path.dentry, |
5306 |
++ old_nd.path.dentry->d_parent->d_inode, old_path.dentry); |
5307 |
++ vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret); |
5308 |
++ res = new_path.dentry; |
5309 |
++ |
5310 |
++out_unlock: |
5311 |
++ mutex_unlock(&old_path.dentry->d_inode->i_sb->s_vfs_rename_mutex); |
5312 |
++ |
5313 |
++out_fput_both: |
5314 |
++ vxdprintk(VXD_CBIT(misc, 3), |
5315 |
++ "fput(new_file=%p[#%ld])", new_file, |
5316 |
++ atomic_read(&new_file->f_count)); |
5317 |
++ fput(new_file); |
5318 |
++ |
5319 |
++out_fput_old: |
5320 |
++ vxdprintk(VXD_CBIT(misc, 3), |
5321 |
++ "fput(old_file=%p[#%ld])", old_file, |
5322 |
++ atomic_read(&old_file->f_count)); |
5323 |
++ fput(old_file); |
5324 |
++ |
5325 |
++out_unlock_new: |
5326 |
++ mutex_unlock(&dir->d_inode->i_mutex); |
5327 |
++ if (!ret) |
5328 |
++ goto out_redo; |
5329 |
++ |
5330 |
++ /* error path cleanup */ |
5331 |
++ vfs_unlink(dir->d_inode, new_path.dentry); |
5332 |
++ dput(new_path.dentry); |
5333 |
++ |
5334 |
++out_redo: |
5335 |
++ if (!redo) |
5336 |
++ goto out_rel_both; |
5337 |
++ /* lookup dentry once again */ |
5338 |
++ path_put(&old_nd.path); |
5339 |
++ ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd); |
5340 |
++ if (ret) |
5341 |
++ goto out_rel_both; |
5342 |
++ |
5343 |
++ new_path.dentry = old_nd.path.dentry; |
5344 |
++ vxdprintk(VXD_CBIT(misc, 2), |
5345 |
++ "path_lookup(redo): %p [»%.*s«:%d]", new_path.dentry, |
5346 |
++ new_path.dentry->d_name.len, new_path.dentry->d_name.name, |
5347 |
++ new_path.dentry->d_name.len); |
5348 |
++ dget(new_path.dentry); |
5349 |
++ res = new_path.dentry; |
5350 |
++ |
5351 |
++out_rel_both: |
5352 |
++ path_put(&dir_nd.path); |
5353 |
++out_rel_old: |
5354 |
++ path_put(&old_nd.path); |
5355 |
++out_free_path: |
5356 |
++ kfree(path); |
5357 |
++out: |
5358 |
++ if (ret) |
5359 |
++ res = ERR_PTR(ret); |
5360 |
++ return res; |
5361 |
++} |
5362 |
++ |
5363 |
++#endif |
5364 |
++ |
5365 |
+ /* get the link contents into pagecache */ |
5366 |
+ static char *page_getlink(struct dentry * dentry, struct page **ppage) |
5367 |
+ { |
5368 |
+diff -NurpP --minimal linux-2.6.29.4/fs/namespace.c linux-2.6.29.4-vs2.3.0.36.14/fs/namespace.c |
5369 |
+--- linux-2.6.29.4/fs/namespace.c 2009-05-23 23:16:52.000000000 +0200 |
5370 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/namespace.c 2009-05-10 23:42:01.000000000 +0200 |
5371 |
+@@ -27,6 +27,11 @@ |
5372 |
+ #include <linux/ramfs.h> |
5373 |
+ #include <linux/log2.h> |
5374 |
+ #include <linux/idr.h> |
5375 |
++#include <linux/vs_base.h> |
5376 |
++#include <linux/vs_context.h> |
5377 |
++#include <linux/vs_tag.h> |
5378 |
++#include <linux/vserver/space.h> |
5379 |
++#include <linux/vserver/global.h> |
5380 |
+ #include <asm/uaccess.h> |
5381 |
+ #include <asm/unistd.h> |
5382 |
+ #include "pnode.h" |
5383 |
+@@ -573,6 +578,7 @@ static struct vfsmount *clone_mnt(struct |
5384 |
+ mnt->mnt_root = dget(root); |
5385 |
+ mnt->mnt_mountpoint = mnt->mnt_root; |
5386 |
+ mnt->mnt_parent = mnt; |
5387 |
++ mnt->mnt_tag = old->mnt_tag; |
5388 |
+ |
5389 |
+ if (flag & CL_SLAVE) { |
5390 |
+ list_add(&mnt->mnt_slave, &old->mnt_slave_list); |
5391 |
+@@ -687,6 +693,31 @@ static inline void mangle(struct seq_fil |
5392 |
+ seq_escape(m, s, " \t\n\\"); |
5393 |
+ } |
5394 |
+ |
5395 |
++static int mnt_is_reachable(struct vfsmount *mnt) |
5396 |
++{ |
5397 |
++ struct path root; |
5398 |
++ struct dentry *point; |
5399 |
++ int ret; |
5400 |
++ |
5401 |
++ if (mnt == mnt->mnt_ns->root) |
5402 |
++ return 1; |
5403 |
++ |
5404 |
++ spin_lock(&vfsmount_lock); |
5405 |
++ root = current->fs->root; |
5406 |
++ point = root.dentry; |
5407 |
++ |
5408 |
++ while ((mnt != mnt->mnt_parent) && (mnt != root.mnt)) { |
5409 |
++ point = mnt->mnt_mountpoint; |
5410 |
++ mnt = mnt->mnt_parent; |
5411 |
++ } |
5412 |
++ |
5413 |
++ ret = (mnt == root.mnt) && is_subdir(point, root.dentry); |
5414 |
++ |
5415 |
++ spin_unlock(&vfsmount_lock); |
5416 |
++ |
5417 |
++ return ret; |
5418 |
++} |
5419 |
++ |
5420 |
+ /* |
5421 |
+ * Simple .show_options callback for filesystems which don't want to |
5422 |
+ * implement more complex mount option showing. |
5423 |
+@@ -759,6 +790,8 @@ static int show_sb_opts(struct seq_file |
5424 |
+ { MS_SYNCHRONOUS, ",sync" }, |
5425 |
+ { MS_DIRSYNC, ",dirsync" }, |
5426 |
+ { MS_MANDLOCK, ",mand" }, |
5427 |
++ { MS_TAGGED, ",tag" }, |
5428 |
++ { MS_NOTAGCHECK, ",notagcheck" }, |
5429 |
+ { 0, NULL } |
5430 |
+ }; |
5431 |
+ const struct proc_fs_info *fs_infop; |
5432 |
+@@ -805,10 +838,20 @@ static int show_vfsmnt(struct seq_file * |
5433 |
+ int err = 0; |
5434 |
+ struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; |
5435 |
+ |
5436 |
+- mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); |
5437 |
+- seq_putc(m, ' '); |
5438 |
+- seq_path(m, &mnt_path, " \t\n\\"); |
5439 |
+- seq_putc(m, ' '); |
5440 |
++ if (vx_flags(VXF_HIDE_MOUNT, 0)) |
5441 |
++ return SEQ_SKIP; |
5442 |
++ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P)) |
5443 |
++ return SEQ_SKIP; |
5444 |
++ |
5445 |
++ if (!vx_check(0, VS_ADMIN|VS_WATCH) && |
5446 |
++ mnt == current->fs->root.mnt) { |
5447 |
++ seq_puts(m, "/dev/root / "); |
5448 |
++ } else { |
5449 |
++ mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); |
5450 |
++ seq_putc(m, ' '); |
5451 |
++ seq_path(m, &mnt_path, " \t\n\\"); |
5452 |
++ seq_putc(m, ' '); |
5453 |
++ } |
5454 |
+ show_type(m, mnt->mnt_sb); |
5455 |
+ seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw"); |
5456 |
+ err = show_sb_opts(m, mnt->mnt_sb); |
5457 |
+@@ -838,6 +881,11 @@ static int show_mountinfo(struct seq_fil |
5458 |
+ struct path root = p->root; |
5459 |
+ int err = 0; |
5460 |
+ |
5461 |
++ if (vx_flags(VXF_HIDE_MOUNT, 0)) |
5462 |
++ return SEQ_SKIP; |
5463 |
++ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P)) |
5464 |
++ return SEQ_SKIP; |
5465 |
++ |
5466 |
+ seq_printf(m, "%i %i %u:%u ", mnt->mnt_id, mnt->mnt_parent->mnt_id, |
5467 |
+ MAJOR(sb->s_dev), MINOR(sb->s_dev)); |
5468 |
+ seq_dentry(m, mnt->mnt_root, " \t\n\\"); |
5469 |
+@@ -896,17 +944,27 @@ static int show_vfsstat(struct seq_file |
5470 |
+ struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; |
5471 |
+ int err = 0; |
5472 |
+ |
5473 |
+- /* device */ |
5474 |
+- if (mnt->mnt_devname) { |
5475 |
+- seq_puts(m, "device "); |
5476 |
+- mangle(m, mnt->mnt_devname); |
5477 |
+- } else |
5478 |
+- seq_puts(m, "no device"); |
5479 |
++ if (vx_flags(VXF_HIDE_MOUNT, 0)) |
5480 |
++ return SEQ_SKIP; |
5481 |
++ if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P)) |
5482 |
++ return SEQ_SKIP; |
5483 |
+ |
5484 |
+- /* mount point */ |
5485 |
+- seq_puts(m, " mounted on "); |
5486 |
+- seq_path(m, &mnt_path, " \t\n\\"); |
5487 |
+- seq_putc(m, ' '); |
5488 |
++ if (!vx_check(0, VS_ADMIN|VS_WATCH) && |
5489 |
++ mnt == current->fs->root.mnt) { |
5490 |
++ seq_puts(m, "device /dev/root mounted on / "); |
5491 |
++ } else { |
5492 |
++ /* device */ |
5493 |
++ if (mnt->mnt_devname) { |
5494 |
++ seq_puts(m, "device "); |
5495 |
++ mangle(m, mnt->mnt_devname); |
5496 |
++ } else |
5497 |
++ seq_puts(m, "no device"); |
5498 |
++ |
5499 |
++ /* mount point */ |
5500 |
++ seq_puts(m, " mounted on "); |
5501 |
++ seq_path(m, &mnt_path, " \t\n\\"); |
5502 |
++ seq_putc(m, ' '); |
5503 |
++ } |
5504 |
+ |
5505 |
+ /* file system type */ |
5506 |
+ seq_puts(m, "with fstype "); |
5507 |
+@@ -1145,7 +1203,7 @@ SYSCALL_DEFINE2(umount, char __user *, n |
5508 |
+ goto dput_and_out; |
5509 |
+ |
5510 |
+ retval = -EPERM; |
5511 |
+- if (!capable(CAP_SYS_ADMIN)) |
5512 |
++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) |
5513 |
+ goto dput_and_out; |
5514 |
+ |
5515 |
+ retval = do_umount(path.mnt, flags); |
5516 |
+@@ -1171,7 +1229,7 @@ SYSCALL_DEFINE1(oldumount, char __user * |
5517 |
+ |
5518 |
+ static int mount_is_safe(struct path *path) |
5519 |
+ { |
5520 |
+- if (capable(CAP_SYS_ADMIN)) |
5521 |
++ if (vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) |
5522 |
+ return 0; |
5523 |
+ return -EPERM; |
5524 |
+ #ifdef notyet |
5525 |
+@@ -1462,11 +1520,13 @@ static int do_change_type(struct path *p |
5526 |
+ * do loopback mount. |
5527 |
+ */ |
5528 |
+ static int do_loopback(struct path *path, char *old_name, |
5529 |
+- int recurse) |
5530 |
++ tag_t tag, unsigned long flags, int mnt_flags) |
5531 |
+ { |
5532 |
+ struct path old_path; |
5533 |
+ struct vfsmount *mnt = NULL; |
5534 |
+ int err = mount_is_safe(path); |
5535 |
++ int recurse = flags & MS_REC; |
5536 |
++ |
5537 |
+ if (err) |
5538 |
+ return err; |
5539 |
+ if (!old_name || !*old_name) |
5540 |
+@@ -1500,6 +1560,7 @@ static int do_loopback(struct path *path |
5541 |
+ spin_unlock(&vfsmount_lock); |
5542 |
+ release_mounts(&umount_list); |
5543 |
+ } |
5544 |
++ mnt->mnt_flags = mnt_flags; |
5545 |
+ |
5546 |
+ out: |
5547 |
+ up_write(&namespace_sem); |
5548 |
+@@ -1530,12 +1591,12 @@ static int change_mount_flags(struct vfs |
5549 |
+ * on it - tough luck. |
5550 |
+ */ |
5551 |
+ static int do_remount(struct path *path, int flags, int mnt_flags, |
5552 |
+- void *data) |
5553 |
++ void *data, xid_t xid) |
5554 |
+ { |
5555 |
+ int err; |
5556 |
+ struct super_block *sb = path->mnt->mnt_sb; |
5557 |
+ |
5558 |
+- if (!capable(CAP_SYS_ADMIN)) |
5559 |
++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_REMOUNT)) |
5560 |
+ return -EPERM; |
5561 |
+ |
5562 |
+ if (!check_mnt(path->mnt)) |
5563 |
+@@ -1577,7 +1638,7 @@ static int do_move_mount(struct path *pa |
5564 |
+ struct path old_path, parent_path; |
5565 |
+ struct vfsmount *p; |
5566 |
+ int err = 0; |
5567 |
+- if (!capable(CAP_SYS_ADMIN)) |
5568 |
++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) |
5569 |
+ return -EPERM; |
5570 |
+ if (!old_name || !*old_name) |
5571 |
+ return -EINVAL; |
5572 |
+@@ -1659,7 +1720,7 @@ static int do_new_mount(struct path *pat |
5573 |
+ return -EINVAL; |
5574 |
+ |
5575 |
+ /* we need capabilities... */ |
5576 |
+- if (!capable(CAP_SYS_ADMIN)) |
5577 |
++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) |
5578 |
+ return -EPERM; |
5579 |
+ |
5580 |
+ mnt = do_kern_mount(type, flags, name, data); |
5581 |
+@@ -1904,6 +1965,7 @@ long do_mount(char *dev_name, char *dir_ |
5582 |
+ struct path path; |
5583 |
+ int retval = 0; |
5584 |
+ int mnt_flags = 0; |
5585 |
++ tag_t tag = 0; |
5586 |
+ |
5587 |
+ /* Discard magic */ |
5588 |
+ if ((flags & MS_MGC_MSK) == MS_MGC_VAL) |
5589 |
+@@ -1919,6 +1981,12 @@ long do_mount(char *dev_name, char *dir_ |
5590 |
+ if (data_page) |
5591 |
+ ((char *)data_page)[PAGE_SIZE - 1] = 0; |
5592 |
+ |
5593 |
++ if (dx_parse_tag(data_page, &tag, 1, &mnt_flags, &flags)) { |
5594 |
++ /* FIXME: bind and re-mounts get the tag flag? */ |
5595 |
++ if (flags & (MS_BIND|MS_REMOUNT)) |
5596 |
++ flags |= MS_TAGID; |
5597 |
++ } |
5598 |
++ |
5599 |
+ /* Separate the per-mountpoint flags */ |
5600 |
+ if (flags & MS_NOSUID) |
5601 |
+ mnt_flags |= MNT_NOSUID; |
5602 |
+@@ -1935,6 +2003,8 @@ long do_mount(char *dev_name, char *dir_ |
5603 |
+ if (flags & MS_RDONLY) |
5604 |
+ mnt_flags |= MNT_READONLY; |
5605 |
+ |
5606 |
++ if (!capable(CAP_SYS_ADMIN)) |
5607 |
++ mnt_flags |= MNT_NODEV; |
5608 |
+ flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | |
5609 |
+ MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); |
5610 |
+ |
5611 |
+@@ -1950,9 +2020,9 @@ long do_mount(char *dev_name, char *dir_ |
5612 |
+ |
5613 |
+ if (flags & MS_REMOUNT) |
5614 |
+ retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, |
5615 |
+- data_page); |
5616 |
++ data_page, tag); |
5617 |
+ else if (flags & MS_BIND) |
5618 |
+- retval = do_loopback(&path, dev_name, flags & MS_REC); |
5619 |
++ retval = do_loopback(&path, dev_name, tag, flags, mnt_flags); |
5620 |
+ else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) |
5621 |
+ retval = do_change_type(&path, flags); |
5622 |
+ else if (flags & MS_MOVE) |
5623 |
+@@ -2021,6 +2091,7 @@ static struct mnt_namespace *dup_mnt_ns( |
5624 |
+ q = next_mnt(q, new_ns->root); |
5625 |
+ } |
5626 |
+ up_write(&namespace_sem); |
5627 |
++ atomic_inc(&vs_global_mnt_ns); |
5628 |
+ |
5629 |
+ if (rootmnt) |
5630 |
+ mntput(rootmnt); |
5631 |
+@@ -2147,9 +2218,10 @@ SYSCALL_DEFINE2(pivot_root, const char _ |
5632 |
+ down_write(&namespace_sem); |
5633 |
+ mutex_lock(&old.dentry->d_inode->i_mutex); |
5634 |
+ error = -EINVAL; |
5635 |
+- if (IS_MNT_SHARED(old.mnt) || |
5636 |
++ if ((IS_MNT_SHARED(old.mnt) || |
5637 |
+ IS_MNT_SHARED(new.mnt->mnt_parent) || |
5638 |
+- IS_MNT_SHARED(root.mnt->mnt_parent)) |
5639 |
++ IS_MNT_SHARED(root.mnt->mnt_parent)) && |
5640 |
++ !vx_flags(VXF_STATE_SETUP, 0)) |
5641 |
+ goto out2; |
5642 |
+ if (!check_mnt(root.mnt)) |
5643 |
+ goto out2; |
5644 |
+@@ -2288,5 +2360,6 @@ void __put_mnt_ns(struct mnt_namespace * |
5645 |
+ spin_unlock(&vfsmount_lock); |
5646 |
+ up_write(&namespace_sem); |
5647 |
+ release_mounts(&umount_list); |
5648 |
++ atomic_dec(&vs_global_mnt_ns); |
5649 |
+ kfree(ns); |
5650 |
+ } |
5651 |
+diff -NurpP --minimal linux-2.6.29.4/fs/nfs/client.c linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/client.c |
5652 |
+--- linux-2.6.29.4/fs/nfs/client.c 2009-03-24 14:22:26.000000000 +0100 |
5653 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/client.c 2009-03-24 14:48:35.000000000 +0100 |
5654 |
+@@ -696,6 +696,9 @@ static int nfs_init_server_rpcclient(str |
5655 |
+ if (server->flags & NFS_MOUNT_SOFT) |
5656 |
+ server->client->cl_softrtry = 1; |
5657 |
+ |
5658 |
++ server->client->cl_tag = 0; |
5659 |
++ if (server->flags & NFS_MOUNT_TAGGED) |
5660 |
++ server->client->cl_tag = 1; |
5661 |
+ return 0; |
5662 |
+ } |
5663 |
+ |
5664 |
+@@ -862,6 +865,10 @@ static void nfs_server_set_fsinfo(struct |
5665 |
+ server->acdirmin = server->acdirmax = 0; |
5666 |
+ } |
5667 |
+ |
5668 |
++ /* FIXME: needs fsinfo |
5669 |
++ if (server->flags & NFS_MOUNT_TAGGED) |
5670 |
++ sb->s_flags |= MS_TAGGED; */ |
5671 |
++ |
5672 |
+ server->maxfilesize = fsinfo->maxfilesize; |
5673 |
+ |
5674 |
+ /* We're airborne Set socket buffersize */ |
5675 |
+diff -NurpP --minimal linux-2.6.29.4/fs/nfs/dir.c linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/dir.c |
5676 |
+--- linux-2.6.29.4/fs/nfs/dir.c 2009-05-23 23:16:52.000000000 +0200 |
5677 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/dir.c 2009-05-23 23:19:11.000000000 +0200 |
5678 |
+@@ -34,6 +34,7 @@ |
5679 |
+ #include <linux/namei.h> |
5680 |
+ #include <linux/mount.h> |
5681 |
+ #include <linux/sched.h> |
5682 |
++#include <linux/vs_tag.h> |
5683 |
+ |
5684 |
+ #include "nfs4_fs.h" |
5685 |
+ #include "delegation.h" |
5686 |
+@@ -950,6 +951,7 @@ static struct dentry *nfs_lookup(struct |
5687 |
+ if (IS_ERR(res)) |
5688 |
+ goto out_unblock_sillyrename; |
5689 |
+ |
5690 |
++ dx_propagate_tag(nd, inode); |
5691 |
+ no_entry: |
5692 |
+ res = d_materialise_unique(dentry, inode); |
5693 |
+ if (res != NULL) { |
5694 |
+diff -NurpP --minimal linux-2.6.29.4/fs/nfs/inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/inode.c |
5695 |
+--- linux-2.6.29.4/fs/nfs/inode.c 2009-03-24 14:22:26.000000000 +0100 |
5696 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/inode.c 2009-03-24 14:48:35.000000000 +0100 |
5697 |
+@@ -37,6 +37,7 @@ |
5698 |
+ #include <linux/vfs.h> |
5699 |
+ #include <linux/inet.h> |
5700 |
+ #include <linux/nfs_xdr.h> |
5701 |
++#include <linux/vs_tag.h> |
5702 |
+ |
5703 |
+ #include <asm/system.h> |
5704 |
+ #include <asm/uaccess.h> |
5705 |
+@@ -313,8 +314,10 @@ nfs_fhget(struct super_block *sb, struct |
5706 |
+ nfsi->change_attr = fattr->change_attr; |
5707 |
+ inode->i_size = nfs_size_to_loff_t(fattr->size); |
5708 |
+ inode->i_nlink = fattr->nlink; |
5709 |
+- inode->i_uid = fattr->uid; |
5710 |
+- inode->i_gid = fattr->gid; |
5711 |
++ inode->i_uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid); |
5712 |
++ inode->i_gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid); |
5713 |
++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0); |
5714 |
++ /* maybe fattr->xid someday */ |
5715 |
+ if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) { |
5716 |
+ /* |
5717 |
+ * report the blocks in 512byte units |
5718 |
+@@ -462,6 +465,8 @@ void nfs_setattr_update_inode(struct ino |
5719 |
+ inode->i_uid = attr->ia_uid; |
5720 |
+ if ((attr->ia_valid & ATTR_GID) != 0) |
5721 |
+ inode->i_gid = attr->ia_gid; |
5722 |
++ if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode)) |
5723 |
++ inode->i_tag = attr->ia_tag; |
5724 |
+ NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
5725 |
+ spin_unlock(&inode->i_lock); |
5726 |
+ } |
5727 |
+@@ -850,6 +855,9 @@ static int nfs_check_inode_attributes(st |
5728 |
+ struct nfs_inode *nfsi = NFS_I(inode); |
5729 |
+ loff_t cur_size, new_isize; |
5730 |
+ unsigned long invalid = 0; |
5731 |
++ uid_t uid; |
5732 |
++ gid_t gid; |
5733 |
++ tag_t tag; |
5734 |
+ |
5735 |
+ |
5736 |
+ /* Has the inode gone and changed behind our back? */ |
5737 |
+@@ -871,10 +879,15 @@ static int nfs_check_inode_attributes(st |
5738 |
+ if (cur_size != new_isize && nfsi->npages == 0) |
5739 |
+ invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; |
5740 |
+ |
5741 |
++ uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid); |
5742 |
++ gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid); |
5743 |
++ tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0); |
5744 |
++ |
5745 |
+ /* Have any file permissions changed? */ |
5746 |
+ if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) |
5747 |
+- || inode->i_uid != fattr->uid |
5748 |
+- || inode->i_gid != fattr->gid) |
5749 |
++ || inode->i_uid != uid |
5750 |
++ || inode->i_gid != gid |
5751 |
++ || inode->i_tag != tag) |
5752 |
+ invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; |
5753 |
+ |
5754 |
+ /* Has the link count changed? */ |
5755 |
+@@ -1073,6 +1086,9 @@ static int nfs_update_inode(struct inode |
5756 |
+ loff_t cur_isize, new_isize; |
5757 |
+ unsigned long invalid = 0; |
5758 |
+ unsigned long now = jiffies; |
5759 |
++ uid_t uid; |
5760 |
++ gid_t gid; |
5761 |
++ tag_t tag; |
5762 |
+ |
5763 |
+ dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", |
5764 |
+ __func__, inode->i_sb->s_id, inode->i_ino, |
5765 |
+@@ -1146,9 +1162,14 @@ static int nfs_update_inode(struct inode |
5766 |
+ memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); |
5767 |
+ nfsi->change_attr = fattr->change_attr; |
5768 |
+ |
5769 |
++ uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid); |
5770 |
++ gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid); |
5771 |
++ tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0); |
5772 |
++ |
5773 |
+ if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) || |
5774 |
+- inode->i_uid != fattr->uid || |
5775 |
+- inode->i_gid != fattr->gid) |
5776 |
++ inode->i_uid != uid || |
5777 |
++ inode->i_gid != gid || |
5778 |
++ inode->i_tag != tag) |
5779 |
+ invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
5780 |
+ |
5781 |
+ if (inode->i_nlink != fattr->nlink) |
5782 |
+@@ -1156,8 +1177,9 @@ static int nfs_update_inode(struct inode |
5783 |
+ |
5784 |
+ inode->i_mode = fattr->mode; |
5785 |
+ inode->i_nlink = fattr->nlink; |
5786 |
+- inode->i_uid = fattr->uid; |
5787 |
+- inode->i_gid = fattr->gid; |
5788 |
++ inode->i_uid = uid; |
5789 |
++ inode->i_gid = gid; |
5790 |
++ inode->i_tag = tag; |
5791 |
+ |
5792 |
+ if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) { |
5793 |
+ /* |
5794 |
+diff -NurpP --minimal linux-2.6.29.4/fs/nfs/nfs3xdr.c linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/nfs3xdr.c |
5795 |
+--- linux-2.6.29.4/fs/nfs/nfs3xdr.c 2009-05-23 23:16:53.000000000 +0200 |
5796 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/nfs3xdr.c 2009-04-30 12:14:53.000000000 +0200 |
5797 |
+@@ -22,6 +22,7 @@ |
5798 |
+ #include <linux/nfs3.h> |
5799 |
+ #include <linux/nfs_fs.h> |
5800 |
+ #include <linux/nfsacl.h> |
5801 |
++#include <linux/vs_tag.h> |
5802 |
+ #include "internal.h" |
5803 |
+ |
5804 |
+ #define NFSDBG_FACILITY NFSDBG_XDR |
5805 |
+@@ -182,7 +183,7 @@ xdr_decode_fattr(__be32 *p, struct nfs_f |
5806 |
+ } |
5807 |
+ |
5808 |
+ static inline __be32 * |
5809 |
+-xdr_encode_sattr(__be32 *p, struct iattr *attr) |
5810 |
++xdr_encode_sattr(__be32 *p, struct iattr *attr, int tag) |
5811 |
+ { |
5812 |
+ if (attr->ia_valid & ATTR_MODE) { |
5813 |
+ *p++ = xdr_one; |
5814 |
+@@ -190,15 +191,17 @@ xdr_encode_sattr(__be32 *p, struct iattr |
5815 |
+ } else { |
5816 |
+ *p++ = xdr_zero; |
5817 |
+ } |
5818 |
+- if (attr->ia_valid & ATTR_UID) { |
5819 |
++ if (attr->ia_valid & ATTR_UID || |
5820 |
++ (tag && (attr->ia_valid & ATTR_TAG))) { |
5821 |
+ *p++ = xdr_one; |
5822 |
+- *p++ = htonl(attr->ia_uid); |
5823 |
++ *p++ = htonl(TAGINO_UID(tag, attr->ia_uid, attr->ia_tag)); |
5824 |
+ } else { |
5825 |
+ *p++ = xdr_zero; |
5826 |
+ } |
5827 |
+- if (attr->ia_valid & ATTR_GID) { |
5828 |
++ if (attr->ia_valid & ATTR_GID || |
5829 |
++ (tag && (attr->ia_valid & ATTR_TAG))) { |
5830 |
+ *p++ = xdr_one; |
5831 |
+- *p++ = htonl(attr->ia_gid); |
5832 |
++ *p++ = htonl(TAGINO_GID(tag, attr->ia_gid, attr->ia_tag)); |
5833 |
+ } else { |
5834 |
+ *p++ = xdr_zero; |
5835 |
+ } |
5836 |
+@@ -283,7 +286,8 @@ static int |
5837 |
+ nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args) |
5838 |
+ { |
5839 |
+ p = xdr_encode_fhandle(p, args->fh); |
5840 |
+- p = xdr_encode_sattr(p, args->sattr); |
5841 |
++ p = xdr_encode_sattr(p, args->sattr, |
5842 |
++ req->rq_task->tk_client->cl_tag); |
5843 |
+ *p++ = htonl(args->guard); |
5844 |
+ if (args->guard) |
5845 |
+ p = xdr_encode_time3(p, &args->guardtime); |
5846 |
+@@ -388,7 +392,8 @@ nfs3_xdr_createargs(struct rpc_rqst *req |
5847 |
+ *p++ = args->verifier[0]; |
5848 |
+ *p++ = args->verifier[1]; |
5849 |
+ } else |
5850 |
+- p = xdr_encode_sattr(p, args->sattr); |
5851 |
++ p = xdr_encode_sattr(p, args->sattr, |
5852 |
++ req->rq_task->tk_client->cl_tag); |
5853 |
+ |
5854 |
+ req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); |
5855 |
+ return 0; |
5856 |
+@@ -402,7 +407,8 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req, |
5857 |
+ { |
5858 |
+ p = xdr_encode_fhandle(p, args->fh); |
5859 |
+ p = xdr_encode_array(p, args->name, args->len); |
5860 |
+- p = xdr_encode_sattr(p, args->sattr); |
5861 |
++ p = xdr_encode_sattr(p, args->sattr, |
5862 |
++ req->rq_task->tk_client->cl_tag); |
5863 |
+ req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); |
5864 |
+ return 0; |
5865 |
+ } |
5866 |
+@@ -415,7 +421,8 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *re |
5867 |
+ { |
5868 |
+ p = xdr_encode_fhandle(p, args->fromfh); |
5869 |
+ p = xdr_encode_array(p, args->fromname, args->fromlen); |
5870 |
+- p = xdr_encode_sattr(p, args->sattr); |
5871 |
++ p = xdr_encode_sattr(p, args->sattr, |
5872 |
++ req->rq_task->tk_client->cl_tag); |
5873 |
+ *p++ = htonl(args->pathlen); |
5874 |
+ req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); |
5875 |
+ |
5876 |
+@@ -433,7 +440,8 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req, |
5877 |
+ p = xdr_encode_fhandle(p, args->fh); |
5878 |
+ p = xdr_encode_array(p, args->name, args->len); |
5879 |
+ *p++ = htonl(args->type); |
5880 |
+- p = xdr_encode_sattr(p, args->sattr); |
5881 |
++ p = xdr_encode_sattr(p, args->sattr, |
5882 |
++ req->rq_task->tk_client->cl_tag); |
5883 |
+ if (args->type == NF3CHR || args->type == NF3BLK) { |
5884 |
+ *p++ = htonl(MAJOR(args->rdev)); |
5885 |
+ *p++ = htonl(MINOR(args->rdev)); |
5886 |
+diff -NurpP --minimal linux-2.6.29.4/fs/nfs/nfsroot.c linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/nfsroot.c |
5887 |
+--- linux-2.6.29.4/fs/nfs/nfsroot.c 2009-03-24 14:22:26.000000000 +0100 |
5888 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/nfsroot.c 2009-03-24 14:48:35.000000000 +0100 |
5889 |
+@@ -119,12 +119,12 @@ static int mount_port __initdata = 0; / |
5890 |
+ enum { |
5891 |
+ /* Options that take integer arguments */ |
5892 |
+ Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin, |
5893 |
+- Opt_acregmax, Opt_acdirmin, Opt_acdirmax, |
5894 |
++ Opt_acregmax, Opt_acdirmin, Opt_acdirmax, Opt_tagid, |
5895 |
+ /* Options that take no arguments */ |
5896 |
+ Opt_soft, Opt_hard, Opt_intr, |
5897 |
+ Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, |
5898 |
+ Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp, |
5899 |
+- Opt_acl, Opt_noacl, |
5900 |
++ Opt_acl, Opt_noacl, Opt_tag, Opt_notag, |
5901 |
+ /* Error token */ |
5902 |
+ Opt_err |
5903 |
+ }; |
5904 |
+@@ -161,6 +161,9 @@ static match_table_t __initconst tokens |
5905 |
+ {Opt_tcp, "tcp"}, |
5906 |
+ {Opt_acl, "acl"}, |
5907 |
+ {Opt_noacl, "noacl"}, |
5908 |
++ {Opt_tag, "tag"}, |
5909 |
++ {Opt_notag, "notag"}, |
5910 |
++ {Opt_tagid, "tagid=%u"}, |
5911 |
+ {Opt_err, NULL} |
5912 |
+ |
5913 |
+ }; |
5914 |
+@@ -272,6 +275,20 @@ static int __init root_nfs_parse(char *n |
5915 |
+ case Opt_noacl: |
5916 |
+ nfs_data.flags |= NFS_MOUNT_NOACL; |
5917 |
+ break; |
5918 |
++#ifndef CONFIG_TAGGING_NONE |
5919 |
++ case Opt_tag: |
5920 |
++ nfs_data.flags |= NFS_MOUNT_TAGGED; |
5921 |
++ break; |
5922 |
++ case Opt_notag: |
5923 |
++ nfs_data.flags &= ~NFS_MOUNT_TAGGED; |
5924 |
++ break; |
5925 |
++#endif |
5926 |
++#ifdef CONFIG_PROPAGATE |
5927 |
++ case Opt_tagid: |
5928 |
++ /* use args[0] */ |
5929 |
++ nfs_data.flags |= NFS_MOUNT_TAGGED; |
5930 |
++ break; |
5931 |
++#endif |
5932 |
+ default: |
5933 |
+ printk(KERN_WARNING "Root-NFS: unknown " |
5934 |
+ "option: %s\n", p); |
5935 |
+diff -NurpP --minimal linux-2.6.29.4/fs/nfs/super.c linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/super.c |
5936 |
+--- linux-2.6.29.4/fs/nfs/super.c 2009-03-24 14:22:26.000000000 +0100 |
5937 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/nfs/super.c 2009-03-24 16:02:06.000000000 +0100 |
5938 |
+@@ -51,6 +51,7 @@ |
5939 |
+ #include <linux/nfs_xdr.h> |
5940 |
+ #include <linux/magic.h> |
5941 |
+ #include <linux/parser.h> |
5942 |
++#include <linux/vs_tag.h> |
5943 |
+ |
5944 |
+ #include <asm/system.h> |
5945 |
+ #include <asm/uaccess.h> |
5946 |
+@@ -517,6 +518,7 @@ static void nfs_show_mount_options(struc |
5947 |
+ { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" }, |
5948 |
+ { NFS_MOUNT_UNSHARED, ",nosharecache", "" }, |
5949 |
+ { NFS_MOUNT_NORESVPORT, ",noresvport", "" }, |
5950 |
++ { NFS_MOUNT_TAGGED, ",tag", "" }, |
5951 |
+ { 0, NULL, NULL } |
5952 |
+ }; |
5953 |
+ const struct proc_nfs_info *nfs_infop; |
5954 |
+diff -NurpP --minimal linux-2.6.29.4/fs/nfsd/auth.c linux-2.6.29.4-vs2.3.0.36.14/fs/nfsd/auth.c |
5955 |
+--- linux-2.6.29.4/fs/nfsd/auth.c 2009-03-24 14:22:26.000000000 +0100 |
5956 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/nfsd/auth.c 2009-03-24 16:09:39.000000000 +0100 |
5957 |
+@@ -10,6 +10,7 @@ |
5958 |
+ #include <linux/sunrpc/svcauth.h> |
5959 |
+ #include <linux/nfsd/nfsd.h> |
5960 |
+ #include <linux/nfsd/export.h> |
5961 |
++#include <linux/vs_tag.h> |
5962 |
+ #include "auth.h" |
5963 |
+ |
5964 |
+ int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp) |
5965 |
+@@ -42,6 +43,9 @@ int nfsd_setuser(struct svc_rqst *rqstp, |
5966 |
+ |
5967 |
+ new->fsuid = rqstp->rq_cred.cr_uid; |
5968 |
+ new->fsgid = rqstp->rq_cred.cr_gid; |
5969 |
++ /* FIXME: this desperately needs a tag :) |
5970 |
++ new->xid = (xid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0); |
5971 |
++ */ |
5972 |
+ |
5973 |
+ rqgi = rqstp->rq_cred.cr_group_info; |
5974 |
+ |
5975 |
+@@ -69,7 +73,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, |
5976 |
+ } |
5977 |
+ } else { |
5978 |
+ gi = get_group_info(rqgi); |
5979 |
+- } |
5980 |
++ } |
5981 |
+ |
5982 |
+ if (new->fsuid == (uid_t) -1) |
5983 |
+ new->fsuid = exp->ex_anon_uid; |
5984 |
+@@ -94,6 +98,6 @@ oom: |
5985 |
+ ret = -ENOMEM; |
5986 |
+ error: |
5987 |
+ abort_creds(new); |
5988 |
+- return ret; |
5989 |
++ return ret; |
5990 |
+ } |
5991 |
+ |
5992 |
+diff -NurpP --minimal linux-2.6.29.4/fs/nfsd/nfs3xdr.c linux-2.6.29.4-vs2.3.0.36.14/fs/nfsd/nfs3xdr.c |
5993 |
+--- linux-2.6.29.4/fs/nfsd/nfs3xdr.c 2008-12-25 00:26:37.000000000 +0100 |
5994 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/nfsd/nfs3xdr.c 2009-02-22 22:54:25.000000000 +0100 |
5995 |
+@@ -21,6 +21,7 @@ |
5996 |
+ #include <linux/sunrpc/svc.h> |
5997 |
+ #include <linux/nfsd/nfsd.h> |
5998 |
+ #include <linux/nfsd/xdr3.h> |
5999 |
++#include <linux/vs_tag.h> |
6000 |
+ #include "auth.h" |
6001 |
+ |
6002 |
+ #define NFSDDBG_FACILITY NFSDDBG_XDR |
6003 |
+@@ -108,6 +109,8 @@ static __be32 * |
6004 |
+ decode_sattr3(__be32 *p, struct iattr *iap) |
6005 |
+ { |
6006 |
+ u32 tmp; |
6007 |
++ uid_t uid = 0; |
6008 |
++ gid_t gid = 0; |
6009 |
+ |
6010 |
+ iap->ia_valid = 0; |
6011 |
+ |
6012 |
+@@ -117,12 +120,15 @@ decode_sattr3(__be32 *p, struct iattr *i |
6013 |
+ } |
6014 |
+ if (*p++) { |
6015 |
+ iap->ia_valid |= ATTR_UID; |
6016 |
+- iap->ia_uid = ntohl(*p++); |
6017 |
++ uid = ntohl(*p++); |
6018 |
+ } |
6019 |
+ if (*p++) { |
6020 |
+ iap->ia_valid |= ATTR_GID; |
6021 |
+- iap->ia_gid = ntohl(*p++); |
6022 |
++ gid = ntohl(*p++); |
6023 |
+ } |
6024 |
++ iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid); |
6025 |
++ iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid); |
6026 |
++ iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0); |
6027 |
+ if (*p++) { |
6028 |
+ u64 newsize; |
6029 |
+ |
6030 |
+@@ -178,8 +184,12 @@ encode_fattr3(struct svc_rqst *rqstp, __ |
6031 |
+ *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); |
6032 |
+ *p++ = htonl((u32) stat->mode); |
6033 |
+ *p++ = htonl((u32) stat->nlink); |
6034 |
+- *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid)); |
6035 |
+- *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid)); |
6036 |
++ *p++ = htonl((u32) nfsd_ruid(rqstp, |
6037 |
++ TAGINO_UID(0 /* FIXME: DX_TAG(dentry->d_inode) */, |
6038 |
++ stat->uid, stat->tag))); |
6039 |
++ *p++ = htonl((u32) nfsd_rgid(rqstp, |
6040 |
++ TAGINO_GID(0 /* FIXME: DX_TAG(dentry->d_inode) */, |
6041 |
++ stat->gid, stat->tag))); |
6042 |
+ if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) { |
6043 |
+ p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); |
6044 |
+ } else { |
6045 |
+diff -NurpP --minimal linux-2.6.29.4/fs/nfsd/nfs4xdr.c linux-2.6.29.4-vs2.3.0.36.14/fs/nfsd/nfs4xdr.c |
6046 |
+--- linux-2.6.29.4/fs/nfsd/nfs4xdr.c 2009-05-23 23:16:53.000000000 +0200 |
6047 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/nfsd/nfs4xdr.c 2009-05-23 23:19:11.000000000 +0200 |
6048 |
+@@ -56,6 +56,7 @@ |
6049 |
+ #include <linux/nfs4_acl.h> |
6050 |
+ #include <linux/sunrpc/gss_api.h> |
6051 |
+ #include <linux/sunrpc/svcauth_gss.h> |
6052 |
++#include <linux/vs_tag.h> |
6053 |
+ |
6054 |
+ #define NFSDDBG_FACILITY NFSDDBG_XDR |
6055 |
+ |
6056 |
+@@ -1714,14 +1715,18 @@ out_acl: |
6057 |
+ WRITE32(stat.nlink); |
6058 |
+ } |
6059 |
+ if (bmval1 & FATTR4_WORD1_OWNER) { |
6060 |
+- status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen); |
6061 |
++ status = nfsd4_encode_user(rqstp, |
6062 |
++ TAGINO_UID(DX_TAG(dentry->d_inode), |
6063 |
++ stat.uid, stat.tag), &p, &buflen); |
6064 |
+ if (status == nfserr_resource) |
6065 |
+ goto out_resource; |
6066 |
+ if (status) |
6067 |
+ goto out; |
6068 |
+ } |
6069 |
+ if (bmval1 & FATTR4_WORD1_OWNER_GROUP) { |
6070 |
+- status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen); |
6071 |
++ status = nfsd4_encode_group(rqstp, |
6072 |
++ TAGINO_GID(DX_TAG(dentry->d_inode), |
6073 |
++ stat.gid, stat.tag), &p, &buflen); |
6074 |
+ if (status == nfserr_resource) |
6075 |
+ goto out_resource; |
6076 |
+ if (status) |
6077 |
+diff -NurpP --minimal linux-2.6.29.4/fs/nfsd/nfsxdr.c linux-2.6.29.4-vs2.3.0.36.14/fs/nfsd/nfsxdr.c |
6078 |
+--- linux-2.6.29.4/fs/nfsd/nfsxdr.c 2008-12-25 00:26:37.000000000 +0100 |
6079 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/nfsd/nfsxdr.c 2009-02-22 22:54:25.000000000 +0100 |
6080 |
+@@ -15,6 +15,7 @@ |
6081 |
+ #include <linux/nfsd/nfsd.h> |
6082 |
+ #include <linux/nfsd/xdr.h> |
6083 |
+ #include <linux/mm.h> |
6084 |
++#include <linux/vs_tag.h> |
6085 |
+ #include "auth.h" |
6086 |
+ |
6087 |
+ #define NFSDDBG_FACILITY NFSDDBG_XDR |
6088 |
+@@ -98,6 +99,8 @@ static __be32 * |
6089 |
+ decode_sattr(__be32 *p, struct iattr *iap) |
6090 |
+ { |
6091 |
+ u32 tmp, tmp1; |
6092 |
++ uid_t uid = 0; |
6093 |
++ gid_t gid = 0; |
6094 |
+ |
6095 |
+ iap->ia_valid = 0; |
6096 |
+ |
6097 |
+@@ -111,12 +114,15 @@ decode_sattr(__be32 *p, struct iattr *ia |
6098 |
+ } |
6099 |
+ if ((tmp = ntohl(*p++)) != (u32)-1) { |
6100 |
+ iap->ia_valid |= ATTR_UID; |
6101 |
+- iap->ia_uid = tmp; |
6102 |
++ uid = tmp; |
6103 |
+ } |
6104 |
+ if ((tmp = ntohl(*p++)) != (u32)-1) { |
6105 |
+ iap->ia_valid |= ATTR_GID; |
6106 |
+- iap->ia_gid = tmp; |
6107 |
++ gid = tmp; |
6108 |
+ } |
6109 |
++ iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid); |
6110 |
++ iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid); |
6111 |
++ iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0); |
6112 |
+ if ((tmp = ntohl(*p++)) != (u32)-1) { |
6113 |
+ iap->ia_valid |= ATTR_SIZE; |
6114 |
+ iap->ia_size = tmp; |
6115 |
+@@ -161,8 +167,10 @@ encode_fattr(struct svc_rqst *rqstp, __b |
6116 |
+ *p++ = htonl(nfs_ftypes[type >> 12]); |
6117 |
+ *p++ = htonl((u32) stat->mode); |
6118 |
+ *p++ = htonl((u32) stat->nlink); |
6119 |
+- *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid)); |
6120 |
+- *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid)); |
6121 |
++ *p++ = htonl((u32) nfsd_ruid(rqstp, |
6122 |
++ TAGINO_UID(DX_TAG(dentry->d_inode), stat->uid, stat->tag))); |
6123 |
++ *p++ = htonl((u32) nfsd_rgid(rqstp, |
6124 |
++ TAGINO_GID(DX_TAG(dentry->d_inode), stat->gid, stat->tag))); |
6125 |
+ |
6126 |
+ if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { |
6127 |
+ *p++ = htonl(NFS_MAXPATHLEN); |
6128 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/dlm/dlmfs.c linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/dlm/dlmfs.c |
6129 |
+--- linux-2.6.29.4/fs/ocfs2/dlm/dlmfs.c 2009-03-24 14:22:27.000000000 +0100 |
6130 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/dlm/dlmfs.c 2009-03-24 16:10:48.000000000 +0100 |
6131 |
+@@ -43,6 +43,7 @@ |
6132 |
+ #include <linux/init.h> |
6133 |
+ #include <linux/string.h> |
6134 |
+ #include <linux/backing-dev.h> |
6135 |
++#include <linux/vs_tag.h> |
6136 |
+ |
6137 |
+ #include <asm/uaccess.h> |
6138 |
+ |
6139 |
+@@ -341,6 +342,7 @@ static struct inode *dlmfs_get_root_inod |
6140 |
+ inode->i_mode = mode; |
6141 |
+ inode->i_uid = current_fsuid(); |
6142 |
+ inode->i_gid = current_fsgid(); |
6143 |
++ inode->i_tag = dx_current_fstag(sb); |
6144 |
+ inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info; |
6145 |
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
6146 |
+ inc_nlink(inode); |
6147 |
+@@ -366,6 +368,7 @@ static struct inode *dlmfs_get_inode(str |
6148 |
+ inode->i_mode = mode; |
6149 |
+ inode->i_uid = current_fsuid(); |
6150 |
+ inode->i_gid = current_fsgid(); |
6151 |
++ inode->i_tag = dx_current_fstag(sb); |
6152 |
+ inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info; |
6153 |
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
6154 |
+ |
6155 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/dlmglue.c linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/dlmglue.c |
6156 |
+--- linux-2.6.29.4/fs/ocfs2/dlmglue.c 2009-03-24 14:22:27.000000000 +0100 |
6157 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/dlmglue.c 2009-03-24 14:48:35.000000000 +0100 |
6158 |
+@@ -1885,6 +1885,7 @@ static void __ocfs2_stuff_meta_lvb(struc |
6159 |
+ lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters); |
6160 |
+ lvb->lvb_iuid = cpu_to_be32(inode->i_uid); |
6161 |
+ lvb->lvb_igid = cpu_to_be32(inode->i_gid); |
6162 |
++ lvb->lvb_itag = cpu_to_be16(inode->i_tag); |
6163 |
+ lvb->lvb_imode = cpu_to_be16(inode->i_mode); |
6164 |
+ lvb->lvb_inlink = cpu_to_be16(inode->i_nlink); |
6165 |
+ lvb->lvb_iatime_packed = |
6166 |
+@@ -1939,6 +1940,7 @@ static void ocfs2_refresh_inode_from_lvb |
6167 |
+ |
6168 |
+ inode->i_uid = be32_to_cpu(lvb->lvb_iuid); |
6169 |
+ inode->i_gid = be32_to_cpu(lvb->lvb_igid); |
6170 |
++ inode->i_tag = be16_to_cpu(lvb->lvb_itag); |
6171 |
+ inode->i_mode = be16_to_cpu(lvb->lvb_imode); |
6172 |
+ inode->i_nlink = be16_to_cpu(lvb->lvb_inlink); |
6173 |
+ ocfs2_unpack_timespec(&inode->i_atime, |
6174 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/dlmglue.h linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/dlmglue.h |
6175 |
+--- linux-2.6.29.4/fs/ocfs2/dlmglue.h 2009-03-24 14:22:27.000000000 +0100 |
6176 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/dlmglue.h 2009-03-24 14:48:35.000000000 +0100 |
6177 |
+@@ -46,7 +46,8 @@ struct ocfs2_meta_lvb { |
6178 |
+ __be16 lvb_inlink; |
6179 |
+ __be32 lvb_iattr; |
6180 |
+ __be32 lvb_igeneration; |
6181 |
+- __be32 lvb_reserved2; |
6182 |
++ __be16 lvb_itag; |
6183 |
++ __be16 lvb_reserved2; |
6184 |
+ }; |
6185 |
+ |
6186 |
+ #define OCFS2_QINFO_LVB_VERSION 1 |
6187 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/file.c linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/file.c |
6188 |
+--- linux-2.6.29.4/fs/ocfs2/file.c 2009-05-23 23:16:53.000000000 +0200 |
6189 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/file.c 2009-05-23 23:19:11.000000000 +0200 |
6190 |
+@@ -911,13 +911,15 @@ int ocfs2_setattr(struct dentry *dentry, |
6191 |
+ mlog(0, "uid change: %d\n", attr->ia_uid); |
6192 |
+ if (attr->ia_valid & ATTR_GID) |
6193 |
+ mlog(0, "gid change: %d\n", attr->ia_gid); |
6194 |
++ if (attr->ia_valid & ATTR_TAG) |
6195 |
++ mlog(0, "tag change: %d\n", attr->ia_tag); |
6196 |
+ if (attr->ia_valid & ATTR_SIZE) |
6197 |
+ mlog(0, "size change...\n"); |
6198 |
+ if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME)) |
6199 |
+ mlog(0, "time change...\n"); |
6200 |
+ |
6201 |
+ #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \ |
6202 |
+- | ATTR_GID | ATTR_UID | ATTR_MODE) |
6203 |
++ | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE) |
6204 |
+ if (!(attr->ia_valid & OCFS2_VALID_ATTRS)) { |
6205 |
+ mlog(0, "can't handle attrs: 0x%x\n", attr->ia_valid); |
6206 |
+ return 0; |
6207 |
+@@ -2128,6 +2130,7 @@ const struct inode_operations ocfs2_file |
6208 |
+ .removexattr = generic_removexattr, |
6209 |
+ .fallocate = ocfs2_fallocate, |
6210 |
+ .fiemap = ocfs2_fiemap, |
6211 |
++ .sync_flags = ocfs2_sync_flags, |
6212 |
+ }; |
6213 |
+ |
6214 |
+ const struct inode_operations ocfs2_special_file_iops = { |
6215 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/inode.c |
6216 |
+--- linux-2.6.29.4/fs/ocfs2/inode.c 2009-03-24 14:22:27.000000000 +0100 |
6217 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/inode.c 2009-03-24 16:11:11.000000000 +0100 |
6218 |
+@@ -29,6 +29,7 @@ |
6219 |
+ #include <linux/highmem.h> |
6220 |
+ #include <linux/pagemap.h> |
6221 |
+ #include <linux/quotaops.h> |
6222 |
++#include <linux/vs_tag.h> |
6223 |
+ |
6224 |
+ #include <asm/byteorder.h> |
6225 |
+ |
6226 |
+@@ -44,6 +45,7 @@ |
6227 |
+ #include "file.h" |
6228 |
+ #include "heartbeat.h" |
6229 |
+ #include "inode.h" |
6230 |
++#include "ioctl.h" |
6231 |
+ #include "journal.h" |
6232 |
+ #include "namei.h" |
6233 |
+ #include "suballoc.h" |
6234 |
+@@ -77,11 +79,13 @@ void ocfs2_set_inode_flags(struct inode |
6235 |
+ { |
6236 |
+ unsigned int flags = OCFS2_I(inode)->ip_attr; |
6237 |
+ |
6238 |
+- inode->i_flags &= ~(S_IMMUTABLE | |
6239 |
++ inode->i_flags &= ~(S_IMMUTABLE | S_IXUNLINK | |
6240 |
+ S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC); |
6241 |
+ |
6242 |
+ if (flags & OCFS2_IMMUTABLE_FL) |
6243 |
+ inode->i_flags |= S_IMMUTABLE; |
6244 |
++ if (flags & OCFS2_IXUNLINK_FL) |
6245 |
++ inode->i_flags |= S_IXUNLINK; |
6246 |
+ |
6247 |
+ if (flags & OCFS2_SYNC_FL) |
6248 |
+ inode->i_flags |= S_SYNC; |
6249 |
+@@ -91,25 +95,85 @@ void ocfs2_set_inode_flags(struct inode |
6250 |
+ inode->i_flags |= S_NOATIME; |
6251 |
+ if (flags & OCFS2_DIRSYNC_FL) |
6252 |
+ inode->i_flags |= S_DIRSYNC; |
6253 |
++ |
6254 |
++ inode->i_vflags &= ~(V_BARRIER | V_COW); |
6255 |
++ |
6256 |
++ if (flags & OCFS2_BARRIER_FL) |
6257 |
++ inode->i_vflags |= V_BARRIER; |
6258 |
++ if (flags & OCFS2_COW_FL) |
6259 |
++ inode->i_vflags |= V_COW; |
6260 |
+ } |
6261 |
+ |
6262 |
+ /* Propagate flags from i_flags to OCFS2_I(inode)->ip_attr */ |
6263 |
+ void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi) |
6264 |
+ { |
6265 |
+ unsigned int flags = oi->vfs_inode.i_flags; |
6266 |
++ unsigned int vflags = oi->vfs_inode.i_vflags; |
6267 |
++ |
6268 |
++ oi->ip_attr &= ~(OCFS2_SYNC_FL | OCFS2_APPEND_FL | |
6269 |
++ OCFS2_IMMUTABLE_FL | OCFS2_IXUNLINK_FL | |
6270 |
++ OCFS2_NOATIME_FL | OCFS2_DIRSYNC_FL | |
6271 |
++ OCFS2_BARRIER_FL | OCFS2_COW_FL); |
6272 |
++ |
6273 |
++ if (flags & S_IMMUTABLE) |
6274 |
++ oi->ip_attr |= OCFS2_IMMUTABLE_FL; |
6275 |
++ if (flags & S_IXUNLINK) |
6276 |
++ oi->ip_attr |= OCFS2_IXUNLINK_FL; |
6277 |
+ |
6278 |
+- oi->ip_attr &= ~(OCFS2_SYNC_FL|OCFS2_APPEND_FL| |
6279 |
+- OCFS2_IMMUTABLE_FL|OCFS2_NOATIME_FL|OCFS2_DIRSYNC_FL); |
6280 |
+ if (flags & S_SYNC) |
6281 |
+ oi->ip_attr |= OCFS2_SYNC_FL; |
6282 |
+ if (flags & S_APPEND) |
6283 |
+ oi->ip_attr |= OCFS2_APPEND_FL; |
6284 |
+- if (flags & S_IMMUTABLE) |
6285 |
+- oi->ip_attr |= OCFS2_IMMUTABLE_FL; |
6286 |
+ if (flags & S_NOATIME) |
6287 |
+ oi->ip_attr |= OCFS2_NOATIME_FL; |
6288 |
+ if (flags & S_DIRSYNC) |
6289 |
+ oi->ip_attr |= OCFS2_DIRSYNC_FL; |
6290 |
++ |
6291 |
++ if (vflags & V_BARRIER) |
6292 |
++ oi->ip_attr |= OCFS2_BARRIER_FL; |
6293 |
++ if (vflags & V_COW) |
6294 |
++ oi->ip_attr |= OCFS2_COW_FL; |
6295 |
++} |
6296 |
++ |
6297 |
++int ocfs2_sync_flags(struct inode *inode) |
6298 |
++{ |
6299 |
++ struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode); |
6300 |
++ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
6301 |
++ handle_t *handle = NULL; |
6302 |
++ struct buffer_head *bh = NULL; |
6303 |
++ int status; |
6304 |
++ |
6305 |
++ status = ocfs2_inode_lock(inode, &bh, 1); |
6306 |
++ if (status < 0) { |
6307 |
++ mlog_errno(status); |
6308 |
++ goto bail; |
6309 |
++ } |
6310 |
++ |
6311 |
++ status = -EROFS; |
6312 |
++ if (IS_RDONLY(inode)) |
6313 |
++ goto bail_unlock; |
6314 |
++ |
6315 |
++ handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
6316 |
++ if (IS_ERR(handle)) { |
6317 |
++ status = PTR_ERR(handle); |
6318 |
++ mlog_errno(status); |
6319 |
++ goto bail_unlock; |
6320 |
++ } |
6321 |
++ |
6322 |
++ ocfs2_get_inode_flags(ocfs2_inode); |
6323 |
++ status = ocfs2_mark_inode_dirty(handle, inode, bh); |
6324 |
++ if (status < 0) |
6325 |
++ mlog_errno(status); |
6326 |
++ |
6327 |
++ ocfs2_commit_trans(osb, handle); |
6328 |
++bail_unlock: |
6329 |
++ ocfs2_inode_unlock(inode, 1); |
6330 |
++bail: |
6331 |
++ if (bh) |
6332 |
++ brelse(bh); |
6333 |
++ |
6334 |
++ mlog_exit(status); |
6335 |
++ return status; |
6336 |
+ } |
6337 |
+ |
6338 |
+ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags, |
6339 |
+@@ -222,6 +286,8 @@ void ocfs2_populate_inode(struct inode * |
6340 |
+ struct super_block *sb; |
6341 |
+ struct ocfs2_super *osb; |
6342 |
+ int use_plocks = 1; |
6343 |
++ uid_t uid; |
6344 |
++ gid_t gid; |
6345 |
+ |
6346 |
+ mlog_entry("(0x%p, size:%llu)\n", inode, |
6347 |
+ (unsigned long long)le64_to_cpu(fe->i_size)); |
6348 |
+@@ -253,8 +319,12 @@ void ocfs2_populate_inode(struct inode * |
6349 |
+ inode->i_generation = le32_to_cpu(fe->i_generation); |
6350 |
+ inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev)); |
6351 |
+ inode->i_mode = le16_to_cpu(fe->i_mode); |
6352 |
+- inode->i_uid = le32_to_cpu(fe->i_uid); |
6353 |
+- inode->i_gid = le32_to_cpu(fe->i_gid); |
6354 |
++ uid = le32_to_cpu(fe->i_uid); |
6355 |
++ gid = le32_to_cpu(fe->i_gid); |
6356 |
++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid); |
6357 |
++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid); |
6358 |
++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid, |
6359 |
++ /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0); |
6360 |
+ |
6361 |
+ /* Fast symlinks will have i_size but no allocated clusters. */ |
6362 |
+ if (S_ISLNK(inode->i_mode) && !fe->i_clusters) |
6363 |
+@@ -1206,8 +1276,11 @@ int ocfs2_mark_inode_dirty(handle_t *han |
6364 |
+ |
6365 |
+ fe->i_size = cpu_to_le64(i_size_read(inode)); |
6366 |
+ fe->i_links_count = cpu_to_le16(inode->i_nlink); |
6367 |
+- fe->i_uid = cpu_to_le32(inode->i_uid); |
6368 |
+- fe->i_gid = cpu_to_le32(inode->i_gid); |
6369 |
++ fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode), |
6370 |
++ inode->i_uid, inode->i_tag)); |
6371 |
++ fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode), |
6372 |
++ inode->i_gid, inode->i_tag)); |
6373 |
++ /* i_tag = = cpu_to_le16(inode->i_tag); */ |
6374 |
+ fe->i_mode = cpu_to_le16(inode->i_mode); |
6375 |
+ fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec); |
6376 |
+ fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); |
6377 |
+@@ -1235,16 +1308,25 @@ leave: |
6378 |
+ void ocfs2_refresh_inode(struct inode *inode, |
6379 |
+ struct ocfs2_dinode *fe) |
6380 |
+ { |
6381 |
++ uid_t uid; |
6382 |
++ gid_t gid; |
6383 |
++ |
6384 |
+ spin_lock(&OCFS2_I(inode)->ip_lock); |
6385 |
+ |
6386 |
+ OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); |
6387 |
+ OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr); |
6388 |
++ /* OCFS2_I(inode)->ip_flags &= ~OCFS2_FL_MASK; |
6389 |
++ OCFS2_I(inode)->ip_flags |= le32_to_cpu(fe->i_flags) & OCFS2_FL_MASK; */ |
6390 |
+ OCFS2_I(inode)->ip_dyn_features = le16_to_cpu(fe->i_dyn_features); |
6391 |
+ ocfs2_set_inode_flags(inode); |
6392 |
+ i_size_write(inode, le64_to_cpu(fe->i_size)); |
6393 |
+ inode->i_nlink = le16_to_cpu(fe->i_links_count); |
6394 |
+- inode->i_uid = le32_to_cpu(fe->i_uid); |
6395 |
+- inode->i_gid = le32_to_cpu(fe->i_gid); |
6396 |
++ uid = le32_to_cpu(fe->i_uid); |
6397 |
++ gid = le32_to_cpu(fe->i_gid); |
6398 |
++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid); |
6399 |
++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid); |
6400 |
++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid, |
6401 |
++ /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0); |
6402 |
+ inode->i_mode = le16_to_cpu(fe->i_mode); |
6403 |
+ if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0) |
6404 |
+ inode->i_blocks = 0; |
6405 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/inode.h linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/inode.h |
6406 |
+--- linux-2.6.29.4/fs/ocfs2/inode.h 2009-03-24 14:22:27.000000000 +0100 |
6407 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/inode.h 2009-03-24 14:48:35.000000000 +0100 |
6408 |
+@@ -147,6 +147,7 @@ struct buffer_head *ocfs2_bread(struct i |
6409 |
+ |
6410 |
+ void ocfs2_set_inode_flags(struct inode *inode); |
6411 |
+ void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi); |
6412 |
++int ocfs2_sync_flags(struct inode *inode); |
6413 |
+ |
6414 |
+ static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode) |
6415 |
+ { |
6416 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/ioctl.c linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/ioctl.c |
6417 |
+--- linux-2.6.29.4/fs/ocfs2/ioctl.c 2008-12-25 00:26:37.000000000 +0100 |
6418 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/ioctl.c 2009-02-22 22:54:25.000000000 +0100 |
6419 |
+@@ -42,7 +42,7 @@ static int ocfs2_get_inode_attr(struct i |
6420 |
+ return status; |
6421 |
+ } |
6422 |
+ |
6423 |
+-static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, |
6424 |
++int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, |
6425 |
+ unsigned mask) |
6426 |
+ { |
6427 |
+ struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode); |
6428 |
+@@ -67,6 +67,11 @@ static int ocfs2_set_inode_attr(struct i |
6429 |
+ if (!S_ISDIR(inode->i_mode)) |
6430 |
+ flags &= ~OCFS2_DIRSYNC_FL; |
6431 |
+ |
6432 |
++ if (IS_BARRIER(inode)) { |
6433 |
++ vxwprintk_task(1, "messing with the barrier."); |
6434 |
++ goto bail_unlock; |
6435 |
++ } |
6436 |
++ |
6437 |
+ handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
6438 |
+ if (IS_ERR(handle)) { |
6439 |
+ status = PTR_ERR(handle); |
6440 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/ioctl.h linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/ioctl.h |
6441 |
+--- linux-2.6.29.4/fs/ocfs2/ioctl.h 2008-12-25 00:26:37.000000000 +0100 |
6442 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/ioctl.h 2009-02-22 22:54:25.000000000 +0100 |
6443 |
+@@ -10,6 +10,9 @@ |
6444 |
+ #ifndef OCFS2_IOCTL_H |
6445 |
+ #define OCFS2_IOCTL_H |
6446 |
+ |
6447 |
++int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, |
6448 |
++ unsigned mask); |
6449 |
++ |
6450 |
+ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); |
6451 |
+ long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg); |
6452 |
+ |
6453 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/namei.c linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/namei.c |
6454 |
+--- linux-2.6.29.4/fs/ocfs2/namei.c 2009-03-24 14:22:27.000000000 +0100 |
6455 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/namei.c 2009-03-25 01:04:31.000000000 +0100 |
6456 |
+@@ -41,6 +41,7 @@ |
6457 |
+ #include <linux/slab.h> |
6458 |
+ #include <linux/highmem.h> |
6459 |
+ #include <linux/quotaops.h> |
6460 |
++#include <linux/vs_tag.h> |
6461 |
+ |
6462 |
+ #define MLOG_MASK_PREFIX ML_NAMEI |
6463 |
+ #include <cluster/masklog.h> |
6464 |
+@@ -462,6 +463,7 @@ static int ocfs2_mknod_locked(struct ocf |
6465 |
+ struct ocfs2_extent_list *fel; |
6466 |
+ u64 fe_blkno = 0; |
6467 |
+ u16 suballoc_bit; |
6468 |
++ tag_t tag; |
6469 |
+ |
6470 |
+ mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, |
6471 |
+ inode->i_mode, (unsigned long)dev, dentry->d_name.len, |
6472 |
+@@ -508,8 +510,11 @@ static int ocfs2_mknod_locked(struct ocf |
6473 |
+ fe->i_blkno = cpu_to_le64(fe_blkno); |
6474 |
+ fe->i_suballoc_bit = cpu_to_le16(suballoc_bit); |
6475 |
+ fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot); |
6476 |
+- fe->i_uid = cpu_to_le32(inode->i_uid); |
6477 |
+- fe->i_gid = cpu_to_le32(inode->i_gid); |
6478 |
++ |
6479 |
++ tag = dx_current_fstag(osb->sb); |
6480 |
++ fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode), inode->i_uid, tag)); |
6481 |
++ fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode), inode->i_gid, tag)); |
6482 |
++ inode->i_tag = tag; |
6483 |
+ fe->i_mode = cpu_to_le16(inode->i_mode); |
6484 |
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) |
6485 |
+ fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev)); |
6486 |
+@@ -2025,6 +2030,7 @@ const struct inode_operations ocfs2_dir_ |
6487 |
+ .rename = ocfs2_rename, |
6488 |
+ .setattr = ocfs2_setattr, |
6489 |
+ .getattr = ocfs2_getattr, |
6490 |
++ .sync_flags = ocfs2_sync_flags, |
6491 |
+ .permission = ocfs2_permission, |
6492 |
+ .setxattr = generic_setxattr, |
6493 |
+ .getxattr = generic_getxattr, |
6494 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/ocfs2_fs.h linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/ocfs2_fs.h |
6495 |
+--- linux-2.6.29.4/fs/ocfs2/ocfs2_fs.h 2009-03-24 14:22:27.000000000 +0100 |
6496 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/ocfs2_fs.h 2009-03-24 14:48:35.000000000 +0100 |
6497 |
+@@ -219,18 +219,23 @@ |
6498 |
+ #define OCFS2_INDEXED_DIR_FL (0x0008) |
6499 |
+ |
6500 |
+ /* Inode attributes, keep in sync with EXT2 */ |
6501 |
+-#define OCFS2_SECRM_FL (0x00000001) /* Secure deletion */ |
6502 |
+-#define OCFS2_UNRM_FL (0x00000002) /* Undelete */ |
6503 |
+-#define OCFS2_COMPR_FL (0x00000004) /* Compress file */ |
6504 |
+-#define OCFS2_SYNC_FL (0x00000008) /* Synchronous updates */ |
6505 |
+-#define OCFS2_IMMUTABLE_FL (0x00000010) /* Immutable file */ |
6506 |
+-#define OCFS2_APPEND_FL (0x00000020) /* writes to file may only append */ |
6507 |
+-#define OCFS2_NODUMP_FL (0x00000040) /* do not dump file */ |
6508 |
+-#define OCFS2_NOATIME_FL (0x00000080) /* do not update atime */ |
6509 |
+-#define OCFS2_DIRSYNC_FL (0x00010000) /* dirsync behaviour (directories only) */ |
6510 |
++#define OCFS2_SECRM_FL FS_SECRM_FL /* Secure deletion */ |
6511 |
++#define OCFS2_UNRM_FL FS_UNRM_FL /* Undelete */ |
6512 |
++#define OCFS2_COMPR_FL FS_COMPR_FL /* Compress file */ |
6513 |
++#define OCFS2_SYNC_FL FS_SYNC_FL /* Synchronous updates */ |
6514 |
++#define OCFS2_IMMUTABLE_FL FS_IMMUTABLE_FL /* Immutable file */ |
6515 |
++#define OCFS2_APPEND_FL FS_APPEND_FL /* writes to file may only append */ |
6516 |
++#define OCFS2_NODUMP_FL FS_NODUMP_FL /* do not dump file */ |
6517 |
++#define OCFS2_NOATIME_FL FS_NOATIME_FL /* do not update atime */ |
6518 |
+ |
6519 |
+-#define OCFS2_FL_VISIBLE (0x000100FF) /* User visible flags */ |
6520 |
+-#define OCFS2_FL_MODIFIABLE (0x000100FF) /* User modifiable flags */ |
6521 |
++#define OCFS2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */ |
6522 |
++#define OCFS2_IXUNLINK_FL FS_IXUNLINK_FL /* Immutable invert on unlink */ |
6523 |
++ |
6524 |
++#define OCFS2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */ |
6525 |
++#define OCFS2_COW_FL FS_COW_FL /* Copy on Write marker */ |
6526 |
++ |
6527 |
++#define OCFS2_FL_VISIBLE (0x010300FF) /* User visible flags */ |
6528 |
++#define OCFS2_FL_MODIFIABLE (0x010300FF) /* User modifiable flags */ |
6529 |
+ |
6530 |
+ /* |
6531 |
+ * Extent record flags (e_node.leaf.flags) |
6532 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/ocfs2.h linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/ocfs2.h |
6533 |
+--- linux-2.6.29.4/fs/ocfs2/ocfs2.h 2009-03-24 14:22:27.000000000 +0100 |
6534 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/ocfs2.h 2009-03-24 16:18:22.000000000 +0100 |
6535 |
+@@ -199,6 +199,7 @@ enum ocfs2_mount_options |
6536 |
+ OCFS2_MOUNT_POSIX_ACL = 1 << 8, /* POSIX access control lists */ |
6537 |
+ OCFS2_MOUNT_USRQUOTA = 1 << 9, /* We support user quotas */ |
6538 |
+ OCFS2_MOUNT_GRPQUOTA = 1 << 10, /* We support group quotas */ |
6539 |
++ OCFS2_MOUNT_TAGGED = 1 << 11, /* use tagging */ |
6540 |
+ }; |
6541 |
+ |
6542 |
+ #define OCFS2_OSB_SOFT_RO 0x0001 |
6543 |
+diff -NurpP --minimal linux-2.6.29.4/fs/ocfs2/super.c linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/super.c |
6544 |
+--- linux-2.6.29.4/fs/ocfs2/super.c 2009-03-24 14:22:27.000000000 +0100 |
6545 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/ocfs2/super.c 2009-03-24 16:19:44.000000000 +0100 |
6546 |
+@@ -172,6 +172,7 @@ enum { |
6547 |
+ Opt_noacl, |
6548 |
+ Opt_usrquota, |
6549 |
+ Opt_grpquota, |
6550 |
++ Opt_tag, Opt_notag, Opt_tagid, |
6551 |
+ Opt_err, |
6552 |
+ }; |
6553 |
+ |
6554 |
+@@ -198,6 +199,9 @@ static const match_table_t tokens = { |
6555 |
+ {Opt_noacl, "noacl"}, |
6556 |
+ {Opt_usrquota, "usrquota"}, |
6557 |
+ {Opt_grpquota, "grpquota"}, |
6558 |
++ {Opt_tag, "tag"}, |
6559 |
++ {Opt_notag, "notag"}, |
6560 |
++ {Opt_tagid, "tagid=%u"}, |
6561 |
+ {Opt_err, NULL} |
6562 |
+ }; |
6563 |
+ |
6564 |
+@@ -436,6 +440,13 @@ static int ocfs2_remount(struct super_bl |
6565 |
+ goto out; |
6566 |
+ } |
6567 |
+ |
6568 |
++ if ((parsed_options.mount_opt & OCFS2_MOUNT_TAGGED) && |
6569 |
++ !(sb->s_flags & MS_TAGGED)) { |
6570 |
++ ret = -EINVAL; |
6571 |
++ mlog(ML_ERROR, "Cannot change tagging on remount\n"); |
6572 |
++ goto out; |
6573 |
++ } |
6574 |
++ |
6575 |
+ if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) != |
6576 |
+ (parsed_options.mount_opt & OCFS2_MOUNT_HB_LOCAL)) { |
6577 |
+ ret = -EINVAL; |
6578 |
+@@ -950,6 +961,9 @@ static int ocfs2_fill_super(struct super |
6579 |
+ |
6580 |
+ ocfs2_complete_mount_recovery(osb); |
6581 |
+ |
6582 |
++ if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED) |
6583 |
++ sb->s_flags |= MS_TAGGED; |
6584 |
++ |
6585 |
+ if (ocfs2_mount_local(osb)) |
6586 |
+ snprintf(nodestr, sizeof(nodestr), "local"); |
6587 |
+ else |
6588 |
+@@ -1208,6 +1222,20 @@ static int ocfs2_parse_options(struct su |
6589 |
+ printk(KERN_INFO "ocfs2 (no)acl options not supported\n"); |
6590 |
+ break; |
6591 |
+ #endif |
6592 |
++#ifndef CONFIG_TAGGING_NONE |
6593 |
++ case Opt_tag: |
6594 |
++ mopt->mount_opt |= OCFS2_MOUNT_TAGGED; |
6595 |
++ break; |
6596 |
++ case Opt_notag: |
6597 |
++ mopt->mount_opt &= ~OCFS2_MOUNT_TAGGED; |
6598 |
++ break; |
6599 |
++#endif |
6600 |
++#ifdef CONFIG_PROPAGATE |
6601 |
++ case Opt_tagid: |
6602 |
++ /* use args[0] */ |
6603 |
++ mopt->mount_opt |= OCFS2_MOUNT_TAGGED; |
6604 |
++ break; |
6605 |
++#endif |
6606 |
+ default: |
6607 |
+ mlog(ML_ERROR, |
6608 |
+ "Unrecognized mount option \"%s\" " |
6609 |
+diff -NurpP --minimal linux-2.6.29.4/fs/open.c linux-2.6.29.4-vs2.3.0.36.14/fs/open.c |
6610 |
+--- linux-2.6.29.4/fs/open.c 2009-03-24 14:22:27.000000000 +0100 |
6611 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/open.c 2009-03-24 14:48:35.000000000 +0100 |
6612 |
+@@ -29,22 +29,31 @@ |
6613 |
+ #include <linux/rcupdate.h> |
6614 |
+ #include <linux/audit.h> |
6615 |
+ #include <linux/falloc.h> |
6616 |
++#include <linux/vs_base.h> |
6617 |
++#include <linux/vs_limit.h> |
6618 |
++#include <linux/vs_dlimit.h> |
6619 |
++#include <linux/vs_tag.h> |
6620 |
++#include <linux/vs_cowbl.h> |
6621 |
+ |
6622 |
+ int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
6623 |
+ { |
6624 |
+ int retval = -ENODEV; |
6625 |
+ |
6626 |
+ if (dentry) { |
6627 |
++ struct super_block *sb = dentry->d_sb; |
6628 |
++ |
6629 |
+ retval = -ENOSYS; |
6630 |
+- if (dentry->d_sb->s_op->statfs) { |
6631 |
++ if (sb->s_op->statfs) { |
6632 |
+ memset(buf, 0, sizeof(*buf)); |
6633 |
+ retval = security_sb_statfs(dentry); |
6634 |
+ if (retval) |
6635 |
+ return retval; |
6636 |
+- retval = dentry->d_sb->s_op->statfs(dentry, buf); |
6637 |
++ retval = sb->s_op->statfs(dentry, buf); |
6638 |
+ if (retval == 0 && buf->f_frsize == 0) |
6639 |
+ buf->f_frsize = buf->f_bsize; |
6640 |
+ } |
6641 |
++ if (!vx_check(0, VS_ADMIN|VS_WATCH)) |
6642 |
++ vx_vsi_statfs(sb, buf); |
6643 |
+ } |
6644 |
+ return retval; |
6645 |
+ } |
6646 |
+@@ -638,6 +647,10 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, cons |
6647 |
+ error = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path); |
6648 |
+ if (error) |
6649 |
+ goto out; |
6650 |
++ |
6651 |
++ error = cow_check_and_break(&path); |
6652 |
++ if (error) |
6653 |
++ goto dput_and_out; |
6654 |
+ inode = path.dentry->d_inode; |
6655 |
+ |
6656 |
+ error = mnt_want_write(path.mnt); |
6657 |
+@@ -671,11 +684,11 @@ static int chown_common(struct dentry * |
6658 |
+ newattrs.ia_valid = ATTR_CTIME; |
6659 |
+ if (user != (uid_t) -1) { |
6660 |
+ newattrs.ia_valid |= ATTR_UID; |
6661 |
+- newattrs.ia_uid = user; |
6662 |
++ newattrs.ia_uid = dx_map_uid(user); |
6663 |
+ } |
6664 |
+ if (group != (gid_t) -1) { |
6665 |
+ newattrs.ia_valid |= ATTR_GID; |
6666 |
+- newattrs.ia_gid = group; |
6667 |
++ newattrs.ia_gid = dx_map_gid(group); |
6668 |
+ } |
6669 |
+ if (!S_ISDIR(inode->i_mode)) |
6670 |
+ newattrs.ia_valid |= |
6671 |
+@@ -698,7 +711,11 @@ SYSCALL_DEFINE3(chown, const char __user |
6672 |
+ error = mnt_want_write(path.mnt); |
6673 |
+ if (error) |
6674 |
+ goto out_release; |
6675 |
+- error = chown_common(path.dentry, user, group); |
6676 |
++#ifdef CONFIG_VSERVER_COWBL |
6677 |
++ error = cow_check_and_break(&path); |
6678 |
++ if (!error) |
6679 |
++#endif |
6680 |
++ error = chown_common(path.dentry, user, group); |
6681 |
+ mnt_drop_write(path.mnt); |
6682 |
+ out_release: |
6683 |
+ path_put(&path); |
6684 |
+@@ -723,7 +740,11 @@ SYSCALL_DEFINE5(fchownat, int, dfd, cons |
6685 |
+ error = mnt_want_write(path.mnt); |
6686 |
+ if (error) |
6687 |
+ goto out_release; |
6688 |
+- error = chown_common(path.dentry, user, group); |
6689 |
++#ifdef CONFIG_VSERVER_COWBL |
6690 |
++ error = cow_check_and_break(&path); |
6691 |
++ if (!error) |
6692 |
++#endif |
6693 |
++ error = chown_common(path.dentry, user, group); |
6694 |
+ mnt_drop_write(path.mnt); |
6695 |
+ out_release: |
6696 |
+ path_put(&path); |
6697 |
+@@ -742,7 +763,11 @@ SYSCALL_DEFINE3(lchown, const char __use |
6698 |
+ error = mnt_want_write(path.mnt); |
6699 |
+ if (error) |
6700 |
+ goto out_release; |
6701 |
+- error = chown_common(path.dentry, user, group); |
6702 |
++#ifdef CONFIG_VSERVER_COWBL |
6703 |
++ error = cow_check_and_break(&path); |
6704 |
++ if (!error) |
6705 |
++#endif |
6706 |
++ error = chown_common(path.dentry, user, group); |
6707 |
+ mnt_drop_write(path.mnt); |
6708 |
+ out_release: |
6709 |
+ path_put(&path); |
6710 |
+@@ -986,6 +1011,7 @@ static void __put_unused_fd(struct files |
6711 |
+ __FD_CLR(fd, fdt->open_fds); |
6712 |
+ if (fd < files->next_fd) |
6713 |
+ files->next_fd = fd; |
6714 |
++ vx_openfd_dec(fd); |
6715 |
+ } |
6716 |
+ |
6717 |
+ void put_unused_fd(unsigned int fd) |
6718 |
+diff -NurpP --minimal linux-2.6.29.4/fs/proc/array.c linux-2.6.29.4-vs2.3.0.36.14/fs/proc/array.c |
6719 |
+--- linux-2.6.29.4/fs/proc/array.c 2009-05-23 23:16:53.000000000 +0200 |
6720 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/proc/array.c 2009-05-10 23:42:01.000000000 +0200 |
6721 |
+@@ -82,6 +82,8 @@ |
6722 |
+ #include <linux/pid_namespace.h> |
6723 |
+ #include <linux/ptrace.h> |
6724 |
+ #include <linux/tracehook.h> |
6725 |
++#include <linux/vs_context.h> |
6726 |
++#include <linux/vs_network.h> |
6727 |
+ |
6728 |
+ #include <asm/pgtable.h> |
6729 |
+ #include <asm/processor.h> |
6730 |
+@@ -138,8 +140,9 @@ static const char *task_state_array[] = |
6731 |
+ "D (disk sleep)", /* 2 */ |
6732 |
+ "T (stopped)", /* 4 */ |
6733 |
+ "T (tracing stop)", /* 8 */ |
6734 |
+- "Z (zombie)", /* 16 */ |
6735 |
+- "X (dead)" /* 32 */ |
6736 |
++ "H (on hold)", /* 16 */ |
6737 |
++ "Z (zombie)", /* 32 */ |
6738 |
++ "X (dead)", /* 64 */ |
6739 |
+ }; |
6740 |
+ |
6741 |
+ static inline const char *get_task_state(struct task_struct *tsk) |
6742 |
+@@ -166,6 +169,9 @@ static inline void task_state(struct seq |
6743 |
+ rcu_read_lock(); |
6744 |
+ ppid = pid_alive(p) ? |
6745 |
+ task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; |
6746 |
++ if (unlikely(vx_current_initpid(p->pid))) |
6747 |
++ ppid = 0; |
6748 |
++ |
6749 |
+ tpid = 0; |
6750 |
+ if (pid_alive(p)) { |
6751 |
+ struct task_struct *tracer = tracehook_tracer_task(p); |
6752 |
+@@ -281,7 +287,7 @@ static inline void task_sig(struct seq_f |
6753 |
+ } |
6754 |
+ |
6755 |
+ static void render_cap_t(struct seq_file *m, const char *header, |
6756 |
+- kernel_cap_t *a) |
6757 |
++ struct vx_info *vxi, kernel_cap_t *a) |
6758 |
+ { |
6759 |
+ unsigned __capi; |
6760 |
+ |
6761 |
+@@ -306,10 +312,11 @@ static inline void task_cap(struct seq_f |
6762 |
+ cap_bset = cred->cap_bset; |
6763 |
+ rcu_read_unlock(); |
6764 |
+ |
6765 |
+- render_cap_t(m, "CapInh:\t", &cap_inheritable); |
6766 |
+- render_cap_t(m, "CapPrm:\t", &cap_permitted); |
6767 |
+- render_cap_t(m, "CapEff:\t", &cap_effective); |
6768 |
+- render_cap_t(m, "CapBnd:\t", &cap_bset); |
6769 |
++ /* FIXME: maybe move the p->vx_info masking to __task_cred() ? */ |
6770 |
++ render_cap_t(m, "CapInh:\t", p->vx_info, &cap_inheritable); |
6771 |
++ render_cap_t(m, "CapPrm:\t", p->vx_info, &cap_permitted); |
6772 |
++ render_cap_t(m, "CapEff:\t", p->vx_info, &cap_effective); |
6773 |
++ render_cap_t(m, "CapBnd:\t", p->vx_info, &cap_bset); |
6774 |
+ } |
6775 |
+ |
6776 |
+ static inline void task_context_switch_counts(struct seq_file *m, |
6777 |
+@@ -321,6 +328,42 @@ static inline void task_context_switch_c |
6778 |
+ p->nivcsw); |
6779 |
+ } |
6780 |
+ |
6781 |
++int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns, |
6782 |
++ struct pid *pid, struct task_struct *task) |
6783 |
++{ |
6784 |
++ seq_printf(m, "Proxy:\t%p(%c)\n" |
6785 |
++ "Count:\t%u\n" |
6786 |
++ "uts:\t%p(%c)\n" |
6787 |
++ "ipc:\t%p(%c)\n" |
6788 |
++ "mnt:\t%p(%c)\n" |
6789 |
++ "pid:\t%p(%c)\n" |
6790 |
++ "net:\t%p(%c)\n", |
6791 |
++ task->nsproxy, |
6792 |
++ (task->nsproxy == init_task.nsproxy ? 'I' : '-'), |
6793 |
++ atomic_read(&task->nsproxy->count), |
6794 |
++ task->nsproxy->uts_ns, |
6795 |
++ (task->nsproxy->uts_ns == init_task.nsproxy->uts_ns ? 'I' : '-'), |
6796 |
++ task->nsproxy->ipc_ns, |
6797 |
++ (task->nsproxy->ipc_ns == init_task.nsproxy->ipc_ns ? 'I' : '-'), |
6798 |
++ task->nsproxy->mnt_ns, |
6799 |
++ (task->nsproxy->mnt_ns == init_task.nsproxy->mnt_ns ? 'I' : '-'), |
6800 |
++ task->nsproxy->pid_ns, |
6801 |
++ (task->nsproxy->pid_ns == init_task.nsproxy->pid_ns ? 'I' : '-'), |
6802 |
++ task->nsproxy->net_ns, |
6803 |
++ (task->nsproxy->net_ns == init_task.nsproxy->net_ns ? 'I' : '-')); |
6804 |
++ return 0; |
6805 |
++} |
6806 |
++ |
6807 |
++void task_vs_id(struct seq_file *m, struct task_struct *task) |
6808 |
++{ |
6809 |
++ if (task_vx_flags(task, VXF_HIDE_VINFO, 0)) |
6810 |
++ return; |
6811 |
++ |
6812 |
++ seq_printf(m, "VxID: %d\n", vx_task_xid(task)); |
6813 |
++ seq_printf(m, "NxID: %d\n", nx_task_nid(task)); |
6814 |
++} |
6815 |
++ |
6816 |
++ |
6817 |
+ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, |
6818 |
+ struct pid *pid, struct task_struct *task) |
6819 |
+ { |
6820 |
+@@ -336,6 +379,7 @@ int proc_pid_status(struct seq_file *m, |
6821 |
+ task_sig(m, task); |
6822 |
+ task_cap(m, task); |
6823 |
+ cpuset_task_status_allowed(m, task); |
6824 |
++ task_vs_id(m, task); |
6825 |
+ #if defined(CONFIG_S390) |
6826 |
+ task_show_regs(m, task); |
6827 |
+ #endif |
6828 |
+@@ -452,6 +496,17 @@ static int do_task_stat(struct seq_file |
6829 |
+ /* convert nsec -> ticks */ |
6830 |
+ start_time = nsec_to_clock_t(start_time); |
6831 |
+ |
6832 |
++ /* fixup start time for virt uptime */ |
6833 |
++ if (vx_flags(VXF_VIRT_UPTIME, 0)) { |
6834 |
++ unsigned long long bias = |
6835 |
++ current->vx_info->cvirt.bias_clock; |
6836 |
++ |
6837 |
++ if (start_time > bias) |
6838 |
++ start_time -= bias; |
6839 |
++ else |
6840 |
++ start_time = 0; |
6841 |
++ } |
6842 |
++ |
6843 |
+ seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \ |
6844 |
+ %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ |
6845 |
+ %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n", |
6846 |
+diff -NurpP --minimal linux-2.6.29.4/fs/proc/base.c linux-2.6.29.4-vs2.3.0.36.14/fs/proc/base.c |
6847 |
+--- linux-2.6.29.4/fs/proc/base.c 2009-05-23 23:16:53.000000000 +0200 |
6848 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/proc/base.c 2009-05-10 23:42:01.000000000 +0200 |
6849 |
+@@ -80,6 +80,8 @@ |
6850 |
+ #include <linux/oom.h> |
6851 |
+ #include <linux/elf.h> |
6852 |
+ #include <linux/pid_namespace.h> |
6853 |
++#include <linux/vs_context.h> |
6854 |
++#include <linux/vs_network.h> |
6855 |
+ #include "internal.h" |
6856 |
+ |
6857 |
+ /* NOTE: |
6858 |
+@@ -1443,6 +1445,8 @@ static struct inode *proc_pid_make_inode |
6859 |
+ inode->i_gid = cred->egid; |
6860 |
+ rcu_read_unlock(); |
6861 |
+ } |
6862 |
++ /* procfs is xid tagged */ |
6863 |
++ inode->i_tag = (tag_t)vx_task_xid(task); |
6864 |
+ security_task_to_inode(task, inode); |
6865 |
+ |
6866 |
+ out: |
6867 |
+@@ -1993,6 +1997,13 @@ static struct dentry *proc_pident_lookup |
6868 |
+ if (!task) |
6869 |
+ goto out_no_task; |
6870 |
+ |
6871 |
++ /* TODO: maybe we can come up with a generic approach? */ |
6872 |
++ if (task_vx_flags(task, VXF_HIDE_VINFO, 0) && |
6873 |
++ (dentry->d_name.len == 5) && |
6874 |
++ (!memcmp(dentry->d_name.name, "vinfo", 5) || |
6875 |
++ !memcmp(dentry->d_name.name, "ninfo", 5))) |
6876 |
++ goto out; |
6877 |
++ |
6878 |
+ /* |
6879 |
+ * Yes, it does not scale. And it should not. Don't add |
6880 |
+ * new entries into /proc/<tgid>/ without very good reasons. |
6881 |
+@@ -2378,7 +2389,7 @@ out_iput: |
6882 |
+ static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) |
6883 |
+ { |
6884 |
+ struct dentry *error; |
6885 |
+- struct task_struct *task = get_proc_task(dir); |
6886 |
++ struct task_struct *task = get_proc_task_real(dir); |
6887 |
+ const struct pid_entry *p, *last; |
6888 |
+ |
6889 |
+ error = ERR_PTR(-ENOENT); |
6890 |
+@@ -2468,6 +2479,9 @@ static int proc_pid_personality(struct s |
6891 |
+ static const struct file_operations proc_task_operations; |
6892 |
+ static const struct inode_operations proc_task_inode_operations; |
6893 |
+ |
6894 |
++extern int proc_pid_vx_info(struct task_struct *, char *); |
6895 |
++extern int proc_pid_nx_info(struct task_struct *, char *); |
6896 |
++ |
6897 |
+ static const struct pid_entry tgid_base_stuff[] = { |
6898 |
+ DIR("task", S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations), |
6899 |
+ DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations), |
6900 |
+@@ -2526,6 +2540,8 @@ static const struct pid_entry tgid_base_ |
6901 |
+ #ifdef CONFIG_CGROUPS |
6902 |
+ REG("cgroup", S_IRUGO, proc_cgroup_operations), |
6903 |
+ #endif |
6904 |
++ INF("vinfo", S_IRUGO, proc_pid_vx_info), |
6905 |
++ INF("ninfo", S_IRUGO, proc_pid_nx_info), |
6906 |
+ INF("oom_score", S_IRUGO, proc_oom_score), |
6907 |
+ REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations), |
6908 |
+ #ifdef CONFIG_AUDITSYSCALL |
6909 |
+@@ -2541,6 +2557,7 @@ static const struct pid_entry tgid_base_ |
6910 |
+ #ifdef CONFIG_TASK_IO_ACCOUNTING |
6911 |
+ INF("io", S_IRUGO, proc_tgid_io_accounting), |
6912 |
+ #endif |
6913 |
++ ONE("nsproxy", S_IRUGO, proc_pid_nsproxy), |
6914 |
+ }; |
6915 |
+ |
6916 |
+ static int proc_tgid_base_readdir(struct file * filp, |
6917 |
+@@ -2737,7 +2754,7 @@ retry: |
6918 |
+ iter.task = NULL; |
6919 |
+ pid = find_ge_pid(iter.tgid, ns); |
6920 |
+ if (pid) { |
6921 |
+- iter.tgid = pid_nr_ns(pid, ns); |
6922 |
++ iter.tgid = pid_unmapped_nr_ns(pid, ns); |
6923 |
+ iter.task = pid_task(pid, PIDTYPE_PID); |
6924 |
+ /* What we to know is if the pid we have find is the |
6925 |
+ * pid of a thread_group_leader. Testing for task |
6926 |
+@@ -2767,7 +2784,7 @@ static int proc_pid_fill_cache(struct fi |
6927 |
+ struct tgid_iter iter) |
6928 |
+ { |
6929 |
+ char name[PROC_NUMBUF]; |
6930 |
+- int len = snprintf(name, sizeof(name), "%d", iter.tgid); |
6931 |
++ int len = snprintf(name, sizeof(name), "%d", vx_map_tgid(iter.tgid)); |
6932 |
+ return proc_fill_cache(filp, dirent, filldir, name, len, |
6933 |
+ proc_pid_instantiate, iter.task, NULL); |
6934 |
+ } |
6935 |
+@@ -2776,7 +2793,7 @@ static int proc_pid_fill_cache(struct fi |
6936 |
+ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) |
6937 |
+ { |
6938 |
+ unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; |
6939 |
+- struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); |
6940 |
++ struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode); |
6941 |
+ struct tgid_iter iter; |
6942 |
+ struct pid_namespace *ns; |
6943 |
+ |
6944 |
+@@ -2796,6 +2813,8 @@ int proc_pid_readdir(struct file * filp, |
6945 |
+ iter.task; |
6946 |
+ iter.tgid += 1, iter = next_tgid(ns, iter)) { |
6947 |
+ filp->f_pos = iter.tgid + TGID_OFFSET; |
6948 |
++ if (!vx_proc_task_visible(iter.task)) |
6949 |
++ continue; |
6950 |
+ if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) { |
6951 |
+ put_task_struct(iter.task); |
6952 |
+ goto out; |
6953 |
+@@ -2942,6 +2961,8 @@ static struct dentry *proc_task_lookup(s |
6954 |
+ tid = name_to_int(dentry); |
6955 |
+ if (tid == ~0U) |
6956 |
+ goto out; |
6957 |
++ if (vx_current_initpid(tid)) |
6958 |
++ goto out; |
6959 |
+ |
6960 |
+ ns = dentry->d_sb->s_fs_info; |
6961 |
+ rcu_read_lock(); |
6962 |
+diff -NurpP --minimal linux-2.6.29.4/fs/proc/generic.c linux-2.6.29.4-vs2.3.0.36.14/fs/proc/generic.c |
6963 |
+--- linux-2.6.29.4/fs/proc/generic.c 2009-03-24 14:22:27.000000000 +0100 |
6964 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/proc/generic.c 2009-03-24 14:48:35.000000000 +0100 |
6965 |
+@@ -20,6 +20,7 @@ |
6966 |
+ #include <linux/bitops.h> |
6967 |
+ #include <linux/spinlock.h> |
6968 |
+ #include <linux/completion.h> |
6969 |
++#include <linux/vserver/inode.h> |
6970 |
+ #include <asm/uaccess.h> |
6971 |
+ |
6972 |
+ #include "internal.h" |
6973 |
+@@ -382,6 +383,8 @@ struct dentry *proc_lookup_de(struct pro |
6974 |
+ for (de = de->subdir; de ; de = de->next) { |
6975 |
+ if (de->namelen != dentry->d_name.len) |
6976 |
+ continue; |
6977 |
++ if (!vx_hide_check(0, de->vx_flags)) |
6978 |
++ continue; |
6979 |
+ if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { |
6980 |
+ unsigned int ino; |
6981 |
+ |
6982 |
+@@ -390,6 +393,8 @@ struct dentry *proc_lookup_de(struct pro |
6983 |
+ spin_unlock(&proc_subdir_lock); |
6984 |
+ error = -EINVAL; |
6985 |
+ inode = proc_get_inode(dir->i_sb, ino, de); |
6986 |
++ /* generic proc entries belong to the host */ |
6987 |
++ inode->i_tag = 0; |
6988 |
+ goto out_unlock; |
6989 |
+ } |
6990 |
+ } |
6991 |
+@@ -467,6 +472,8 @@ int proc_readdir_de(struct proc_dir_entr |
6992 |
+ |
6993 |
+ /* filldir passes info to user space */ |
6994 |
+ de_get(de); |
6995 |
++ if (!vx_hide_check(0, de->vx_flags)) |
6996 |
++ goto skip; |
6997 |
+ spin_unlock(&proc_subdir_lock); |
6998 |
+ if (filldir(dirent, de->name, de->namelen, filp->f_pos, |
6999 |
+ de->low_ino, de->mode >> 12) < 0) { |
7000 |
+@@ -474,6 +481,7 @@ int proc_readdir_de(struct proc_dir_entr |
7001 |
+ goto out; |
7002 |
+ } |
7003 |
+ spin_lock(&proc_subdir_lock); |
7004 |
++ skip: |
7005 |
+ filp->f_pos++; |
7006 |
+ next = de->next; |
7007 |
+ de_put(de); |
7008 |
+@@ -588,6 +596,7 @@ static struct proc_dir_entry *__proc_cre |
7009 |
+ ent->nlink = nlink; |
7010 |
+ atomic_set(&ent->count, 1); |
7011 |
+ ent->pde_users = 0; |
7012 |
++ ent->vx_flags = IATTR_PROC_DEFAULT; |
7013 |
+ spin_lock_init(&ent->pde_unload_lock); |
7014 |
+ ent->pde_unload_completion = NULL; |
7015 |
+ INIT_LIST_HEAD(&ent->pde_openers); |
7016 |
+@@ -611,7 +620,8 @@ struct proc_dir_entry *proc_symlink(cons |
7017 |
+ kfree(ent->data); |
7018 |
+ kfree(ent); |
7019 |
+ ent = NULL; |
7020 |
+- } |
7021 |
++ } else |
7022 |
++ ent->vx_flags = IATTR_PROC_SYMLINK; |
7023 |
+ } else { |
7024 |
+ kfree(ent); |
7025 |
+ ent = NULL; |
7026 |
+diff -NurpP --minimal linux-2.6.29.4/fs/proc/inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/proc/inode.c |
7027 |
+--- linux-2.6.29.4/fs/proc/inode.c 2009-03-24 14:22:27.000000000 +0100 |
7028 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/proc/inode.c 2009-03-24 14:48:35.000000000 +0100 |
7029 |
+@@ -465,6 +465,8 @@ struct inode *proc_get_inode(struct supe |
7030 |
+ inode->i_uid = de->uid; |
7031 |
+ inode->i_gid = de->gid; |
7032 |
+ } |
7033 |
++ if (de->vx_flags) |
7034 |
++ PROC_I(inode)->vx_flags = de->vx_flags; |
7035 |
+ if (de->size) |
7036 |
+ inode->i_size = de->size; |
7037 |
+ if (de->nlink) |
7038 |
+diff -NurpP --minimal linux-2.6.29.4/fs/proc/internal.h linux-2.6.29.4-vs2.3.0.36.14/fs/proc/internal.h |
7039 |
+--- linux-2.6.29.4/fs/proc/internal.h 2009-03-24 14:22:27.000000000 +0100 |
7040 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/proc/internal.h 2009-03-24 14:48:35.000000000 +0100 |
7041 |
+@@ -10,6 +10,7 @@ |
7042 |
+ */ |
7043 |
+ |
7044 |
+ #include <linux/proc_fs.h> |
7045 |
++#include <linux/vs_pid.h> |
7046 |
+ |
7047 |
+ extern struct proc_dir_entry proc_root; |
7048 |
+ #ifdef CONFIG_PROC_SYSCTL |
7049 |
+@@ -51,6 +52,9 @@ extern int proc_pid_status(struct seq_fi |
7050 |
+ struct pid *pid, struct task_struct *task); |
7051 |
+ extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, |
7052 |
+ struct pid *pid, struct task_struct *task); |
7053 |
++extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns, |
7054 |
++ struct pid *pid, struct task_struct *task); |
7055 |
++ |
7056 |
+ extern loff_t mem_lseek(struct file *file, loff_t offset, int orig); |
7057 |
+ |
7058 |
+ extern const struct file_operations proc_maps_operations; |
7059 |
+@@ -70,11 +74,16 @@ static inline struct pid *proc_pid(struc |
7060 |
+ return PROC_I(inode)->pid; |
7061 |
+ } |
7062 |
+ |
7063 |
+-static inline struct task_struct *get_proc_task(struct inode *inode) |
7064 |
++static inline struct task_struct *get_proc_task_real(struct inode *inode) |
7065 |
+ { |
7066 |
+ return get_pid_task(proc_pid(inode), PIDTYPE_PID); |
7067 |
+ } |
7068 |
+ |
7069 |
++static inline struct task_struct *get_proc_task(struct inode *inode) |
7070 |
++{ |
7071 |
++ return vx_get_proc_task(inode, proc_pid(inode)); |
7072 |
++} |
7073 |
++ |
7074 |
+ static inline int proc_fd(struct inode *inode) |
7075 |
+ { |
7076 |
+ return PROC_I(inode)->fd; |
7077 |
+diff -NurpP --minimal linux-2.6.29.4/fs/proc/loadavg.c linux-2.6.29.4-vs2.3.0.36.14/fs/proc/loadavg.c |
7078 |
+--- linux-2.6.29.4/fs/proc/loadavg.c 2008-12-25 00:26:37.000000000 +0100 |
7079 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/proc/loadavg.c 2009-05-20 00:24:34.000000000 +0200 |
7080 |
+@@ -12,21 +12,37 @@ |
7081 |
+ |
7082 |
+ static int loadavg_proc_show(struct seq_file *m, void *v) |
7083 |
+ { |
7084 |
++ unsigned long running; |
7085 |
++ unsigned int threads; |
7086 |
+ int a, b, c; |
7087 |
+ unsigned long seq; |
7088 |
+ |
7089 |
+ do { |
7090 |
+ seq = read_seqbegin(&xtime_lock); |
7091 |
+- a = avenrun[0] + (FIXED_1/200); |
7092 |
+- b = avenrun[1] + (FIXED_1/200); |
7093 |
+- c = avenrun[2] + (FIXED_1/200); |
7094 |
++ if (vx_flags(VXF_VIRT_LOAD, 0)) { |
7095 |
++ struct vx_info *vxi = current->vx_info; |
7096 |
++ |
7097 |
++ a = vxi->cvirt.load[0] + (FIXED_1/200); |
7098 |
++ b = vxi->cvirt.load[1] + (FIXED_1/200); |
7099 |
++ c = vxi->cvirt.load[2] + (FIXED_1/200); |
7100 |
++ |
7101 |
++ running = atomic_read(&vxi->cvirt.nr_running); |
7102 |
++ threads = atomic_read(&vxi->cvirt.nr_threads); |
7103 |
++ } else { |
7104 |
++ a = avenrun[0] + (FIXED_1/200); |
7105 |
++ b = avenrun[1] + (FIXED_1/200); |
7106 |
++ c = avenrun[2] + (FIXED_1/200); |
7107 |
++ |
7108 |
++ running = nr_running(); |
7109 |
++ threads = nr_threads; |
7110 |
++ } |
7111 |
+ } while (read_seqretry(&xtime_lock, seq)); |
7112 |
+ |
7113 |
+ seq_printf(m, "%d.%02d %d.%02d %d.%02d %ld/%d %d\n", |
7114 |
+ LOAD_INT(a), LOAD_FRAC(a), |
7115 |
+ LOAD_INT(b), LOAD_FRAC(b), |
7116 |
+ LOAD_INT(c), LOAD_FRAC(c), |
7117 |
+- nr_running(), nr_threads, |
7118 |
++ running, threads, |
7119 |
+ task_active_pid_ns(current)->last_pid); |
7120 |
+ return 0; |
7121 |
+ } |
7122 |
+diff -NurpP --minimal linux-2.6.29.4/fs/proc/meminfo.c linux-2.6.29.4-vs2.3.0.36.14/fs/proc/meminfo.c |
7123 |
+--- linux-2.6.29.4/fs/proc/meminfo.c 2009-05-23 23:16:53.000000000 +0200 |
7124 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/proc/meminfo.c 2009-05-10 23:42:01.000000000 +0200 |
7125 |
+@@ -41,7 +41,7 @@ static int meminfo_proc_show(struct seq_ |
7126 |
+ |
7127 |
+ cached = global_page_state(NR_FILE_PAGES) - |
7128 |
+ total_swapcache_pages - i.bufferram; |
7129 |
+- if (cached < 0) |
7130 |
++ if (cached < 0 || vx_flags(VXF_VIRT_MEM, 0)) |
7131 |
+ cached = 0; |
7132 |
+ |
7133 |
+ get_vmalloc_info(&vmi); |
7134 |
+diff -NurpP --minimal linux-2.6.29.4/fs/proc/root.c linux-2.6.29.4-vs2.3.0.36.14/fs/proc/root.c |
7135 |
+--- linux-2.6.29.4/fs/proc/root.c 2009-03-24 14:22:27.000000000 +0100 |
7136 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/proc/root.c 2009-03-24 14:48:35.000000000 +0100 |
7137 |
+@@ -18,9 +18,14 @@ |
7138 |
+ #include <linux/bitops.h> |
7139 |
+ #include <linux/mount.h> |
7140 |
+ #include <linux/pid_namespace.h> |
7141 |
++#include <linux/vserver/inode.h> |
7142 |
+ |
7143 |
+ #include "internal.h" |
7144 |
+ |
7145 |
++struct proc_dir_entry *proc_virtual; |
7146 |
++ |
7147 |
++extern void proc_vx_init(void); |
7148 |
++ |
7149 |
+ static int proc_test_super(struct super_block *sb, void *data) |
7150 |
+ { |
7151 |
+ return sb->s_fs_info == data; |
7152 |
+@@ -136,6 +141,7 @@ void __init proc_root_init(void) |
7153 |
+ #endif |
7154 |
+ proc_mkdir("bus", NULL); |
7155 |
+ proc_sys_init(); |
7156 |
++ proc_vx_init(); |
7157 |
+ } |
7158 |
+ |
7159 |
+ static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat |
7160 |
+@@ -203,6 +209,7 @@ struct proc_dir_entry proc_root = { |
7161 |
+ .proc_iops = &proc_root_inode_operations, |
7162 |
+ .proc_fops = &proc_root_operations, |
7163 |
+ .parent = &proc_root, |
7164 |
++ .vx_flags = IATTR_ADMIN | IATTR_WATCH, |
7165 |
+ }; |
7166 |
+ |
7167 |
+ int pid_ns_prepare_proc(struct pid_namespace *ns) |
7168 |
+diff -NurpP --minimal linux-2.6.29.4/fs/proc/uptime.c linux-2.6.29.4-vs2.3.0.36.14/fs/proc/uptime.c |
7169 |
+--- linux-2.6.29.4/fs/proc/uptime.c 2008-12-25 00:26:37.000000000 +0100 |
7170 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/proc/uptime.c 2009-02-22 22:54:25.000000000 +0100 |
7171 |
+@@ -2,6 +2,7 @@ |
7172 |
+ #include <linux/proc_fs.h> |
7173 |
+ #include <linux/sched.h> |
7174 |
+ #include <linux/time.h> |
7175 |
++#include <linux/vserver/cvirt.h> |
7176 |
+ #include <asm/cputime.h> |
7177 |
+ |
7178 |
+ static int proc_calc_metrics(char *page, char **start, off_t off, |
7179 |
+@@ -29,6 +30,10 @@ static int uptime_read_proc(char *page, |
7180 |
+ do_posix_clock_monotonic_gettime(&uptime); |
7181 |
+ monotonic_to_bootbased(&uptime); |
7182 |
+ cputime_to_timespec(idletime, &idle); |
7183 |
++ |
7184 |
++ if (vx_flags(VXF_VIRT_UPTIME, 0)) |
7185 |
++ vx_vsi_uptime(&uptime, &idle); |
7186 |
++ |
7187 |
+ len = sprintf(page, "%lu.%02lu %lu.%02lu\n", |
7188 |
+ (unsigned long) uptime.tv_sec, |
7189 |
+ (uptime.tv_nsec / (NSEC_PER_SEC / 100)), |
7190 |
+diff -NurpP --minimal linux-2.6.29.4/fs/quota.c linux-2.6.29.4-vs2.3.0.36.14/fs/quota.c |
7191 |
+--- linux-2.6.29.4/fs/quota.c 2009-03-24 14:22:27.000000000 +0100 |
7192 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/quota.c 2009-03-24 14:48:35.000000000 +0100 |
7193 |
+@@ -18,6 +18,7 @@ |
7194 |
+ #include <linux/capability.h> |
7195 |
+ #include <linux/quotaops.h> |
7196 |
+ #include <linux/types.h> |
7197 |
++#include <linux/vs_context.h> |
7198 |
+ |
7199 |
+ /* Check validity of generic quotactl commands */ |
7200 |
+ static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id) |
7201 |
+@@ -81,11 +82,11 @@ static int generic_quotactl_valid(struct |
7202 |
+ if (cmd == Q_GETQUOTA) { |
7203 |
+ if (((type == USRQUOTA && current_euid() != id) || |
7204 |
+ (type == GRPQUOTA && !in_egroup_p(id))) && |
7205 |
+- !capable(CAP_SYS_ADMIN)) |
7206 |
++ !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) |
7207 |
+ return -EPERM; |
7208 |
+ } |
7209 |
+ else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO) |
7210 |
+- if (!capable(CAP_SYS_ADMIN)) |
7211 |
++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) |
7212 |
+ return -EPERM; |
7213 |
+ |
7214 |
+ return 0; |
7215 |
+@@ -132,10 +133,10 @@ static int xqm_quotactl_valid(struct sup |
7216 |
+ if (cmd == Q_XGETQUOTA) { |
7217 |
+ if (((type == XQM_USRQUOTA && current_euid() != id) || |
7218 |
+ (type == XQM_GRPQUOTA && !in_egroup_p(id))) && |
7219 |
+- !capable(CAP_SYS_ADMIN)) |
7220 |
++ !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) |
7221 |
+ return -EPERM; |
7222 |
+ } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) { |
7223 |
+- if (!capable(CAP_SYS_ADMIN)) |
7224 |
++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) |
7225 |
+ return -EPERM; |
7226 |
+ } |
7227 |
+ |
7228 |
+@@ -337,6 +338,46 @@ static int do_quotactl(struct super_bloc |
7229 |
+ return 0; |
7230 |
+ } |
7231 |
+ |
7232 |
++#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE) |
7233 |
++ |
7234 |
++#include <linux/vroot.h> |
7235 |
++#include <linux/major.h> |
7236 |
++#include <linux/module.h> |
7237 |
++#include <linux/kallsyms.h> |
7238 |
++#include <linux/vserver/debug.h> |
7239 |
++ |
7240 |
++static vroot_grb_func *vroot_get_real_bdev = NULL; |
7241 |
++ |
7242 |
++static spinlock_t vroot_grb_lock = SPIN_LOCK_UNLOCKED; |
7243 |
++ |
7244 |
++int register_vroot_grb(vroot_grb_func *func) { |
7245 |
++ int ret = -EBUSY; |
7246 |
++ |
7247 |
++ spin_lock(&vroot_grb_lock); |
7248 |
++ if (!vroot_get_real_bdev) { |
7249 |
++ vroot_get_real_bdev = func; |
7250 |
++ ret = 0; |
7251 |
++ } |
7252 |
++ spin_unlock(&vroot_grb_lock); |
7253 |
++ return ret; |
7254 |
++} |
7255 |
++EXPORT_SYMBOL(register_vroot_grb); |
7256 |
++ |
7257 |
++int unregister_vroot_grb(vroot_grb_func *func) { |
7258 |
++ int ret = -EINVAL; |
7259 |
++ |
7260 |
++ spin_lock(&vroot_grb_lock); |
7261 |
++ if (vroot_get_real_bdev) { |
7262 |
++ vroot_get_real_bdev = NULL; |
7263 |
++ ret = 0; |
7264 |
++ } |
7265 |
++ spin_unlock(&vroot_grb_lock); |
7266 |
++ return ret; |
7267 |
++} |
7268 |
++EXPORT_SYMBOL(unregister_vroot_grb); |
7269 |
++ |
7270 |
++#endif |
7271 |
++ |
7272 |
+ /* |
7273 |
+ * look up a superblock on which quota ops will be performed |
7274 |
+ * - use the name of a block device to find the superblock thereon |
7275 |
+@@ -354,6 +395,22 @@ static inline struct super_block *quotac |
7276 |
+ putname(tmp); |
7277 |
+ if (IS_ERR(bdev)) |
7278 |
+ return ERR_CAST(bdev); |
7279 |
++#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE) |
7280 |
++ if (bdev && bdev->bd_inode && |
7281 |
++ imajor(bdev->bd_inode) == VROOT_MAJOR) { |
7282 |
++ struct block_device *bdnew = (void *)-EINVAL; |
7283 |
++ |
7284 |
++ if (vroot_get_real_bdev) |
7285 |
++ bdnew = vroot_get_real_bdev(bdev); |
7286 |
++ else |
7287 |
++ vxdprintk(VXD_CBIT(misc, 0), |
7288 |
++ "vroot_get_real_bdev not set"); |
7289 |
++ bdput(bdev); |
7290 |
++ if (IS_ERR(bdnew)) |
7291 |
++ return ERR_PTR(PTR_ERR(bdnew)); |
7292 |
++ bdev = bdnew; |
7293 |
++ } |
7294 |
++#endif |
7295 |
+ sb = get_super(bdev); |
7296 |
+ bdput(bdev); |
7297 |
+ if (!sb) |
7298 |
+diff -NurpP --minimal linux-2.6.29.4/fs/reiserfs/bitmap.c linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/bitmap.c |
7299 |
+--- linux-2.6.29.4/fs/reiserfs/bitmap.c 2008-12-25 00:26:37.000000000 +0100 |
7300 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/bitmap.c 2009-02-22 22:54:25.000000000 +0100 |
7301 |
+@@ -13,6 +13,7 @@ |
7302 |
+ #include <linux/reiserfs_fs_sb.h> |
7303 |
+ #include <linux/reiserfs_fs_i.h> |
7304 |
+ #include <linux/quotaops.h> |
7305 |
++#include <linux/vs_dlimit.h> |
7306 |
+ |
7307 |
+ #define PREALLOCATION_SIZE 9 |
7308 |
+ |
7309 |
+@@ -429,8 +430,10 @@ static void _reiserfs_free_block(struct |
7310 |
+ set_sb_free_blocks(rs, sb_free_blocks(rs) + 1); |
7311 |
+ |
7312 |
+ journal_mark_dirty(th, s, sbh); |
7313 |
+- if (for_unformatted) |
7314 |
++ if (for_unformatted) { |
7315 |
++ DLIMIT_FREE_BLOCK(inode, 1); |
7316 |
+ DQUOT_FREE_BLOCK_NODIRTY(inode, 1); |
7317 |
++ } |
7318 |
+ } |
7319 |
+ |
7320 |
+ void reiserfs_free_block(struct reiserfs_transaction_handle *th, |
7321 |
+@@ -1045,6 +1048,7 @@ static inline int blocknrs_and_prealloc_ |
7322 |
+ b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1; |
7323 |
+ int passno = 0; |
7324 |
+ int nr_allocated = 0; |
7325 |
++ int blocks; |
7326 |
+ |
7327 |
+ determine_prealloc_size(hint); |
7328 |
+ if (!hint->formatted_node) { |
7329 |
+@@ -1054,19 +1058,30 @@ static inline int blocknrs_and_prealloc_ |
7330 |
+ "reiserquota: allocating %d blocks id=%u", |
7331 |
+ amount_needed, hint->inode->i_uid); |
7332 |
+ #endif |
7333 |
+- quota_ret = |
7334 |
+- DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed); |
7335 |
+- if (quota_ret) /* Quota exceeded? */ |
7336 |
++ quota_ret = DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, |
7337 |
++ amount_needed); |
7338 |
++ if (quota_ret) |
7339 |
+ return QUOTA_EXCEEDED; |
7340 |
++ if (DLIMIT_ALLOC_BLOCK(hint->inode, amount_needed)) { |
7341 |
++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, |
7342 |
++ amount_needed); |
7343 |
++ return NO_DISK_SPACE; |
7344 |
++ } |
7345 |
++ |
7346 |
+ if (hint->preallocate && hint->prealloc_size) { |
7347 |
+ #ifdef REISERQUOTA_DEBUG |
7348 |
+ reiserfs_debug(s, REISERFS_DEBUG_CODE, |
7349 |
+ "reiserquota: allocating (prealloc) %d blocks id=%u", |
7350 |
+ hint->prealloc_size, hint->inode->i_uid); |
7351 |
+ #endif |
7352 |
+- quota_ret = |
7353 |
+- DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode, |
7354 |
+- hint->prealloc_size); |
7355 |
++ quota_ret = DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode, |
7356 |
++ hint->prealloc_size); |
7357 |
++ if (!quota_ret && |
7358 |
++ DLIMIT_ALLOC_BLOCK(hint->inode, hint->prealloc_size)) { |
7359 |
++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, |
7360 |
++ hint->prealloc_size); |
7361 |
++ quota_ret = 1; |
7362 |
++ } |
7363 |
+ if (quota_ret) |
7364 |
+ hint->preallocate = hint->prealloc_size = 0; |
7365 |
+ } |
7366 |
+@@ -1098,7 +1113,10 @@ static inline int blocknrs_and_prealloc_ |
7367 |
+ nr_allocated, |
7368 |
+ hint->inode->i_uid); |
7369 |
+ #endif |
7370 |
+- DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated); /* Free not allocated blocks */ |
7371 |
++ /* Free not allocated blocks */ |
7372 |
++ blocks = amount_needed + hint->prealloc_size - nr_allocated; |
7373 |
++ DLIMIT_FREE_BLOCK(hint->inode, blocks); |
7374 |
++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks); |
7375 |
+ } |
7376 |
+ while (nr_allocated--) |
7377 |
+ reiserfs_free_block(hint->th, hint->inode, |
7378 |
+@@ -1129,10 +1147,10 @@ static inline int blocknrs_and_prealloc_ |
7379 |
+ REISERFS_I(hint->inode)->i_prealloc_count, |
7380 |
+ hint->inode->i_uid); |
7381 |
+ #endif |
7382 |
+- DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + |
7383 |
+- hint->prealloc_size - nr_allocated - |
7384 |
+- REISERFS_I(hint->inode)-> |
7385 |
+- i_prealloc_count); |
7386 |
++ blocks = amount_needed + hint->prealloc_size - nr_allocated - |
7387 |
++ REISERFS_I(hint->inode)->i_prealloc_count; |
7388 |
++ DLIMIT_FREE_BLOCK(hint->inode, blocks); |
7389 |
++ DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks); |
7390 |
+ } |
7391 |
+ |
7392 |
+ return CARRY_ON; |
7393 |
+diff -NurpP --minimal linux-2.6.29.4/fs/reiserfs/file.c linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/file.c |
7394 |
+--- linux-2.6.29.4/fs/reiserfs/file.c 2008-12-25 00:26:37.000000000 +0100 |
7395 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/file.c 2009-02-22 22:54:25.000000000 +0100 |
7396 |
+@@ -307,4 +307,5 @@ const struct inode_operations reiserfs_f |
7397 |
+ .listxattr = reiserfs_listxattr, |
7398 |
+ .removexattr = reiserfs_removexattr, |
7399 |
+ .permission = reiserfs_permission, |
7400 |
++ .sync_flags = reiserfs_sync_flags, |
7401 |
+ }; |
7402 |
+diff -NurpP --minimal linux-2.6.29.4/fs/reiserfs/inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/inode.c |
7403 |
+--- linux-2.6.29.4/fs/reiserfs/inode.c 2009-03-24 14:22:27.000000000 +0100 |
7404 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/inode.c 2009-03-24 14:48:35.000000000 +0100 |
7405 |
+@@ -18,6 +18,8 @@ |
7406 |
+ #include <linux/writeback.h> |
7407 |
+ #include <linux/quotaops.h> |
7408 |
+ #include <linux/swap.h> |
7409 |
++#include <linux/vs_dlimit.h> |
7410 |
++#include <linux/vs_tag.h> |
7411 |
+ |
7412 |
+ int reiserfs_commit_write(struct file *f, struct page *page, |
7413 |
+ unsigned from, unsigned to); |
7414 |
+@@ -54,6 +56,7 @@ void reiserfs_delete_inode(struct inode |
7415 |
+ * stat data deletion */ |
7416 |
+ if (!err) |
7417 |
+ DQUOT_FREE_INODE(inode); |
7418 |
++ DLIMIT_FREE_INODE(inode); |
7419 |
+ |
7420 |
+ if (journal_end(&th, inode->i_sb, jbegin_count)) |
7421 |
+ goto out; |
7422 |
+@@ -1116,6 +1119,8 @@ static void init_inode(struct inode *ino |
7423 |
+ struct buffer_head *bh; |
7424 |
+ struct item_head *ih; |
7425 |
+ __u32 rdev; |
7426 |
++ uid_t uid; |
7427 |
++ gid_t gid; |
7428 |
+ //int version = ITEM_VERSION_1; |
7429 |
+ |
7430 |
+ bh = PATH_PLAST_BUFFER(path); |
7431 |
+@@ -1139,12 +1144,13 @@ static void init_inode(struct inode *ino |
7432 |
+ (struct stat_data_v1 *)B_I_PITEM(bh, ih); |
7433 |
+ unsigned long blocks; |
7434 |
+ |
7435 |
++ uid = sd_v1_uid(sd); |
7436 |
++ gid = sd_v1_gid(sd); |
7437 |
++ |
7438 |
+ set_inode_item_key_version(inode, KEY_FORMAT_3_5); |
7439 |
+ set_inode_sd_version(inode, STAT_DATA_V1); |
7440 |
+ inode->i_mode = sd_v1_mode(sd); |
7441 |
+ inode->i_nlink = sd_v1_nlink(sd); |
7442 |
+- inode->i_uid = sd_v1_uid(sd); |
7443 |
+- inode->i_gid = sd_v1_gid(sd); |
7444 |
+ inode->i_size = sd_v1_size(sd); |
7445 |
+ inode->i_atime.tv_sec = sd_v1_atime(sd); |
7446 |
+ inode->i_mtime.tv_sec = sd_v1_mtime(sd); |
7447 |
+@@ -1186,11 +1192,12 @@ static void init_inode(struct inode *ino |
7448 |
+ // (directories and symlinks) |
7449 |
+ struct stat_data *sd = (struct stat_data *)B_I_PITEM(bh, ih); |
7450 |
+ |
7451 |
++ uid = sd_v2_uid(sd); |
7452 |
++ gid = sd_v2_gid(sd); |
7453 |
++ |
7454 |
+ inode->i_mode = sd_v2_mode(sd); |
7455 |
+ inode->i_nlink = sd_v2_nlink(sd); |
7456 |
+- inode->i_uid = sd_v2_uid(sd); |
7457 |
+ inode->i_size = sd_v2_size(sd); |
7458 |
+- inode->i_gid = sd_v2_gid(sd); |
7459 |
+ inode->i_mtime.tv_sec = sd_v2_mtime(sd); |
7460 |
+ inode->i_atime.tv_sec = sd_v2_atime(sd); |
7461 |
+ inode->i_ctime.tv_sec = sd_v2_ctime(sd); |
7462 |
+@@ -1220,6 +1227,10 @@ static void init_inode(struct inode *ino |
7463 |
+ sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode); |
7464 |
+ } |
7465 |
+ |
7466 |
++ inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid); |
7467 |
++ inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid); |
7468 |
++ inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid, 0); |
7469 |
++ |
7470 |
+ pathrelse(path); |
7471 |
+ if (S_ISREG(inode->i_mode)) { |
7472 |
+ inode->i_op = &reiserfs_file_inode_operations; |
7473 |
+@@ -1242,13 +1253,15 @@ static void init_inode(struct inode *ino |
7474 |
+ static void inode2sd(void *sd, struct inode *inode, loff_t size) |
7475 |
+ { |
7476 |
+ struct stat_data *sd_v2 = (struct stat_data *)sd; |
7477 |
++ uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag); |
7478 |
++ gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag); |
7479 |
+ __u16 flags; |
7480 |
+ |
7481 |
++ set_sd_v2_uid(sd_v2, uid); |
7482 |
++ set_sd_v2_gid(sd_v2, gid); |
7483 |
+ set_sd_v2_mode(sd_v2, inode->i_mode); |
7484 |
+ set_sd_v2_nlink(sd_v2, inode->i_nlink); |
7485 |
+- set_sd_v2_uid(sd_v2, inode->i_uid); |
7486 |
+ set_sd_v2_size(sd_v2, size); |
7487 |
+- set_sd_v2_gid(sd_v2, inode->i_gid); |
7488 |
+ set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec); |
7489 |
+ set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec); |
7490 |
+ set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec); |
7491 |
+@@ -1763,6 +1776,10 @@ int reiserfs_new_inode(struct reiserfs_t |
7492 |
+ |
7493 |
+ BUG_ON(!th->t_trans_id); |
7494 |
+ |
7495 |
++ if (DLIMIT_ALLOC_INODE(inode)) { |
7496 |
++ err = -ENOSPC; |
7497 |
++ goto out_bad_dlimit; |
7498 |
++ } |
7499 |
+ if (DQUOT_ALLOC_INODE(inode)) { |
7500 |
+ err = -EDQUOT; |
7501 |
+ goto out_end_trans; |
7502 |
+@@ -1950,6 +1967,9 @@ int reiserfs_new_inode(struct reiserfs_t |
7503 |
+ DQUOT_FREE_INODE(inode); |
7504 |
+ |
7505 |
+ out_end_trans: |
7506 |
++ DLIMIT_FREE_INODE(inode); |
7507 |
++ |
7508 |
++ out_bad_dlimit: |
7509 |
+ journal_end(th, th->t_super, th->t_blocks_allocated); |
7510 |
+ /* Drop can be outside and it needs more credits so it's better to have it outside */ |
7511 |
+ DQUOT_DROP(inode); |
7512 |
+@@ -2837,14 +2857,19 @@ int reiserfs_commit_write(struct file *f |
7513 |
+ void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode) |
7514 |
+ { |
7515 |
+ if (reiserfs_attrs(inode->i_sb)) { |
7516 |
+- if (sd_attrs & REISERFS_SYNC_FL) |
7517 |
+- inode->i_flags |= S_SYNC; |
7518 |
+- else |
7519 |
+- inode->i_flags &= ~S_SYNC; |
7520 |
+ if (sd_attrs & REISERFS_IMMUTABLE_FL) |
7521 |
+ inode->i_flags |= S_IMMUTABLE; |
7522 |
+ else |
7523 |
+ inode->i_flags &= ~S_IMMUTABLE; |
7524 |
++ if (sd_attrs & REISERFS_IXUNLINK_FL) |
7525 |
++ inode->i_flags |= S_IXUNLINK; |
7526 |
++ else |
7527 |
++ inode->i_flags &= ~S_IXUNLINK; |
7528 |
++ |
7529 |
++ if (sd_attrs & REISERFS_SYNC_FL) |
7530 |
++ inode->i_flags |= S_SYNC; |
7531 |
++ else |
7532 |
++ inode->i_flags &= ~S_SYNC; |
7533 |
+ if (sd_attrs & REISERFS_APPEND_FL) |
7534 |
+ inode->i_flags |= S_APPEND; |
7535 |
+ else |
7536 |
+@@ -2857,6 +2882,15 @@ void sd_attrs_to_i_attrs(__u16 sd_attrs, |
7537 |
+ REISERFS_I(inode)->i_flags |= i_nopack_mask; |
7538 |
+ else |
7539 |
+ REISERFS_I(inode)->i_flags &= ~i_nopack_mask; |
7540 |
++ |
7541 |
++ if (sd_attrs & REISERFS_BARRIER_FL) |
7542 |
++ inode->i_vflags |= V_BARRIER; |
7543 |
++ else |
7544 |
++ inode->i_vflags &= ~V_BARRIER; |
7545 |
++ if (sd_attrs & REISERFS_COW_FL) |
7546 |
++ inode->i_vflags |= V_COW; |
7547 |
++ else |
7548 |
++ inode->i_vflags &= ~V_COW; |
7549 |
+ } |
7550 |
+ } |
7551 |
+ |
7552 |
+@@ -2867,6 +2901,11 @@ void i_attrs_to_sd_attrs(struct inode *i |
7553 |
+ *sd_attrs |= REISERFS_IMMUTABLE_FL; |
7554 |
+ else |
7555 |
+ *sd_attrs &= ~REISERFS_IMMUTABLE_FL; |
7556 |
++ if (inode->i_flags & S_IXUNLINK) |
7557 |
++ *sd_attrs |= REISERFS_IXUNLINK_FL; |
7558 |
++ else |
7559 |
++ *sd_attrs &= ~REISERFS_IXUNLINK_FL; |
7560 |
++ |
7561 |
+ if (inode->i_flags & S_SYNC) |
7562 |
+ *sd_attrs |= REISERFS_SYNC_FL; |
7563 |
+ else |
7564 |
+@@ -2879,6 +2918,15 @@ void i_attrs_to_sd_attrs(struct inode *i |
7565 |
+ *sd_attrs |= REISERFS_NOTAIL_FL; |
7566 |
+ else |
7567 |
+ *sd_attrs &= ~REISERFS_NOTAIL_FL; |
7568 |
++ |
7569 |
++ if (inode->i_vflags & V_BARRIER) |
7570 |
++ *sd_attrs |= REISERFS_BARRIER_FL; |
7571 |
++ else |
7572 |
++ *sd_attrs &= ~REISERFS_BARRIER_FL; |
7573 |
++ if (inode->i_vflags & V_COW) |
7574 |
++ *sd_attrs |= REISERFS_COW_FL; |
7575 |
++ else |
7576 |
++ *sd_attrs &= ~REISERFS_COW_FL; |
7577 |
+ } |
7578 |
+ } |
7579 |
+ |
7580 |
+@@ -3046,6 +3094,22 @@ static ssize_t reiserfs_direct_IO(int rw |
7581 |
+ reiserfs_get_blocks_direct_io, NULL); |
7582 |
+ } |
7583 |
+ |
7584 |
++int reiserfs_sync_flags(struct inode *inode) |
7585 |
++{ |
7586 |
++ u16 oldflags, newflags; |
7587 |
++ |
7588 |
++ oldflags = REISERFS_I(inode)->i_attrs; |
7589 |
++ newflags = oldflags; |
7590 |
++ i_attrs_to_sd_attrs(inode, &newflags); |
7591 |
++ |
7592 |
++ if (oldflags ^ newflags) { |
7593 |
++ REISERFS_I(inode)->i_attrs = newflags; |
7594 |
++ inode->i_ctime = CURRENT_TIME_SEC; |
7595 |
++ mark_inode_dirty(inode); |
7596 |
++ } |
7597 |
++ return 0; |
7598 |
++} |
7599 |
++ |
7600 |
+ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) |
7601 |
+ { |
7602 |
+ struct inode *inode = dentry->d_inode; |
7603 |
+@@ -3099,9 +3163,11 @@ int reiserfs_setattr(struct dentry *dent |
7604 |
+ } |
7605 |
+ |
7606 |
+ error = inode_change_ok(inode, attr); |
7607 |
++ |
7608 |
+ if (!error) { |
7609 |
+ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || |
7610 |
+- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { |
7611 |
++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) || |
7612 |
++ (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) { |
7613 |
+ error = reiserfs_chown_xattrs(inode, attr); |
7614 |
+ |
7615 |
+ if (!error) { |
7616 |
+@@ -3131,6 +3197,9 @@ int reiserfs_setattr(struct dentry *dent |
7617 |
+ inode->i_uid = attr->ia_uid; |
7618 |
+ if (attr->ia_valid & ATTR_GID) |
7619 |
+ inode->i_gid = attr->ia_gid; |
7620 |
++ if ((attr->ia_valid & ATTR_TAG) && |
7621 |
++ IS_TAGGED(inode)) |
7622 |
++ inode->i_tag = attr->ia_tag; |
7623 |
+ mark_inode_dirty(inode); |
7624 |
+ error = |
7625 |
+ journal_end(&th, inode->i_sb, jbegin_count); |
7626 |
+diff -NurpP --minimal linux-2.6.29.4/fs/reiserfs/ioctl.c linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/ioctl.c |
7627 |
+--- linux-2.6.29.4/fs/reiserfs/ioctl.c 2008-12-25 00:26:37.000000000 +0100 |
7628 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/ioctl.c 2009-02-22 22:54:25.000000000 +0100 |
7629 |
+@@ -7,6 +7,7 @@ |
7630 |
+ #include <linux/mount.h> |
7631 |
+ #include <linux/reiserfs_fs.h> |
7632 |
+ #include <linux/time.h> |
7633 |
++#include <linux/mount.h> |
7634 |
+ #include <asm/uaccess.h> |
7635 |
+ #include <linux/pagemap.h> |
7636 |
+ #include <linux/smp_lock.h> |
7637 |
+@@ -23,7 +24,7 @@ |
7638 |
+ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, |
7639 |
+ unsigned long arg) |
7640 |
+ { |
7641 |
+- unsigned int flags; |
7642 |
++ unsigned int flags, oldflags; |
7643 |
+ int err = 0; |
7644 |
+ |
7645 |
+ switch (cmd) { |
7646 |
+@@ -43,6 +44,7 @@ int reiserfs_ioctl(struct inode *inode, |
7647 |
+ |
7648 |
+ flags = REISERFS_I(inode)->i_attrs; |
7649 |
+ i_attrs_to_sd_attrs(inode, (__u16 *) & flags); |
7650 |
++ flags &= REISERFS_FL_USER_VISIBLE; |
7651 |
+ return put_user(flags, (int __user *)arg); |
7652 |
+ case REISERFS_IOC_SETFLAGS:{ |
7653 |
+ if (!reiserfs_attrs(inode->i_sb)) |
7654 |
+@@ -60,6 +62,10 @@ int reiserfs_ioctl(struct inode *inode, |
7655 |
+ err = -EFAULT; |
7656 |
+ goto setflags_out; |
7657 |
+ } |
7658 |
++ if (IS_BARRIER(inode)) { |
7659 |
++ vxwprintk_task(1, "messing with the barrier."); |
7660 |
++ return -EACCES; |
7661 |
++ } |
7662 |
+ /* |
7663 |
+ * Is it quota file? Do not allow user to mess with it |
7664 |
+ */ |
7665 |
+@@ -84,6 +90,10 @@ int reiserfs_ioctl(struct inode *inode, |
7666 |
+ goto setflags_out; |
7667 |
+ } |
7668 |
+ } |
7669 |
++ |
7670 |
++ oldflags = REISERFS_I(inode)->i_attrs; |
7671 |
++ flags = flags & REISERFS_FL_USER_MODIFIABLE; |
7672 |
++ flags |= oldflags & ~REISERFS_FL_USER_MODIFIABLE; |
7673 |
+ sd_attrs_to_i_attrs(flags, inode); |
7674 |
+ REISERFS_I(inode)->i_attrs = flags; |
7675 |
+ inode->i_ctime = CURRENT_TIME_SEC; |
7676 |
+diff -NurpP --minimal linux-2.6.29.4/fs/reiserfs/namei.c linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/namei.c |
7677 |
+--- linux-2.6.29.4/fs/reiserfs/namei.c 2009-03-24 14:22:27.000000000 +0100 |
7678 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/namei.c 2009-03-24 14:48:35.000000000 +0100 |
7679 |
+@@ -17,6 +17,7 @@ |
7680 |
+ #include <linux/reiserfs_acl.h> |
7681 |
+ #include <linux/reiserfs_xattr.h> |
7682 |
+ #include <linux/quotaops.h> |
7683 |
++#include <linux/vs_tag.h> |
7684 |
+ |
7685 |
+ #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } |
7686 |
+ #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i); |
7687 |
+@@ -360,6 +361,7 @@ static struct dentry *reiserfs_lookup(st |
7688 |
+ reiserfs_write_unlock(dir->i_sb); |
7689 |
+ return ERR_PTR(-EACCES); |
7690 |
+ } |
7691 |
++ dx_propagate_tag(nd, inode); |
7692 |
+ |
7693 |
+ /* Propogate the priv_object flag so we know we're in the priv tree */ |
7694 |
+ if (is_reiserfs_priv_object(dir)) |
7695 |
+@@ -586,6 +588,7 @@ static int new_inode_init(struct inode * |
7696 |
+ } else { |
7697 |
+ inode->i_gid = current_fsgid(); |
7698 |
+ } |
7699 |
++ inode->i_tag = dx_current_fstag(inode->i_sb); |
7700 |
+ DQUOT_INIT(inode); |
7701 |
+ return 0; |
7702 |
+ } |
7703 |
+@@ -1540,6 +1543,7 @@ const struct inode_operations reiserfs_d |
7704 |
+ .listxattr = reiserfs_listxattr, |
7705 |
+ .removexattr = reiserfs_removexattr, |
7706 |
+ .permission = reiserfs_permission, |
7707 |
++ .sync_flags = reiserfs_sync_flags, |
7708 |
+ }; |
7709 |
+ |
7710 |
+ /* |
7711 |
+@@ -1556,6 +1560,7 @@ const struct inode_operations reiserfs_s |
7712 |
+ .listxattr = reiserfs_listxattr, |
7713 |
+ .removexattr = reiserfs_removexattr, |
7714 |
+ .permission = reiserfs_permission, |
7715 |
++ .sync_flags = reiserfs_sync_flags, |
7716 |
+ |
7717 |
+ }; |
7718 |
+ |
7719 |
+@@ -1569,5 +1574,6 @@ const struct inode_operations reiserfs_s |
7720 |
+ .listxattr = reiserfs_listxattr, |
7721 |
+ .removexattr = reiserfs_removexattr, |
7722 |
+ .permission = reiserfs_permission, |
7723 |
++ .sync_flags = reiserfs_sync_flags, |
7724 |
+ |
7725 |
+ }; |
7726 |
+diff -NurpP --minimal linux-2.6.29.4/fs/reiserfs/stree.c linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/stree.c |
7727 |
+--- linux-2.6.29.4/fs/reiserfs/stree.c 2008-12-25 00:26:37.000000000 +0100 |
7728 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/stree.c 2009-02-22 22:54:25.000000000 +0100 |
7729 |
+@@ -55,6 +55,7 @@ |
7730 |
+ #include <linux/reiserfs_fs.h> |
7731 |
+ #include <linux/buffer_head.h> |
7732 |
+ #include <linux/quotaops.h> |
7733 |
++#include <linux/vs_dlimit.h> |
7734 |
+ |
7735 |
+ /* Does the buffer contain a disk block which is in the tree. */ |
7736 |
+ inline int B_IS_IN_TREE(const struct buffer_head *p_s_bh) |
7737 |
+@@ -1297,6 +1298,7 @@ int reiserfs_delete_item(struct reiserfs |
7738 |
+ "reiserquota delete_item(): freeing %u, id=%u type=%c", |
7739 |
+ quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih)); |
7740 |
+ #endif |
7741 |
++ DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes); |
7742 |
+ DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes); |
7743 |
+ |
7744 |
+ /* Return deleted body length */ |
7745 |
+@@ -1385,6 +1387,7 @@ void reiserfs_delete_solid_item(struct r |
7746 |
+ #endif |
7747 |
+ DQUOT_FREE_SPACE_NODIRTY(inode, |
7748 |
+ quota_cut_bytes); |
7749 |
++ DLIMIT_FREE_SPACE(inode, quota_cut_bytes); |
7750 |
+ } |
7751 |
+ break; |
7752 |
+ } |
7753 |
+@@ -1734,6 +1737,7 @@ int reiserfs_cut_from_item(struct reiser |
7754 |
+ "reiserquota cut_from_item(): freeing %u id=%u type=%c", |
7755 |
+ quota_cut_bytes, p_s_inode->i_uid, '?'); |
7756 |
+ #endif |
7757 |
++ DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes); |
7758 |
+ DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes); |
7759 |
+ return n_ret_value; |
7760 |
+ } |
7761 |
+@@ -1975,6 +1979,11 @@ int reiserfs_paste_into_item(struct reis |
7762 |
+ pathrelse(p_s_search_path); |
7763 |
+ return -EDQUOT; |
7764 |
+ } |
7765 |
++ if (DLIMIT_ALLOC_SPACE(inode, n_pasted_size)) { |
7766 |
++ DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size); |
7767 |
++ pathrelse(p_s_search_path); |
7768 |
++ return -ENOSPC; |
7769 |
++ } |
7770 |
+ init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path, |
7771 |
+ n_pasted_size); |
7772 |
+ #ifdef DISPLACE_NEW_PACKING_LOCALITIES |
7773 |
+@@ -2027,6 +2036,7 @@ int reiserfs_paste_into_item(struct reis |
7774 |
+ n_pasted_size, inode->i_uid, |
7775 |
+ key2type(&(p_s_key->on_disk_key))); |
7776 |
+ #endif |
7777 |
++ DLIMIT_FREE_SPACE(inode, n_pasted_size); |
7778 |
+ DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size); |
7779 |
+ return retval; |
7780 |
+ } |
7781 |
+@@ -2064,6 +2074,11 @@ int reiserfs_insert_item(struct reiserfs |
7782 |
+ pathrelse(p_s_path); |
7783 |
+ return -EDQUOT; |
7784 |
+ } |
7785 |
++ if (DLIMIT_ALLOC_SPACE(inode, quota_bytes)) { |
7786 |
++ DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes); |
7787 |
++ pathrelse(p_s_path); |
7788 |
++ return -ENOSPC; |
7789 |
++ } |
7790 |
+ } |
7791 |
+ init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path, |
7792 |
+ IH_SIZE + ih_item_len(p_s_ih)); |
7793 |
+@@ -2111,7 +2126,9 @@ int reiserfs_insert_item(struct reiserfs |
7794 |
+ "reiserquota insert_item(): freeing %u id=%u type=%c", |
7795 |
+ quota_bytes, inode->i_uid, head2type(p_s_ih)); |
7796 |
+ #endif |
7797 |
+- if (inode) |
7798 |
++ if (inode) { |
7799 |
++ DLIMIT_FREE_SPACE(inode, quota_bytes); |
7800 |
+ DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes); |
7801 |
++ } |
7802 |
+ return retval; |
7803 |
+ } |
7804 |
+diff -NurpP --minimal linux-2.6.29.4/fs/reiserfs/super.c linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/super.c |
7805 |
+--- linux-2.6.29.4/fs/reiserfs/super.c 2009-03-24 14:22:27.000000000 +0100 |
7806 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/super.c 2009-03-24 14:48:35.000000000 +0100 |
7807 |
+@@ -902,6 +902,14 @@ static int reiserfs_parse_options(struct |
7808 |
+ {"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT}, |
7809 |
+ {"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT}, |
7810 |
+ #endif |
7811 |
++#ifndef CONFIG_TAGGING_NONE |
7812 |
++ {"tagxid",.setmask = 1 << REISERFS_TAGGED}, |
7813 |
++ {"tag",.setmask = 1 << REISERFS_TAGGED}, |
7814 |
++ {"notag",.clrmask = 1 << REISERFS_TAGGED}, |
7815 |
++#endif |
7816 |
++#ifdef CONFIG_PROPAGATE |
7817 |
++ {"tag",.arg_required = 'T',.values = NULL}, |
7818 |
++#endif |
7819 |
+ #ifdef CONFIG_REISERFS_FS_POSIX_ACL |
7820 |
+ {"acl",.setmask = 1 << REISERFS_POSIXACL}, |
7821 |
+ {"noacl",.clrmask = 1 << REISERFS_POSIXACL}, |
7822 |
+@@ -1195,6 +1203,12 @@ static int reiserfs_remount(struct super |
7823 |
+ handle_quota_files(s, qf_names, &qfmt); |
7824 |
+ #endif |
7825 |
+ |
7826 |
++ if ((mount_options & (1 << REISERFS_TAGGED)) && |
7827 |
++ !(s->s_flags & MS_TAGGED)) { |
7828 |
++ reiserfs_warning(s, "reiserfs: tagging not permitted on remount."); |
7829 |
++ return -EINVAL; |
7830 |
++ } |
7831 |
++ |
7832 |
+ handle_attrs(s); |
7833 |
+ |
7834 |
+ /* Add options that are safe here */ |
7835 |
+@@ -1659,6 +1673,10 @@ static int reiserfs_fill_super(struct su |
7836 |
+ goto error; |
7837 |
+ } |
7838 |
+ |
7839 |
++ /* map mount option tagxid */ |
7840 |
++ if (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_TAGGED)) |
7841 |
++ s->s_flags |= MS_TAGGED; |
7842 |
++ |
7843 |
+ rs = SB_DISK_SUPER_BLOCK(s); |
7844 |
+ /* Let's do basic sanity check to verify that underlying device is not |
7845 |
+ smaller than the filesystem. If the check fails then abort and scream, |
7846 |
+diff -NurpP --minimal linux-2.6.29.4/fs/reiserfs/xattr.c linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/xattr.c |
7847 |
+--- linux-2.6.29.4/fs/reiserfs/xattr.c 2008-12-25 00:26:37.000000000 +0100 |
7848 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/reiserfs/xattr.c 2009-02-22 22:54:25.000000000 +0100 |
7849 |
+@@ -35,6 +35,7 @@ |
7850 |
+ #include <linux/namei.h> |
7851 |
+ #include <linux/errno.h> |
7852 |
+ #include <linux/fs.h> |
7853 |
++#include <linux/mount.h> |
7854 |
+ #include <linux/file.h> |
7855 |
+ #include <linux/pagemap.h> |
7856 |
+ #include <linux/xattr.h> |
7857 |
+diff -NurpP --minimal linux-2.6.29.4/fs/stat.c linux-2.6.29.4-vs2.3.0.36.14/fs/stat.c |
7858 |
+--- linux-2.6.29.4/fs/stat.c 2009-03-24 14:22:36.000000000 +0100 |
7859 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/stat.c 2009-03-24 14:48:35.000000000 +0100 |
7860 |
+@@ -26,6 +26,7 @@ void generic_fillattr(struct inode *inod |
7861 |
+ stat->nlink = inode->i_nlink; |
7862 |
+ stat->uid = inode->i_uid; |
7863 |
+ stat->gid = inode->i_gid; |
7864 |
++ stat->tag = inode->i_tag; |
7865 |
+ stat->rdev = inode->i_rdev; |
7866 |
+ stat->atime = inode->i_atime; |
7867 |
+ stat->mtime = inode->i_mtime; |
7868 |
+diff -NurpP --minimal linux-2.6.29.4/fs/super.c linux-2.6.29.4-vs2.3.0.36.14/fs/super.c |
7869 |
+--- linux-2.6.29.4/fs/super.c 2009-03-24 14:22:36.000000000 +0100 |
7870 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/super.c 2009-03-24 16:32:06.000000000 +0100 |
7871 |
+@@ -39,6 +39,9 @@ |
7872 |
+ #include <linux/mutex.h> |
7873 |
+ #include <linux/file.h> |
7874 |
+ #include <linux/async.h> |
7875 |
++#include <linux/devpts_fs.h> |
7876 |
++#include <linux/proc_fs.h> |
7877 |
++#include <linux/vs_context.h> |
7878 |
+ #include <asm/uaccess.h> |
7879 |
+ #include "internal.h" |
7880 |
+ |
7881 |
+@@ -918,12 +921,18 @@ struct vfsmount * |
7882 |
+ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data) |
7883 |
+ { |
7884 |
+ struct vfsmount *mnt; |
7885 |
++ struct super_block *sb; |
7886 |
+ char *secdata = NULL; |
7887 |
+ int error; |
7888 |
+ |
7889 |
+ if (!type) |
7890 |
+ return ERR_PTR(-ENODEV); |
7891 |
+ |
7892 |
++ error = -EPERM; |
7893 |
++ if ((type->fs_flags & FS_BINARY_MOUNTDATA) && |
7894 |
++ !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT)) |
7895 |
++ goto out; |
7896 |
++ |
7897 |
+ error = -ENOMEM; |
7898 |
+ mnt = alloc_vfsmnt(name); |
7899 |
+ if (!mnt) |
7900 |
+@@ -942,9 +951,17 @@ vfs_kern_mount(struct file_system_type * |
7901 |
+ error = type->get_sb(type, flags, name, data, mnt); |
7902 |
+ if (error < 0) |
7903 |
+ goto out_free_secdata; |
7904 |
+- BUG_ON(!mnt->mnt_sb); |
7905 |
+ |
7906 |
+- error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); |
7907 |
++ sb = mnt->mnt_sb; |
7908 |
++ BUG_ON(!sb); |
7909 |
++ |
7910 |
++ error = -EPERM; |
7911 |
++ if (!vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT) && !sb->s_bdev && |
7912 |
++ (sb->s_magic != PROC_SUPER_MAGIC) && |
7913 |
++ (sb->s_magic != DEVPTS_SUPER_MAGIC)) |
7914 |
++ goto out_sb; |
7915 |
++ |
7916 |
++ error = security_sb_kern_mount(sb, flags, secdata); |
7917 |
+ if (error) |
7918 |
+ goto out_sb; |
7919 |
+ |
7920 |
+diff -NurpP --minimal linux-2.6.29.4/fs/sysfs/mount.c linux-2.6.29.4-vs2.3.0.36.14/fs/sysfs/mount.c |
7921 |
+--- linux-2.6.29.4/fs/sysfs/mount.c 2008-12-25 00:26:37.000000000 +0100 |
7922 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/sysfs/mount.c 2009-02-22 22:54:25.000000000 +0100 |
7923 |
+@@ -20,8 +20,6 @@ |
7924 |
+ |
7925 |
+ #include "sysfs.h" |
7926 |
+ |
7927 |
+-/* Random magic number */ |
7928 |
+-#define SYSFS_MAGIC 0x62656572 |
7929 |
+ |
7930 |
+ static struct vfsmount *sysfs_mount; |
7931 |
+ struct super_block * sysfs_sb = NULL; |
7932 |
+@@ -47,7 +45,7 @@ static int sysfs_fill_super(struct super |
7933 |
+ |
7934 |
+ sb->s_blocksize = PAGE_CACHE_SIZE; |
7935 |
+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
7936 |
+- sb->s_magic = SYSFS_MAGIC; |
7937 |
++ sb->s_magic = SYSFS_SUPER_MAGIC; |
7938 |
+ sb->s_op = &sysfs_ops; |
7939 |
+ sb->s_time_gran = 1; |
7940 |
+ sysfs_sb = sb; |
7941 |
+diff -NurpP --minimal linux-2.6.29.4/fs/utimes.c linux-2.6.29.4-vs2.3.0.36.14/fs/utimes.c |
7942 |
+--- linux-2.6.29.4/fs/utimes.c 2009-03-24 14:22:37.000000000 +0100 |
7943 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/utimes.c 2009-02-22 22:54:25.000000000 +0100 |
7944 |
+@@ -8,6 +8,8 @@ |
7945 |
+ #include <linux/stat.h> |
7946 |
+ #include <linux/utime.h> |
7947 |
+ #include <linux/syscalls.h> |
7948 |
++#include <linux/mount.h> |
7949 |
++#include <linux/vs_cowbl.h> |
7950 |
+ #include <asm/uaccess.h> |
7951 |
+ #include <asm/unistd.h> |
7952 |
+ |
7953 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xattr.c linux-2.6.29.4-vs2.3.0.36.14/fs/xattr.c |
7954 |
+--- linux-2.6.29.4/fs/xattr.c 2009-03-24 14:22:37.000000000 +0100 |
7955 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xattr.c 2009-03-24 14:48:35.000000000 +0100 |
7956 |
+@@ -18,6 +18,7 @@ |
7957 |
+ #include <linux/module.h> |
7958 |
+ #include <linux/fsnotify.h> |
7959 |
+ #include <linux/audit.h> |
7960 |
++#include <linux/mount.h> |
7961 |
+ #include <asm/uaccess.h> |
7962 |
+ |
7963 |
+ |
7964 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/linux-2.6/xfs_ioctl.c |
7965 |
+--- linux-2.6.29.4/fs/xfs/linux-2.6/xfs_ioctl.c 2009-03-24 14:22:37.000000000 +0100 |
7966 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/linux-2.6/xfs_ioctl.c 2009-03-24 14:48:35.000000000 +0100 |
7967 |
+@@ -769,6 +769,10 @@ xfs_merge_ioc_xflags( |
7968 |
+ xflags |= XFS_XFLAG_IMMUTABLE; |
7969 |
+ else |
7970 |
+ xflags &= ~XFS_XFLAG_IMMUTABLE; |
7971 |
++ if (flags & FS_IXUNLINK_FL) |
7972 |
++ xflags |= XFS_XFLAG_IXUNLINK; |
7973 |
++ else |
7974 |
++ xflags &= ~XFS_XFLAG_IXUNLINK; |
7975 |
+ if (flags & FS_APPEND_FL) |
7976 |
+ xflags |= XFS_XFLAG_APPEND; |
7977 |
+ else |
7978 |
+@@ -797,6 +801,8 @@ xfs_di2lxflags( |
7979 |
+ |
7980 |
+ if (di_flags & XFS_DIFLAG_IMMUTABLE) |
7981 |
+ flags |= FS_IMMUTABLE_FL; |
7982 |
++ if (di_flags & XFS_DIFLAG_IXUNLINK) |
7983 |
++ flags |= FS_IXUNLINK_FL; |
7984 |
+ if (di_flags & XFS_DIFLAG_APPEND) |
7985 |
+ flags |= FS_APPEND_FL; |
7986 |
+ if (di_flags & XFS_DIFLAG_SYNC) |
7987 |
+@@ -855,6 +861,8 @@ xfs_set_diflags( |
7988 |
+ di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC); |
7989 |
+ if (xflags & XFS_XFLAG_IMMUTABLE) |
7990 |
+ di_flags |= XFS_DIFLAG_IMMUTABLE; |
7991 |
++ if (xflags & XFS_XFLAG_IXUNLINK) |
7992 |
++ di_flags |= XFS_DIFLAG_IXUNLINK; |
7993 |
+ if (xflags & XFS_XFLAG_APPEND) |
7994 |
+ di_flags |= XFS_DIFLAG_APPEND; |
7995 |
+ if (xflags & XFS_XFLAG_SYNC) |
7996 |
+@@ -897,6 +905,10 @@ xfs_diflags_to_linux( |
7997 |
+ inode->i_flags |= S_IMMUTABLE; |
7998 |
+ else |
7999 |
+ inode->i_flags &= ~S_IMMUTABLE; |
8000 |
++ if (xflags & XFS_XFLAG_IXUNLINK) |
8001 |
++ inode->i_flags |= S_IXUNLINK; |
8002 |
++ else |
8003 |
++ inode->i_flags &= ~S_IXUNLINK; |
8004 |
+ if (xflags & XFS_XFLAG_APPEND) |
8005 |
+ inode->i_flags |= S_APPEND; |
8006 |
+ else |
8007 |
+@@ -1371,10 +1383,18 @@ xfs_file_ioctl( |
8008 |
+ case XFS_IOC_FSGETXATTRA: |
8009 |
+ return xfs_ioc_fsgetxattr(ip, 1, arg); |
8010 |
+ case XFS_IOC_FSSETXATTR: |
8011 |
++ if (IS_BARRIER(inode)) { |
8012 |
++ vxwprintk_task(1, "messing with the barrier."); |
8013 |
++ return -XFS_ERROR(EACCES); |
8014 |
++ } |
8015 |
+ return xfs_ioc_fssetxattr(ip, filp, arg); |
8016 |
+ case XFS_IOC_GETXFLAGS: |
8017 |
+ return xfs_ioc_getxflags(ip, arg); |
8018 |
+ case XFS_IOC_SETXFLAGS: |
8019 |
++ if (IS_BARRIER(inode)) { |
8020 |
++ vxwprintk_task(1, "messing with the barrier."); |
8021 |
++ return -XFS_ERROR(EACCES); |
8022 |
++ } |
8023 |
+ return xfs_ioc_setxflags(ip, filp, arg); |
8024 |
+ |
8025 |
+ case XFS_IOC_FSSETDM: { |
8026 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/linux-2.6/xfs_iops.c |
8027 |
+--- linux-2.6.29.4/fs/xfs/linux-2.6/xfs_iops.c 2009-03-24 14:22:37.000000000 +0100 |
8028 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/linux-2.6/xfs_iops.c 2009-03-24 16:33:10.000000000 +0100 |
8029 |
+@@ -54,6 +54,7 @@ |
8030 |
+ #include <linux/security.h> |
8031 |
+ #include <linux/falloc.h> |
8032 |
+ #include <linux/fiemap.h> |
8033 |
++#include <linux/vs_tag.h> |
8034 |
+ |
8035 |
+ /* |
8036 |
+ * Bring the atime in the XFS inode uptodate. |
8037 |
+@@ -552,6 +553,7 @@ xfs_vn_getattr( |
8038 |
+ stat->nlink = ip->i_d.di_nlink; |
8039 |
+ stat->uid = ip->i_d.di_uid; |
8040 |
+ stat->gid = ip->i_d.di_gid; |
8041 |
++ stat->tag = ip->i_d.di_tag; |
8042 |
+ stat->ino = ip->i_ino; |
8043 |
+ #if XFS_BIG_INUMS |
8044 |
+ stat->ino += mp->m_inoadd; |
8045 |
+@@ -591,6 +593,12 @@ xfs_vn_getattr( |
8046 |
+ } |
8047 |
+ |
8048 |
+ STATIC int |
8049 |
++xfs_vn_sync_xflags(struct inode *inode) |
8050 |
++{ |
8051 |
++ return -xfs_sync_xflags(XFS_I(inode)); |
8052 |
++} |
8053 |
++ |
8054 |
++STATIC int |
8055 |
+ xfs_vn_setattr( |
8056 |
+ struct dentry *dentry, |
8057 |
+ struct iattr *iattr) |
8058 |
+@@ -748,6 +756,7 @@ static const struct inode_operations xfs |
8059 |
+ .listxattr = xfs_vn_listxattr, |
8060 |
+ .fallocate = xfs_vn_fallocate, |
8061 |
+ .fiemap = xfs_vn_fiemap, |
8062 |
++ .sync_flags = xfs_vn_sync_xflags, |
8063 |
+ }; |
8064 |
+ |
8065 |
+ static const struct inode_operations xfs_dir_inode_operations = { |
8066 |
+@@ -773,6 +782,7 @@ static const struct inode_operations xfs |
8067 |
+ .getxattr = generic_getxattr, |
8068 |
+ .removexattr = generic_removexattr, |
8069 |
+ .listxattr = xfs_vn_listxattr, |
8070 |
++ .sync_flags = xfs_vn_sync_xflags, |
8071 |
+ }; |
8072 |
+ |
8073 |
+ static const struct inode_operations xfs_dir_ci_inode_operations = { |
8074 |
+@@ -822,6 +832,10 @@ xfs_diflags_to_iflags( |
8075 |
+ inode->i_flags |= S_IMMUTABLE; |
8076 |
+ else |
8077 |
+ inode->i_flags &= ~S_IMMUTABLE; |
8078 |
++ if (ip->i_d.di_flags & XFS_DIFLAG_IXUNLINK) |
8079 |
++ inode->i_flags |= S_IXUNLINK; |
8080 |
++ else |
8081 |
++ inode->i_flags &= ~S_IXUNLINK; |
8082 |
+ if (ip->i_d.di_flags & XFS_DIFLAG_APPEND) |
8083 |
+ inode->i_flags |= S_APPEND; |
8084 |
+ else |
8085 |
+@@ -834,6 +848,15 @@ xfs_diflags_to_iflags( |
8086 |
+ inode->i_flags |= S_NOATIME; |
8087 |
+ else |
8088 |
+ inode->i_flags &= ~S_NOATIME; |
8089 |
++ |
8090 |
++ if (ip->i_d.di_vflags & XFS_DIVFLAG_BARRIER) |
8091 |
++ inode->i_vflags |= V_BARRIER; |
8092 |
++ else |
8093 |
++ inode->i_vflags &= ~V_BARRIER; |
8094 |
++ if (ip->i_d.di_vflags & XFS_DIVFLAG_COW) |
8095 |
++ inode->i_vflags |= V_COW; |
8096 |
++ else |
8097 |
++ inode->i_vflags &= ~V_COW; |
8098 |
+ } |
8099 |
+ |
8100 |
+ /* |
8101 |
+@@ -862,6 +885,7 @@ xfs_setup_inode( |
8102 |
+ inode->i_nlink = ip->i_d.di_nlink; |
8103 |
+ inode->i_uid = ip->i_d.di_uid; |
8104 |
+ inode->i_gid = ip->i_d.di_gid; |
8105 |
++ inode->i_tag = ip->i_d.di_tag; |
8106 |
+ |
8107 |
+ switch (inode->i_mode & S_IFMT) { |
8108 |
+ case S_IFBLK: |
8109 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/linux-2.6/xfs_linux.h linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/linux-2.6/xfs_linux.h |
8110 |
+--- linux-2.6.29.4/fs/xfs/linux-2.6/xfs_linux.h 2009-03-24 14:22:37.000000000 +0100 |
8111 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/linux-2.6/xfs_linux.h 2009-03-25 01:26:04.000000000 +0100 |
8112 |
+@@ -119,6 +119,7 @@ |
8113 |
+ |
8114 |
+ #define current_cpu() (raw_smp_processor_id()) |
8115 |
+ #define current_pid() (current->pid) |
8116 |
++#define current_fstag(cred,vp) (dx_current_fstag((vp)->i_sb)) |
8117 |
+ #define current_test_flags(f) (current->flags & (f)) |
8118 |
+ #define current_set_flags_nested(sp, f) \ |
8119 |
+ (*(sp) = current->flags, current->flags |= (f)) |
8120 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/linux-2.6/xfs_super.c linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/linux-2.6/xfs_super.c |
8121 |
+--- linux-2.6.29.4/fs/xfs/linux-2.6/xfs_super.c 2009-03-24 14:22:37.000000000 +0100 |
8122 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/linux-2.6/xfs_super.c 2009-03-25 01:48:51.000000000 +0100 |
8123 |
+@@ -120,6 +120,9 @@ mempool_t *xfs_ioend_pool; |
8124 |
+ #define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */ |
8125 |
+ #define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */ |
8126 |
+ #define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */ |
8127 |
++#define MNTOPT_TAGXID "tagxid" /* context tagging for inodes */ |
8128 |
++#define MNTOPT_TAGGED "tag" /* context tagging for inodes */ |
8129 |
++#define MNTOPT_NOTAGTAG "notag" /* do not use context tagging */ |
8130 |
+ |
8131 |
+ /* |
8132 |
+ * Table driven mount option parser. |
8133 |
+@@ -128,10 +131,14 @@ mempool_t *xfs_ioend_pool; |
8134 |
+ * in the future, too. |
8135 |
+ */ |
8136 |
+ enum { |
8137 |
++ Opt_tag, Opt_notag, |
8138 |
+ Opt_barrier, Opt_nobarrier, Opt_err |
8139 |
+ }; |
8140 |
+ |
8141 |
+ static const match_table_t tokens = { |
8142 |
++ {Opt_tag, "tagxid"}, |
8143 |
++ {Opt_tag, "tag"}, |
8144 |
++ {Opt_notag, "notag"}, |
8145 |
+ {Opt_barrier, "barrier"}, |
8146 |
+ {Opt_nobarrier, "nobarrier"}, |
8147 |
+ {Opt_err, NULL} |
8148 |
+@@ -395,6 +402,19 @@ xfs_parseargs( |
8149 |
+ } else if (!strcmp(this_char, "irixsgid")) { |
8150 |
+ cmn_err(CE_WARN, |
8151 |
+ "XFS: irixsgid is now a sysctl(2) variable, option is deprecated."); |
8152 |
++#ifndef CONFIG_TAGGING_NONE |
8153 |
++ } else if (!strcmp(this_char, MNTOPT_TAGGED)) { |
8154 |
++ mp->m_flags |= XFS_MOUNT_TAGGED; |
8155 |
++ } else if (!strcmp(this_char, MNTOPT_NOTAGTAG)) { |
8156 |
++ mp->m_flags &= ~XFS_MOUNT_TAGGED; |
8157 |
++ } else if (!strcmp(this_char, MNTOPT_TAGXID)) { |
8158 |
++ mp->m_flags |= XFS_MOUNT_TAGGED; |
8159 |
++#endif |
8160 |
++#ifdef CONFIG_PROPAGATE |
8161 |
++ } else if (!strcmp(this_char, MNTOPT_TAGGED)) { |
8162 |
++ /* use value */ |
8163 |
++ mp->m_flags |= XFS_MOUNT_TAGGED; |
8164 |
++#endif |
8165 |
+ } else { |
8166 |
+ cmn_err(CE_WARN, |
8167 |
+ "XFS: unknown mount option [%s].", this_char); |
8168 |
+@@ -1221,6 +1241,16 @@ xfs_fs_remount( |
8169 |
+ case Opt_nobarrier: |
8170 |
+ mp->m_flags &= ~XFS_MOUNT_BARRIER; |
8171 |
+ break; |
8172 |
++ case Opt_tag: |
8173 |
++ if (!(sb->s_flags & MS_TAGGED)) { |
8174 |
++ printk(KERN_INFO |
8175 |
++ "XFS: %s: tagging not permitted on remount.\n", |
8176 |
++ sb->s_id); |
8177 |
++ return -EINVAL; |
8178 |
++ } |
8179 |
++ break; |
8180 |
++ case Opt_notag: |
8181 |
++ break; |
8182 |
+ default: |
8183 |
+ /* |
8184 |
+ * Logically we would return an error here to prevent |
8185 |
+@@ -1480,6 +1510,9 @@ xfs_fs_fill_super( |
8186 |
+ |
8187 |
+ XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, mtpt, mp->m_fsname); |
8188 |
+ |
8189 |
++ if (mp->m_flags & XFS_MOUNT_TAGGED) |
8190 |
++ sb->s_flags |= MS_TAGGED; |
8191 |
++ |
8192 |
+ sb->s_dirt = 1; |
8193 |
+ sb->s_magic = XFS_SB_MAGIC; |
8194 |
+ sb->s_blocksize = mp->m_sb.sb_blocksize; |
8195 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/quota/xfs_qm_syscalls.c linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/quota/xfs_qm_syscalls.c |
8196 |
+--- linux-2.6.29.4/fs/xfs/quota/xfs_qm_syscalls.c 2009-03-24 14:22:37.000000000 +0100 |
8197 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/quota/xfs_qm_syscalls.c 2009-03-24 14:48:35.000000000 +0100 |
8198 |
+@@ -426,7 +426,7 @@ xfs_qm_scall_quotaon( |
8199 |
+ uint accflags; |
8200 |
+ __int64_t sbflags; |
8201 |
+ |
8202 |
+- if (!capable(CAP_SYS_ADMIN)) |
8203 |
++ if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL)) |
8204 |
+ return XFS_ERROR(EPERM); |
8205 |
+ |
8206 |
+ flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); |
8207 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/xfs_dinode.h linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_dinode.h |
8208 |
+--- linux-2.6.29.4/fs/xfs/xfs_dinode.h 2009-03-24 14:22:37.000000000 +0100 |
8209 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_dinode.h 2009-03-24 16:38:27.000000000 +0100 |
8210 |
+@@ -50,7 +50,9 @@ typedef struct xfs_dinode { |
8211 |
+ __be32 di_gid; /* owner's group id */ |
8212 |
+ __be32 di_nlink; /* number of links to file */ |
8213 |
+ __be16 di_projid; /* owner's project id */ |
8214 |
+- __u8 di_pad[8]; /* unused, zeroed space */ |
8215 |
++ __be16 di_tag; /* context tagging */ |
8216 |
++ __be16 di_vflags; /* vserver specific flags */ |
8217 |
++ __u8 di_pad[4]; /* unused, zeroed space */ |
8218 |
+ __be16 di_flushiter; /* incremented on flush */ |
8219 |
+ xfs_timestamp_t di_atime; /* time last accessed */ |
8220 |
+ xfs_timestamp_t di_mtime; /* time last modified */ |
8221 |
+@@ -181,6 +183,8 @@ static inline void xfs_dinode_put_rdev(s |
8222 |
+ #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ |
8223 |
+ #define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */ |
8224 |
+ #define XFS_DIFLAG_FILESTREAM_BIT 14 /* use filestream allocator */ |
8225 |
++#define XFS_DIFLAG_IXUNLINK_BIT 15 /* Immutable inver on unlink */ |
8226 |
++ |
8227 |
+ #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) |
8228 |
+ #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) |
8229 |
+ #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) |
8230 |
+@@ -196,6 +200,7 @@ static inline void xfs_dinode_put_rdev(s |
8231 |
+ #define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) |
8232 |
+ #define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT) |
8233 |
+ #define XFS_DIFLAG_FILESTREAM (1 << XFS_DIFLAG_FILESTREAM_BIT) |
8234 |
++#define XFS_DIFLAG_IXUNLINK (1 << XFS_DIFLAG_IXUNLINK_BIT) |
8235 |
+ |
8236 |
+ #ifdef CONFIG_XFS_RT |
8237 |
+ #define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) |
8238 |
+@@ -208,6 +213,10 @@ static inline void xfs_dinode_put_rdev(s |
8239 |
+ XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ |
8240 |
+ XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ |
8241 |
+ XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ |
8242 |
+- XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM) |
8243 |
++ XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM | \ |
8244 |
++ XFS_DIFLAG_IXUNLINK) |
8245 |
++ |
8246 |
++#define XFS_DIVFLAG_BARRIER 0x01 |
8247 |
++#define XFS_DIVFLAG_COW 0x02 |
8248 |
+ |
8249 |
+ #endif /* __XFS_DINODE_H__ */ |
8250 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/xfs_fs.h linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_fs.h |
8251 |
+--- linux-2.6.29.4/fs/xfs/xfs_fs.h 2009-03-24 14:22:37.000000000 +0100 |
8252 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_fs.h 2009-03-24 14:48:35.000000000 +0100 |
8253 |
+@@ -67,6 +67,9 @@ struct fsxattr { |
8254 |
+ #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ |
8255 |
+ #define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */ |
8256 |
+ #define XFS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */ |
8257 |
++#define XFS_XFLAG_IXUNLINK 0x00008000 /* immutable invert on unlink */ |
8258 |
++#define XFS_XFLAG_BARRIER 0x10000000 /* chroot() barrier */ |
8259 |
++#define XFS_XFLAG_COW 0x20000000 /* copy on write mark */ |
8260 |
+ #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ |
8261 |
+ |
8262 |
+ /* |
8263 |
+@@ -289,7 +292,8 @@ typedef struct xfs_bstat { |
8264 |
+ __s32 bs_extents; /* number of extents */ |
8265 |
+ __u32 bs_gen; /* generation count */ |
8266 |
+ __u16 bs_projid; /* project id */ |
8267 |
+- unsigned char bs_pad[14]; /* pad space, unused */ |
8268 |
++ __u16 bs_tag; /* context tagging */ |
8269 |
++ unsigned char bs_pad[12]; /* pad space, unused */ |
8270 |
+ __u32 bs_dmevmask; /* DMIG event mask */ |
8271 |
+ __u16 bs_dmstate; /* DMIG state info */ |
8272 |
+ __u16 bs_aextents; /* attribute number of extents */ |
8273 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/xfs_ialloc.c linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_ialloc.c |
8274 |
+--- linux-2.6.29.4/fs/xfs/xfs_ialloc.c 2009-03-24 14:22:37.000000000 +0100 |
8275 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_ialloc.c 2009-03-24 17:03:17.000000000 +0100 |
8276 |
+@@ -41,7 +41,6 @@ |
8277 |
+ #include "xfs_error.h" |
8278 |
+ #include "xfs_bmap.h" |
8279 |
+ |
8280 |
+- |
8281 |
+ /* |
8282 |
+ * Allocation group level functions. |
8283 |
+ */ |
8284 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/xfs_inode.c linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_inode.c |
8285 |
+--- linux-2.6.29.4/fs/xfs/xfs_inode.c 2009-03-24 14:22:37.000000000 +0100 |
8286 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_inode.c 2009-03-25 01:42:50.000000000 +0100 |
8287 |
+@@ -250,6 +250,7 @@ xfs_inotobp( |
8288 |
+ return 0; |
8289 |
+ } |
8290 |
+ |
8291 |
++#include <linux/vs_tag.h> |
8292 |
+ |
8293 |
+ /* |
8294 |
+ * This routine is called to map an inode to the buffer containing |
8295 |
+@@ -645,15 +646,25 @@ xfs_iformat_btree( |
8296 |
+ void |
8297 |
+ xfs_dinode_from_disk( |
8298 |
+ xfs_icdinode_t *to, |
8299 |
+- xfs_dinode_t *from) |
8300 |
++ xfs_dinode_t *from, |
8301 |
++ int tagged) |
8302 |
+ { |
8303 |
++ uint32_t uid, gid, tag; |
8304 |
++ |
8305 |
+ to->di_magic = be16_to_cpu(from->di_magic); |
8306 |
+ to->di_mode = be16_to_cpu(from->di_mode); |
8307 |
+ to->di_version = from ->di_version; |
8308 |
+ to->di_format = from->di_format; |
8309 |
+ to->di_onlink = be16_to_cpu(from->di_onlink); |
8310 |
+- to->di_uid = be32_to_cpu(from->di_uid); |
8311 |
+- to->di_gid = be32_to_cpu(from->di_gid); |
8312 |
++ |
8313 |
++ uid = be32_to_cpu(from->di_uid); |
8314 |
++ gid = be32_to_cpu(from->di_gid); |
8315 |
++ tag = be16_to_cpu(from->di_tag); |
8316 |
++ |
8317 |
++ to->di_uid = INOTAG_UID(tagged, uid, gid); |
8318 |
++ to->di_gid = INOTAG_GID(tagged, uid, gid); |
8319 |
++ to->di_tag = INOTAG_TAG(tagged, uid, gid, tag); |
8320 |
++ |
8321 |
+ to->di_nlink = be32_to_cpu(from->di_nlink); |
8322 |
+ to->di_projid = be16_to_cpu(from->di_projid); |
8323 |
+ memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); |
8324 |
+@@ -674,21 +685,26 @@ xfs_dinode_from_disk( |
8325 |
+ to->di_dmevmask = be32_to_cpu(from->di_dmevmask); |
8326 |
+ to->di_dmstate = be16_to_cpu(from->di_dmstate); |
8327 |
+ to->di_flags = be16_to_cpu(from->di_flags); |
8328 |
++ to->di_vflags = be16_to_cpu(from->di_vflags); |
8329 |
+ to->di_gen = be32_to_cpu(from->di_gen); |
8330 |
+ } |
8331 |
+ |
8332 |
+ void |
8333 |
+ xfs_dinode_to_disk( |
8334 |
+ xfs_dinode_t *to, |
8335 |
+- xfs_icdinode_t *from) |
8336 |
++ xfs_icdinode_t *from, |
8337 |
++ int tagged) |
8338 |
+ { |
8339 |
+ to->di_magic = cpu_to_be16(from->di_magic); |
8340 |
+ to->di_mode = cpu_to_be16(from->di_mode); |
8341 |
+ to->di_version = from ->di_version; |
8342 |
+ to->di_format = from->di_format; |
8343 |
+ to->di_onlink = cpu_to_be16(from->di_onlink); |
8344 |
+- to->di_uid = cpu_to_be32(from->di_uid); |
8345 |
+- to->di_gid = cpu_to_be32(from->di_gid); |
8346 |
++ |
8347 |
++ to->di_uid = cpu_to_be32(TAGINO_UID(tagged, from->di_uid, from->di_tag)); |
8348 |
++ to->di_gid = cpu_to_be32(TAGINO_GID(tagged, from->di_gid, from->di_tag)); |
8349 |
++ to->di_tag = cpu_to_be16(TAGINO_TAG(tagged, from->di_tag)); |
8350 |
++ |
8351 |
+ to->di_nlink = cpu_to_be32(from->di_nlink); |
8352 |
+ to->di_projid = cpu_to_be16(from->di_projid); |
8353 |
+ memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); |
8354 |
+@@ -709,12 +725,14 @@ xfs_dinode_to_disk( |
8355 |
+ to->di_dmevmask = cpu_to_be32(from->di_dmevmask); |
8356 |
+ to->di_dmstate = cpu_to_be16(from->di_dmstate); |
8357 |
+ to->di_flags = cpu_to_be16(from->di_flags); |
8358 |
++ to->di_vflags = cpu_to_be16(from->di_vflags); |
8359 |
+ to->di_gen = cpu_to_be32(from->di_gen); |
8360 |
+ } |
8361 |
+ |
8362 |
+ STATIC uint |
8363 |
+ _xfs_dic2xflags( |
8364 |
+- __uint16_t di_flags) |
8365 |
++ __uint16_t di_flags, |
8366 |
++ __uint16_t di_vflags) |
8367 |
+ { |
8368 |
+ uint flags = 0; |
8369 |
+ |
8370 |
+@@ -725,6 +743,8 @@ _xfs_dic2xflags( |
8371 |
+ flags |= XFS_XFLAG_PREALLOC; |
8372 |
+ if (di_flags & XFS_DIFLAG_IMMUTABLE) |
8373 |
+ flags |= XFS_XFLAG_IMMUTABLE; |
8374 |
++ if (di_flags & XFS_DIFLAG_IXUNLINK) |
8375 |
++ flags |= XFS_XFLAG_IXUNLINK; |
8376 |
+ if (di_flags & XFS_DIFLAG_APPEND) |
8377 |
+ flags |= XFS_XFLAG_APPEND; |
8378 |
+ if (di_flags & XFS_DIFLAG_SYNC) |
8379 |
+@@ -749,6 +769,10 @@ _xfs_dic2xflags( |
8380 |
+ flags |= XFS_XFLAG_FILESTREAM; |
8381 |
+ } |
8382 |
+ |
8383 |
++ if (di_vflags & XFS_DIVFLAG_BARRIER) |
8384 |
++ flags |= FS_BARRIER_FL; |
8385 |
++ if (di_vflags & XFS_DIVFLAG_COW) |
8386 |
++ flags |= FS_COW_FL; |
8387 |
+ return flags; |
8388 |
+ } |
8389 |
+ |
8390 |
+@@ -758,7 +782,7 @@ xfs_ip2xflags( |
8391 |
+ { |
8392 |
+ xfs_icdinode_t *dic = &ip->i_d; |
8393 |
+ |
8394 |
+- return _xfs_dic2xflags(dic->di_flags) | |
8395 |
++ return _xfs_dic2xflags(dic->di_flags, dic->di_vflags) | |
8396 |
+ (XFS_IFORK_Q(ip) ? XFS_XFLAG_HASATTR : 0); |
8397 |
+ } |
8398 |
+ |
8399 |
+@@ -766,7 +790,8 @@ uint |
8400 |
+ xfs_dic2xflags( |
8401 |
+ xfs_dinode_t *dip) |
8402 |
+ { |
8403 |
+- return _xfs_dic2xflags(be16_to_cpu(dip->di_flags)) | |
8404 |
++ return _xfs_dic2xflags(be16_to_cpu(dip->di_flags), |
8405 |
++ be16_to_cpu(dip->di_vflags)) | |
8406 |
+ (XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0); |
8407 |
+ } |
8408 |
+ |
8409 |
+@@ -802,7 +827,6 @@ xfs_iread( |
8410 |
+ if (error) |
8411 |
+ return error; |
8412 |
+ dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); |
8413 |
+- |
8414 |
+ /* |
8415 |
+ * If we got something that isn't an inode it means someone |
8416 |
+ * (nfs or dmi) has a stale handle. |
8417 |
+@@ -827,7 +851,8 @@ xfs_iread( |
8418 |
+ * Otherwise, just get the truly permanent information. |
8419 |
+ */ |
8420 |
+ if (dip->di_mode) { |
8421 |
+- xfs_dinode_from_disk(&ip->i_d, dip); |
8422 |
++ xfs_dinode_from_disk(&ip->i_d, dip, |
8423 |
++ mp->m_flags & XFS_MOUNT_TAGGED); |
8424 |
+ error = xfs_iformat(ip, dip); |
8425 |
+ if (error) { |
8426 |
+ #ifdef DEBUG |
8427 |
+@@ -1027,6 +1052,7 @@ xfs_ialloc( |
8428 |
+ ASSERT(ip->i_d.di_nlink == nlink); |
8429 |
+ ip->i_d.di_uid = current_fsuid(); |
8430 |
+ ip->i_d.di_gid = current_fsgid(); |
8431 |
++ ip->i_d.di_tag = current_fstag(cr, &ip->i_vnode); |
8432 |
+ ip->i_d.di_projid = prid; |
8433 |
+ memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); |
8434 |
+ |
8435 |
+@@ -1087,6 +1113,7 @@ xfs_ialloc( |
8436 |
+ ip->i_d.di_dmevmask = 0; |
8437 |
+ ip->i_d.di_dmstate = 0; |
8438 |
+ ip->i_d.di_flags = 0; |
8439 |
++ ip->i_d.di_vflags = 0; |
8440 |
+ flags = XFS_ILOG_CORE; |
8441 |
+ switch (mode & S_IFMT) { |
8442 |
+ case S_IFIFO: |
8443 |
+@@ -2161,6 +2188,7 @@ xfs_ifree( |
8444 |
+ } |
8445 |
+ ip->i_d.di_mode = 0; /* mark incore inode as free */ |
8446 |
+ ip->i_d.di_flags = 0; |
8447 |
++ ip->i_d.di_vflags = 0; |
8448 |
+ ip->i_d.di_dmevmask = 0; |
8449 |
+ ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ |
8450 |
+ ip->i_df.if_ext_max = |
8451 |
+@@ -3128,7 +3156,8 @@ xfs_iflush_int( |
8452 |
+ * because if the inode is dirty at all the core must |
8453 |
+ * be. |
8454 |
+ */ |
8455 |
+- xfs_dinode_to_disk(dip, &ip->i_d); |
8456 |
++ xfs_dinode_to_disk(dip, &ip->i_d, |
8457 |
++ mp->m_flags & XFS_MOUNT_TAGGED); |
8458 |
+ |
8459 |
+ /* Wrap, we never let the log put out DI_MAX_FLUSH */ |
8460 |
+ if (ip->i_d.di_flushiter == DI_MAX_FLUSH) |
8461 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/xfs_inode.h linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_inode.h |
8462 |
+--- linux-2.6.29.4/fs/xfs/xfs_inode.h 2009-03-24 14:22:37.000000000 +0100 |
8463 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_inode.h 2009-03-25 01:10:35.000000000 +0100 |
8464 |
+@@ -134,7 +134,9 @@ typedef struct xfs_icdinode { |
8465 |
+ __uint32_t di_gid; /* owner's group id */ |
8466 |
+ __uint32_t di_nlink; /* number of links to file */ |
8467 |
+ __uint16_t di_projid; /* owner's project id */ |
8468 |
+- __uint8_t di_pad[8]; /* unused, zeroed space */ |
8469 |
++ __uint16_t di_tag; /* context tagging */ |
8470 |
++ __uint16_t di_vflags; /* vserver specific flags */ |
8471 |
++ __uint8_t di_pad[4]; /* unused, zeroed space */ |
8472 |
+ __uint16_t di_flushiter; /* incremented on flush */ |
8473 |
+ xfs_ictimestamp_t di_atime; /* time last accessed */ |
8474 |
+ xfs_ictimestamp_t di_mtime; /* time last modified */ |
8475 |
+@@ -589,9 +591,9 @@ int xfs_itobp(struct xfs_mount *, struc |
8476 |
+ int xfs_iread(struct xfs_mount *, struct xfs_trans *, |
8477 |
+ struct xfs_inode *, xfs_daddr_t, uint); |
8478 |
+ void xfs_dinode_from_disk(struct xfs_icdinode *, |
8479 |
+- struct xfs_dinode *); |
8480 |
++ struct xfs_dinode *, int); |
8481 |
+ void xfs_dinode_to_disk(struct xfs_dinode *, |
8482 |
+- struct xfs_icdinode *); |
8483 |
++ struct xfs_icdinode *, int); |
8484 |
+ void xfs_idestroy_fork(struct xfs_inode *, int); |
8485 |
+ void xfs_idata_realloc(struct xfs_inode *, int, int); |
8486 |
+ void xfs_iroot_realloc(struct xfs_inode *, int, int); |
8487 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/xfs_itable.c linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_itable.c |
8488 |
+--- linux-2.6.29.4/fs/xfs/xfs_itable.c 2009-03-24 14:22:37.000000000 +0100 |
8489 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_itable.c 2009-03-24 14:48:35.000000000 +0100 |
8490 |
+@@ -82,6 +82,7 @@ xfs_bulkstat_one_iget( |
8491 |
+ buf->bs_mode = dic->di_mode; |
8492 |
+ buf->bs_uid = dic->di_uid; |
8493 |
+ buf->bs_gid = dic->di_gid; |
8494 |
++ buf->bs_tag = dic->di_tag; |
8495 |
+ buf->bs_size = dic->di_size; |
8496 |
+ vn_atime_to_bstime(VFS_I(ip), &buf->bs_atime); |
8497 |
+ buf->bs_mtime.tv_sec = dic->di_mtime.t_sec; |
8498 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/xfs_log_recover.c linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_log_recover.c |
8499 |
+--- linux-2.6.29.4/fs/xfs/xfs_log_recover.c 2009-03-24 14:22:37.000000000 +0100 |
8500 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_log_recover.c 2009-03-24 17:17:15.000000000 +0100 |
8501 |
+@@ -2421,7 +2421,8 @@ xlog_recover_do_inode_trans( |
8502 |
+ } |
8503 |
+ |
8504 |
+ /* The core is in in-core format */ |
8505 |
+- xfs_dinode_to_disk(dip, (xfs_icdinode_t *)item->ri_buf[1].i_addr); |
8506 |
++ xfs_dinode_to_disk(dip, (xfs_icdinode_t *)item->ri_buf[1].i_addr, |
8507 |
++ mp->m_flags & XFS_MOUNT_TAGGED); |
8508 |
+ |
8509 |
+ /* the rest is in on-disk format */ |
8510 |
+ if (item->ri_buf[1].i_len > sizeof(struct xfs_icdinode)) { |
8511 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/xfs_mount.h linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_mount.h |
8512 |
+--- linux-2.6.29.4/fs/xfs/xfs_mount.h 2009-03-24 14:22:37.000000000 +0100 |
8513 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_mount.h 2009-03-24 14:48:35.000000000 +0100 |
8514 |
+@@ -371,6 +371,7 @@ typedef struct xfs_mount { |
8515 |
+ allocator */ |
8516 |
+ #define XFS_MOUNT_NOATTR2 (1ULL << 25) /* disable use of attr2 format */ |
8517 |
+ |
8518 |
++#define XFS_MOUNT_TAGGED (1ULL << 31) /* context tagging */ |
8519 |
+ |
8520 |
+ /* |
8521 |
+ * Default minimum read and write sizes. |
8522 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/xfs_vnodeops.c linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_vnodeops.c |
8523 |
+--- linux-2.6.29.4/fs/xfs/xfs_vnodeops.c 2009-03-24 14:22:37.000000000 +0100 |
8524 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_vnodeops.c 2009-03-24 17:18:40.000000000 +0100 |
8525 |
+@@ -53,6 +53,90 @@ |
8526 |
+ #include "xfs_filestream.h" |
8527 |
+ #include "xfs_vnodeops.h" |
8528 |
+ |
8529 |
++ |
8530 |
++STATIC void |
8531 |
++xfs_get_inode_flags( |
8532 |
++ xfs_inode_t *ip) |
8533 |
++{ |
8534 |
++ struct inode *inode = VFS_I(ip); |
8535 |
++ unsigned int flags = inode->i_flags; |
8536 |
++ unsigned int vflags = inode->i_vflags; |
8537 |
++ |
8538 |
++ if (flags & S_IMMUTABLE) |
8539 |
++ ip->i_d.di_flags |= XFS_DIFLAG_IMMUTABLE; |
8540 |
++ else |
8541 |
++ ip->i_d.di_flags &= ~XFS_DIFLAG_IMMUTABLE; |
8542 |
++ if (flags & S_IXUNLINK) |
8543 |
++ ip->i_d.di_flags |= XFS_DIFLAG_IXUNLINK; |
8544 |
++ else |
8545 |
++ ip->i_d.di_flags &= ~XFS_DIFLAG_IXUNLINK; |
8546 |
++ |
8547 |
++ if (vflags & V_BARRIER) |
8548 |
++ ip->i_d.di_vflags |= XFS_DIVFLAG_BARRIER; |
8549 |
++ else |
8550 |
++ ip->i_d.di_vflags &= ~XFS_DIVFLAG_BARRIER; |
8551 |
++ if (vflags & V_COW) |
8552 |
++ ip->i_d.di_vflags |= XFS_DIVFLAG_COW; |
8553 |
++ else |
8554 |
++ ip->i_d.di_vflags &= ~XFS_DIVFLAG_COW; |
8555 |
++} |
8556 |
++ |
8557 |
++int |
8558 |
++xfs_sync_xflags( |
8559 |
++ xfs_inode_t *ip) |
8560 |
++{ |
8561 |
++ struct xfs_mount *mp = ip->i_mount; |
8562 |
++ struct xfs_trans *tp; |
8563 |
++ unsigned int lock_flags = 0; |
8564 |
++ int code; |
8565 |
++ |
8566 |
++ xfs_itrace_entry(ip); |
8567 |
++ |
8568 |
++ if (mp->m_flags & XFS_MOUNT_RDONLY) |
8569 |
++ return XFS_ERROR(EROFS); |
8570 |
++ |
8571 |
++ /* |
8572 |
++ * we acquire the inode lock and do an error checking pass. |
8573 |
++ */ |
8574 |
++ tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); |
8575 |
++ code = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0); |
8576 |
++ if (code) |
8577 |
++ goto error_return; |
8578 |
++ |
8579 |
++ lock_flags = XFS_ILOCK_EXCL; |
8580 |
++ xfs_ilock(ip, lock_flags); |
8581 |
++ |
8582 |
++ xfs_trans_ijoin(tp, ip, lock_flags); |
8583 |
++ xfs_trans_ihold(tp, ip); |
8584 |
++ |
8585 |
++ xfs_get_inode_flags(ip); |
8586 |
++ // xfs_diflags_to_linux(ip); |
8587 |
++ |
8588 |
++ xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
8589 |
++ xfs_ichgtime(ip, XFS_ICHGTIME_CHG); |
8590 |
++ |
8591 |
++ XFS_STATS_INC(xs_ig_attrchg); |
8592 |
++ |
8593 |
++ /* |
8594 |
++ * If this is a synchronous mount, make sure that the |
8595 |
++ * transaction goes to disk before returning to the user. |
8596 |
++ */ |
8597 |
++ if (mp->m_flags & XFS_MOUNT_WSYNC) |
8598 |
++ xfs_trans_set_sync(tp); |
8599 |
++ code = xfs_trans_commit(tp, 0); |
8600 |
++ xfs_iunlock(ip, lock_flags); |
8601 |
++ |
8602 |
++ if (code) |
8603 |
++ return code; |
8604 |
++ return 0; |
8605 |
++ |
8606 |
++ error_return: |
8607 |
++ xfs_trans_cancel(tp, 0); |
8608 |
++ if (lock_flags) |
8609 |
++ xfs_iunlock(ip, lock_flags); |
8610 |
++ return code; |
8611 |
++} |
8612 |
++ |
8613 |
+ int |
8614 |
+ xfs_setattr( |
8615 |
+ struct xfs_inode *ip, |
8616 |
+@@ -68,6 +152,7 @@ xfs_setattr( |
8617 |
+ uint commit_flags=0; |
8618 |
+ uid_t uid=0, iuid=0; |
8619 |
+ gid_t gid=0, igid=0; |
8620 |
++ tag_t tag=0, itag=0; |
8621 |
+ int timeflags = 0; |
8622 |
+ struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; |
8623 |
+ int need_iolock = 1; |
8624 |
+@@ -164,7 +249,7 @@ xfs_setattr( |
8625 |
+ /* |
8626 |
+ * Change file ownership. Must be the owner or privileged. |
8627 |
+ */ |
8628 |
+- if (mask & (ATTR_UID|ATTR_GID)) { |
8629 |
++ if (mask & (ATTR_UID|ATTR_GID|ATTR_TAG)) { |
8630 |
+ /* |
8631 |
+ * These IDs could have changed since we last looked at them. |
8632 |
+ * But, we're assured that if the ownership did change |
8633 |
+@@ -173,15 +258,19 @@ xfs_setattr( |
8634 |
+ */ |
8635 |
+ iuid = ip->i_d.di_uid; |
8636 |
+ igid = ip->i_d.di_gid; |
8637 |
++ itag = ip->i_d.di_tag; |
8638 |
+ gid = (mask & ATTR_GID) ? iattr->ia_gid : igid; |
8639 |
+ uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid; |
8640 |
++ tag = (mask & ATTR_TAG) ? iattr->ia_tag : itag; |
8641 |
+ |
8642 |
+ /* |
8643 |
+ * Do a quota reservation only if uid/gid is actually |
8644 |
+ * going to change. |
8645 |
+ */ |
8646 |
+ if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || |
8647 |
+- (XFS_IS_GQUOTA_ON(mp) && igid != gid)) { |
8648 |
++ (XFS_IS_GQUOTA_ON(mp) && igid != gid) || |
8649 |
++ (XFS_IS_GQUOTA_ON(mp) && itag != tag)) { |
8650 |
++ /* TODO: handle tagging? */ |
8651 |
+ ASSERT(tp); |
8652 |
+ code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, |
8653 |
+ capable(CAP_FOWNER) ? |
8654 |
+@@ -334,7 +423,7 @@ xfs_setattr( |
8655 |
+ /* |
8656 |
+ * Change file ownership. Must be the owner or privileged. |
8657 |
+ */ |
8658 |
+- if (mask & (ATTR_UID|ATTR_GID)) { |
8659 |
++ if (mask & (ATTR_UID|ATTR_GID|ATTR_TAG)) { |
8660 |
+ /* |
8661 |
+ * CAP_FSETID overrides the following restrictions: |
8662 |
+ * |
8663 |
+@@ -350,6 +439,10 @@ xfs_setattr( |
8664 |
+ * Change the ownerships and register quota modifications |
8665 |
+ * in the transaction. |
8666 |
+ */ |
8667 |
++ if (itag != tag) { |
8668 |
++ ip->i_d.di_tag = tag; |
8669 |
++ inode->i_tag = tag; |
8670 |
++ } |
8671 |
+ if (iuid != uid) { |
8672 |
+ if (XFS_IS_UQUOTA_ON(mp)) { |
8673 |
+ ASSERT(mask & ATTR_UID); |
8674 |
+diff -NurpP --minimal linux-2.6.29.4/fs/xfs/xfs_vnodeops.h linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_vnodeops.h |
8675 |
+--- linux-2.6.29.4/fs/xfs/xfs_vnodeops.h 2009-03-24 14:22:37.000000000 +0100 |
8676 |
++++ linux-2.6.29.4-vs2.3.0.36.14/fs/xfs/xfs_vnodeops.h 2009-03-24 17:19:30.000000000 +0100 |
8677 |
+@@ -14,6 +14,7 @@ struct xfs_inode; |
8678 |
+ struct xfs_iomap; |
8679 |
+ |
8680 |
+ |
8681 |
++int xfs_sync_xflags(struct xfs_inode *ip); |
8682 |
+ int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags); |
8683 |
+ #define XFS_ATTR_DMI 0x01 /* invocation from a DMI function */ |
8684 |
+ #define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */ |
8685 |
+diff -NurpP --minimal linux-2.6.29.4/include/asm-generic/tlb.h linux-2.6.29.4-vs2.3.0.36.14/include/asm-generic/tlb.h |
8686 |
+--- linux-2.6.29.4/include/asm-generic/tlb.h 2008-12-25 00:26:37.000000000 +0100 |
8687 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/asm-generic/tlb.h 2009-04-08 15:50:06.000000000 +0200 |
8688 |
+@@ -14,6 +14,7 @@ |
8689 |
+ #define _ASM_GENERIC__TLB_H |
8690 |
+ |
8691 |
+ #include <linux/swap.h> |
8692 |
++#include <linux/vs_memory.h> |
8693 |
+ #include <asm/pgalloc.h> |
8694 |
+ #include <asm/tlbflush.h> |
8695 |
+ |
8696 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/capability.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/capability.h |
8697 |
+--- linux-2.6.29.4/include/linux/capability.h 2009-05-23 23:16:53.000000000 +0200 |
8698 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/capability.h 2009-04-30 12:14:53.000000000 +0200 |
8699 |
+@@ -285,6 +285,7 @@ struct cpu_vfs_cap_data { |
8700 |
+ arbitrary SCSI commands */ |
8701 |
+ /* Allow setting encryption key on loopback filesystem */ |
8702 |
+ /* Allow setting zone reclaim policy */ |
8703 |
++/* Allow the selection of a security context */ |
8704 |
+ |
8705 |
+ #define CAP_SYS_ADMIN 21 |
8706 |
+ |
8707 |
+@@ -357,7 +358,13 @@ struct cpu_vfs_cap_data { |
8708 |
+ |
8709 |
+ #define CAP_MAC_ADMIN 33 |
8710 |
+ |
8711 |
+-#define CAP_LAST_CAP CAP_MAC_ADMIN |
8712 |
++/* Allow context manipulations */ |
8713 |
++/* Allow changing context info on files */ |
8714 |
++ |
8715 |
++#define CAP_CONTEXT 34 |
8716 |
++ |
8717 |
++ |
8718 |
++#define CAP_LAST_CAP CAP_CONTEXT |
8719 |
+ |
8720 |
+ #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) |
8721 |
+ |
8722 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/devpts_fs.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/devpts_fs.h |
8723 |
+--- linux-2.6.29.4/include/linux/devpts_fs.h 2008-12-25 00:26:37.000000000 +0100 |
8724 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/devpts_fs.h 2009-02-22 22:54:26.000000000 +0100 |
8725 |
+@@ -45,5 +45,4 @@ static inline void devpts_pty_kill(struc |
8726 |
+ |
8727 |
+ #endif |
8728 |
+ |
8729 |
+- |
8730 |
+ #endif /* _LINUX_DEVPTS_FS_H */ |
8731 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/ext2_fs.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/ext2_fs.h |
8732 |
+--- linux-2.6.29.4/include/linux/ext2_fs.h 2009-03-24 14:22:41.000000000 +0100 |
8733 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/ext2_fs.h 2009-03-24 15:39:54.000000000 +0100 |
8734 |
+@@ -189,8 +189,12 @@ struct ext2_group_desc |
8735 |
+ #define EXT2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */ |
8736 |
+ #define EXT2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */ |
8737 |
+ #define EXT2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/ |
8738 |
++#define EXT2_IXUNLINK_FL FS_IXUNLINK_FL /* Immutable invert on unlink */ |
8739 |
+ #define EXT2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */ |
8740 |
+ |
8741 |
++#define EXT2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */ |
8742 |
++#define EXT2_COW_FL FS_COW_FL /* Copy on Write marker */ |
8743 |
++ |
8744 |
+ #define EXT2_FL_USER_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */ |
8745 |
+ #define EXT2_FL_USER_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */ |
8746 |
+ |
8747 |
+@@ -271,7 +275,7 @@ struct ext2_inode { |
8748 |
+ struct { |
8749 |
+ __u8 l_i_frag; /* Fragment number */ |
8750 |
+ __u8 l_i_fsize; /* Fragment size */ |
8751 |
+- __u16 i_pad1; |
8752 |
++ __u16 l_i_tag; /* Context Tag */ |
8753 |
+ __le16 l_i_uid_high; /* these 2 fields */ |
8754 |
+ __le16 l_i_gid_high; /* were reserved2[0] */ |
8755 |
+ __u32 l_i_reserved2; |
8756 |
+@@ -303,6 +307,7 @@ struct ext2_inode { |
8757 |
+ #define i_gid_low i_gid |
8758 |
+ #define i_uid_high osd2.linux2.l_i_uid_high |
8759 |
+ #define i_gid_high osd2.linux2.l_i_gid_high |
8760 |
++#define i_raw_tag osd2.linux2.l_i_tag |
8761 |
+ #define i_reserved2 osd2.linux2.l_i_reserved2 |
8762 |
+ #endif |
8763 |
+ |
8764 |
+@@ -347,6 +352,7 @@ struct ext2_inode { |
8765 |
+ #define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */ |
8766 |
+ #define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */ |
8767 |
+ #define EXT2_MOUNT_RESERVATION 0x080000 /* Preallocation */ |
8768 |
++#define EXT2_MOUNT_TAGGED (1<<24) /* Enable Context Tags */ |
8769 |
+ |
8770 |
+ |
8771 |
+ #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt |
8772 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/ext3_fs.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/ext3_fs.h |
8773 |
+--- linux-2.6.29.4/include/linux/ext3_fs.h 2009-03-24 14:22:41.000000000 +0100 |
8774 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/ext3_fs.h 2009-03-24 14:48:36.000000000 +0100 |
8775 |
+@@ -173,10 +173,14 @@ struct ext3_group_desc |
8776 |
+ #define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */ |
8777 |
+ #define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ |
8778 |
+ #define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ |
8779 |
++#define EXT3_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */ |
8780 |
+ #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ |
8781 |
+ |
8782 |
+-#define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ |
8783 |
+-#define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ |
8784 |
++#define EXT3_BARRIER_FL 0x04000000 /* Barrier for chroot() */ |
8785 |
++#define EXT3_COW_FL 0x20000000 /* Copy on Write marker */ |
8786 |
++ |
8787 |
++#define EXT3_FL_USER_VISIBLE 0x0103DFFF /* User visible flags */ |
8788 |
++#define EXT3_FL_USER_MODIFIABLE 0x010380FF /* User modifiable flags */ |
8789 |
+ |
8790 |
+ /* Flags that should be inherited by new inodes from their parent. */ |
8791 |
+ #define EXT3_FL_INHERITED (EXT3_SECRM_FL | EXT3_UNRM_FL | EXT3_COMPR_FL |\ |
8792 |
+@@ -316,7 +320,7 @@ struct ext3_inode { |
8793 |
+ struct { |
8794 |
+ __u8 l_i_frag; /* Fragment number */ |
8795 |
+ __u8 l_i_fsize; /* Fragment size */ |
8796 |
+- __u16 i_pad1; |
8797 |
++ __u16 l_i_tag; /* Context Tag */ |
8798 |
+ __le16 l_i_uid_high; /* these 2 fields */ |
8799 |
+ __le16 l_i_gid_high; /* were reserved2[0] */ |
8800 |
+ __u32 l_i_reserved2; |
8801 |
+@@ -350,6 +354,7 @@ struct ext3_inode { |
8802 |
+ #define i_gid_low i_gid |
8803 |
+ #define i_uid_high osd2.linux2.l_i_uid_high |
8804 |
+ #define i_gid_high osd2.linux2.l_i_gid_high |
8805 |
++#define i_raw_tag osd2.linux2.l_i_tag |
8806 |
+ #define i_reserved2 osd2.linux2.l_i_reserved2 |
8807 |
+ |
8808 |
+ #elif defined(__GNU__) |
8809 |
+@@ -413,6 +418,7 @@ struct ext3_inode { |
8810 |
+ #define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ |
8811 |
+ #define EXT3_MOUNT_DATA_ERR_ABORT 0x400000 /* Abort on file data write |
8812 |
+ * error in ordered mode */ |
8813 |
++#define EXT3_MOUNT_TAGGED (1<<24) /* Enable Context Tags */ |
8814 |
+ |
8815 |
+ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ |
8816 |
+ #ifndef _LINUX_EXT2_FS_H |
8817 |
+@@ -874,6 +880,7 @@ struct buffer_head * ext3_bread (handle_ |
8818 |
+ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, |
8819 |
+ sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result, |
8820 |
+ int create, int extend_disksize); |
8821 |
++extern int ext3_sync_flags(struct inode *inode); |
8822 |
+ |
8823 |
+ extern struct inode *ext3_iget(struct super_block *, unsigned long); |
8824 |
+ extern int ext3_write_inode (struct inode *, int); |
8825 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/fs.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/fs.h |
8826 |
+--- linux-2.6.29.4/include/linux/fs.h 2009-03-24 14:22:41.000000000 +0100 |
8827 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/fs.h 2009-03-24 17:21:20.000000000 +0100 |
8828 |
+@@ -141,6 +141,9 @@ struct inodes_stat_t { |
8829 |
+ #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ |
8830 |
+ #define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ |
8831 |
+ #define MS_I_VERSION (1<<23) /* Update inode I_version field */ |
8832 |
++#define MS_TAGGED (1<<24) /* use generic inode tagging */ |
8833 |
++#define MS_TAGID (1<<25) /* use specific tag for this mount */ |
8834 |
++#define MS_NOTAGCHECK (1<<26) /* don't check tags */ |
8835 |
+ #define MS_ACTIVE (1<<30) |
8836 |
+ #define MS_NOUSER (1<<31) |
8837 |
+ |
8838 |
+@@ -167,6 +170,14 @@ struct inodes_stat_t { |
8839 |
+ #define S_NOCMTIME 128 /* Do not update file c/mtime */ |
8840 |
+ #define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */ |
8841 |
+ #define S_PRIVATE 512 /* Inode is fs-internal */ |
8842 |
++#define S_IXUNLINK 1024 /* Immutable Invert on unlink */ |
8843 |
++ |
8844 |
++/* Linux-VServer related Inode flags */ |
8845 |
++ |
8846 |
++#define V_VALID 1 |
8847 |
++#define V_XATTR 2 |
8848 |
++#define V_BARRIER 4 /* Barrier for chroot() */ |
8849 |
++#define V_COW 8 /* Copy on Write */ |
8850 |
+ |
8851 |
+ /* |
8852 |
+ * Note that nosuid etc flags are inode-specific: setting some file-system |
8853 |
+@@ -189,12 +200,15 @@ struct inodes_stat_t { |
8854 |
+ #define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \ |
8855 |
+ ((inode)->i_flags & (S_SYNC|S_DIRSYNC))) |
8856 |
+ #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK) |
8857 |
+-#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME) |
8858 |
+-#define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION) |
8859 |
++#define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME) |
8860 |
++#define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION) |
8861 |
++#define IS_TAGGED(inode) __IS_FLG(inode, MS_TAGGED) |
8862 |
+ |
8863 |
+ #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) |
8864 |
+ #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) |
8865 |
+ #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) |
8866 |
++#define IS_IXUNLINK(inode) ((inode)->i_flags & S_IXUNLINK) |
8867 |
++#define IS_IXORUNLINK(inode) ((IS_IXUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode)) |
8868 |
+ #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) |
8869 |
+ |
8870 |
+ #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) |
8871 |
+@@ -202,6 +216,16 @@ struct inodes_stat_t { |
8872 |
+ #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) |
8873 |
+ #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE) |
8874 |
+ |
8875 |
++#define IS_BARRIER(inode) (S_ISDIR((inode)->i_mode) && ((inode)->i_vflags & V_BARRIER)) |
8876 |
++ |
8877 |
++#ifdef CONFIG_VSERVER_COWBL |
8878 |
++# define IS_COW(inode) (IS_IXUNLINK(inode) && IS_IMMUTABLE(inode)) |
8879 |
++# define IS_COW_LINK(inode) (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1)) |
8880 |
++#else |
8881 |
++# define IS_COW(inode) (0) |
8882 |
++# define IS_COW_LINK(inode) (0) |
8883 |
++#endif |
8884 |
++ |
8885 |
+ /* the read-only stuff doesn't really belong here, but any other place is |
8886 |
+ probably as bad and I don't want to create yet another include file. */ |
8887 |
+ |
8888 |
+@@ -279,11 +303,14 @@ struct inodes_stat_t { |
8889 |
+ #define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ |
8890 |
+ #define FS_EXTENT_FL 0x00080000 /* Extents */ |
8891 |
+ #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */ |
8892 |
++#define FS_IXUNLINK_FL 0x08000000 /* Immutable invert on unlink */ |
8893 |
+ #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ |
8894 |
+ |
8895 |
+-#define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ |
8896 |
+-#define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ |
8897 |
++#define FS_BARRIER_FL 0x04000000 /* Barrier for chroot() */ |
8898 |
++#define FS_COW_FL 0x20000000 /* Copy on Write marker */ |
8899 |
+ |
8900 |
++#define FS_FL_USER_VISIBLE 0x0103DFFF /* User visible flags */ |
8901 |
++#define FS_FL_USER_MODIFIABLE 0x010380FF /* User modifiable flags */ |
8902 |
+ |
8903 |
+ #define SYNC_FILE_RANGE_WAIT_BEFORE 1 |
8904 |
+ #define SYNC_FILE_RANGE_WRITE 2 |
8905 |
+@@ -365,6 +392,7 @@ typedef void (dio_iodone_t)(struct kiocb |
8906 |
+ #define ATTR_KILL_PRIV (1 << 14) |
8907 |
+ #define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */ |
8908 |
+ #define ATTR_TIMES_SET (1 << 16) |
8909 |
++#define ATTR_TAG (1 << 17) |
8910 |
+ |
8911 |
+ /* |
8912 |
+ * This is the Inode Attributes structure, used for notify_change(). It |
8913 |
+@@ -380,6 +408,7 @@ struct iattr { |
8914 |
+ umode_t ia_mode; |
8915 |
+ uid_t ia_uid; |
8916 |
+ gid_t ia_gid; |
8917 |
++ tag_t ia_tag; |
8918 |
+ loff_t ia_size; |
8919 |
+ struct timespec ia_atime; |
8920 |
+ struct timespec ia_mtime; |
8921 |
+@@ -393,6 +422,9 @@ struct iattr { |
8922 |
+ struct file *ia_file; |
8923 |
+ }; |
8924 |
+ |
8925 |
++#define ATTR_FLAG_BARRIER 512 /* Barrier for chroot() */ |
8926 |
++#define ATTR_FLAG_IXUNLINK 1024 /* Immutable invert on unlink */ |
8927 |
++ |
8928 |
+ /* |
8929 |
+ * Includes for diskquotas. |
8930 |
+ */ |
8931 |
+@@ -656,7 +688,9 @@ struct inode { |
8932 |
+ unsigned int i_nlink; |
8933 |
+ uid_t i_uid; |
8934 |
+ gid_t i_gid; |
8935 |
++ tag_t i_tag; |
8936 |
+ dev_t i_rdev; |
8937 |
++ dev_t i_mdev; |
8938 |
+ u64 i_version; |
8939 |
+ loff_t i_size; |
8940 |
+ #ifdef __NEED_I_SIZE_ORDERED |
8941 |
+@@ -704,7 +738,8 @@ struct inode { |
8942 |
+ unsigned long i_state; |
8943 |
+ unsigned long dirtied_when; /* jiffies of first dirtying */ |
8944 |
+ |
8945 |
+- unsigned int i_flags; |
8946 |
++ unsigned short i_flags; |
8947 |
++ unsigned short i_vflags; |
8948 |
+ |
8949 |
+ atomic_t i_writecount; |
8950 |
+ #ifdef CONFIG_SECURITY |
8951 |
+@@ -791,12 +826,12 @@ static inline void i_size_write(struct i |
8952 |
+ |
8953 |
+ static inline unsigned iminor(const struct inode *inode) |
8954 |
+ { |
8955 |
+- return MINOR(inode->i_rdev); |
8956 |
++ return MINOR(inode->i_mdev); |
8957 |
+ } |
8958 |
+ |
8959 |
+ static inline unsigned imajor(const struct inode *inode) |
8960 |
+ { |
8961 |
+- return MAJOR(inode->i_rdev); |
8962 |
++ return MAJOR(inode->i_mdev); |
8963 |
+ } |
8964 |
+ |
8965 |
+ extern struct block_device *I_BDEV(struct inode *inode); |
8966 |
+@@ -854,6 +889,7 @@ struct file { |
8967 |
+ loff_t f_pos; |
8968 |
+ struct fown_struct f_owner; |
8969 |
+ const struct cred *f_cred; |
8970 |
++ xid_t f_xid; |
8971 |
+ struct file_ra_state f_ra; |
8972 |
+ |
8973 |
+ u64 f_version; |
8974 |
+@@ -996,6 +1032,7 @@ struct file_lock { |
8975 |
+ struct file *fl_file; |
8976 |
+ loff_t fl_start; |
8977 |
+ loff_t fl_end; |
8978 |
++ xid_t fl_xid; |
8979 |
+ |
8980 |
+ struct fasync_struct * fl_fasync; /* for lease break notifications */ |
8981 |
+ unsigned long fl_break_time; /* for nonblocking lease breaks */ |
8982 |
+@@ -1363,6 +1400,7 @@ struct inode_operations { |
8983 |
+ loff_t len); |
8984 |
+ int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, |
8985 |
+ u64 len); |
8986 |
++ int (*sync_flags) (struct inode *); |
8987 |
+ }; |
8988 |
+ |
8989 |
+ struct seq_file; |
8990 |
+@@ -1378,6 +1416,7 @@ extern ssize_t vfs_readv(struct file *, |
8991 |
+ unsigned long, loff_t *); |
8992 |
+ extern ssize_t vfs_writev(struct file *, const struct iovec __user *, |
8993 |
+ unsigned long, loff_t *); |
8994 |
++ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t); |
8995 |
+ |
8996 |
+ struct super_operations { |
8997 |
+ struct inode *(*alloc_inode)(struct super_block *sb); |
8998 |
+@@ -2096,6 +2135,7 @@ extern int dcache_dir_open(struct inode |
8999 |
+ extern int dcache_dir_close(struct inode *, struct file *); |
9000 |
+ extern loff_t dcache_dir_lseek(struct file *, loff_t, int); |
9001 |
+ extern int dcache_readdir(struct file *, void *, filldir_t); |
9002 |
++extern int dcache_readdir_filter(struct file *, void *, filldir_t, int (*)(struct dentry *)); |
9003 |
+ extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *); |
9004 |
+ extern int simple_statfs(struct dentry *, struct kstatfs *); |
9005 |
+ extern int simple_link(struct dentry *, struct inode *, struct dentry *); |
9006 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/if_tun.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/if_tun.h |
9007 |
+--- linux-2.6.29.4/include/linux/if_tun.h 2008-12-25 00:26:37.000000000 +0100 |
9008 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/if_tun.h 2009-02-22 22:54:26.000000000 +0100 |
9009 |
+@@ -46,6 +46,7 @@ |
9010 |
+ #define TUNSETOFFLOAD _IOW('T', 208, unsigned int) |
9011 |
+ #define TUNSETTXFILTER _IOW('T', 209, unsigned int) |
9012 |
+ #define TUNGETIFF _IOR('T', 210, unsigned int) |
9013 |
++#define TUNSETNID _IOW('T', 215, int) |
9014 |
+ |
9015 |
+ /* TUNSETIFF ifr flags */ |
9016 |
+ #define IFF_TUN 0x0001 |
9017 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/init_task.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/init_task.h |
9018 |
+--- linux-2.6.29.4/include/linux/init_task.h 2009-03-24 14:22:41.000000000 +0100 |
9019 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/init_task.h 2009-03-24 14:48:36.000000000 +0100 |
9020 |
+@@ -184,6 +184,10 @@ extern struct cred init_cred; |
9021 |
+ INIT_IDS \ |
9022 |
+ INIT_TRACE_IRQFLAGS \ |
9023 |
+ INIT_LOCKDEP \ |
9024 |
++ .xid = 0, \ |
9025 |
++ .vx_info = NULL, \ |
9026 |
++ .nid = 0, \ |
9027 |
++ .nx_info = NULL, \ |
9028 |
+ } |
9029 |
+ |
9030 |
+ |
9031 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/interrupt.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/interrupt.h |
9032 |
+--- linux-2.6.29.4/include/linux/interrupt.h 2009-05-23 23:16:53.000000000 +0200 |
9033 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/interrupt.h 2009-04-30 12:14:53.000000000 +0200 |
9034 |
+@@ -9,8 +9,8 @@ |
9035 |
+ #include <linux/cpumask.h> |
9036 |
+ #include <linux/irqreturn.h> |
9037 |
+ #include <linux/irqnr.h> |
9038 |
+-#include <linux/hardirq.h> |
9039 |
+ #include <linux/sched.h> |
9040 |
++#include <linux/hardirq.h> |
9041 |
+ #include <linux/irqflags.h> |
9042 |
+ #include <linux/smp.h> |
9043 |
+ #include <linux/percpu.h> |
9044 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/ipc.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/ipc.h |
9045 |
+--- linux-2.6.29.4/include/linux/ipc.h 2008-12-25 00:26:37.000000000 +0100 |
9046 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/ipc.h 2009-02-22 22:54:26.000000000 +0100 |
9047 |
+@@ -93,6 +93,7 @@ struct kern_ipc_perm |
9048 |
+ key_t key; |
9049 |
+ uid_t uid; |
9050 |
+ gid_t gid; |
9051 |
++ xid_t xid; |
9052 |
+ uid_t cuid; |
9053 |
+ gid_t cgid; |
9054 |
+ mode_t mode; |
9055 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/Kbuild linux-2.6.29.4-vs2.3.0.36.14/include/linux/Kbuild |
9056 |
+--- linux-2.6.29.4/include/linux/Kbuild 2009-03-24 14:22:40.000000000 +0100 |
9057 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/Kbuild 2009-03-24 17:22:07.000000000 +0100 |
9058 |
+@@ -373,5 +373,8 @@ unifdef-y += xattr.h |
9059 |
+ unifdef-y += xfrm.h |
9060 |
+ |
9061 |
+ objhdr-y += version.h |
9062 |
++ |
9063 |
++header-y += vserver/ |
9064 |
+ header-y += wimax.h |
9065 |
+ header-y += wimax/ |
9066 |
++ |
9067 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/loop.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/loop.h |
9068 |
+--- linux-2.6.29.4/include/linux/loop.h 2009-03-24 14:22:42.000000000 +0100 |
9069 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/loop.h 2009-03-24 14:48:36.000000000 +0100 |
9070 |
+@@ -45,6 +45,7 @@ struct loop_device { |
9071 |
+ struct loop_func_table *lo_encryption; |
9072 |
+ __u32 lo_init[2]; |
9073 |
+ uid_t lo_key_owner; /* Who set the key */ |
9074 |
++ xid_t lo_xid; |
9075 |
+ int (*ioctl)(struct loop_device *, int cmd, |
9076 |
+ unsigned long arg); |
9077 |
+ |
9078 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/magic.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/magic.h |
9079 |
+--- linux-2.6.29.4/include/linux/magic.h 2009-03-24 14:22:42.000000000 +0100 |
9080 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/magic.h 2009-03-24 14:48:36.000000000 +0100 |
9081 |
+@@ -3,7 +3,7 @@ |
9082 |
+ |
9083 |
+ #define ADFS_SUPER_MAGIC 0xadf5 |
9084 |
+ #define AFFS_SUPER_MAGIC 0xadff |
9085 |
+-#define AFS_SUPER_MAGIC 0x5346414F |
9086 |
++#define AFS_SUPER_MAGIC 0x5346414F |
9087 |
+ #define AUTOFS_SUPER_MAGIC 0x0187 |
9088 |
+ #define CODA_SUPER_MAGIC 0x73757245 |
9089 |
+ #define DEBUGFS_MAGIC 0x64626720 |
9090 |
+@@ -33,6 +33,7 @@ |
9091 |
+ #define NFS_SUPER_MAGIC 0x6969 |
9092 |
+ #define OPENPROM_SUPER_MAGIC 0x9fa1 |
9093 |
+ #define PROC_SUPER_MAGIC 0x9fa0 |
9094 |
++#define DEVPTS_SUPER_MAGIC 0x1cd1 |
9095 |
+ #define QNX4_SUPER_MAGIC 0x002f /* qnx4 fs detection */ |
9096 |
+ |
9097 |
+ #define REISERFS_SUPER_MAGIC 0x52654973 /* used by gcc */ |
9098 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/major.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/major.h |
9099 |
+--- linux-2.6.29.4/include/linux/major.h 2008-12-25 00:26:37.000000000 +0100 |
9100 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/major.h 2009-02-22 22:54:26.000000000 +0100 |
9101 |
+@@ -15,6 +15,7 @@ |
9102 |
+ #define HD_MAJOR IDE0_MAJOR |
9103 |
+ #define PTY_SLAVE_MAJOR 3 |
9104 |
+ #define TTY_MAJOR 4 |
9105 |
++#define VROOT_MAJOR 4 |
9106 |
+ #define TTYAUX_MAJOR 5 |
9107 |
+ #define LP_MAJOR 6 |
9108 |
+ #define VCS_MAJOR 7 |
9109 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/mm_types.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/mm_types.h |
9110 |
+--- linux-2.6.29.4/include/linux/mm_types.h 2009-03-24 14:22:42.000000000 +0100 |
9111 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/mm_types.h 2009-03-24 14:48:36.000000000 +0100 |
9112 |
+@@ -232,6 +232,7 @@ struct mm_struct { |
9113 |
+ |
9114 |
+ /* Architecture-specific MM context */ |
9115 |
+ mm_context_t context; |
9116 |
++ struct vx_info *mm_vx_info; |
9117 |
+ |
9118 |
+ /* Swap token stuff */ |
9119 |
+ /* |
9120 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/mount.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/mount.h |
9121 |
+--- linux-2.6.29.4/include/linux/mount.h 2008-12-25 00:26:37.000000000 +0100 |
9122 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/mount.h 2009-02-22 22:54:26.000000000 +0100 |
9123 |
+@@ -35,6 +35,9 @@ struct mnt_namespace; |
9124 |
+ #define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */ |
9125 |
+ #define MNT_PNODE_MASK 0x3000 /* propagation flag mask */ |
9126 |
+ |
9127 |
++#define MNT_TAGID 0x10000 |
9128 |
++#define MNT_NOTAG 0x20000 |
9129 |
++ |
9130 |
+ struct vfsmount { |
9131 |
+ struct list_head mnt_hash; |
9132 |
+ struct vfsmount *mnt_parent; /* fs we are mounted on */ |
9133 |
+@@ -69,6 +72,7 @@ struct vfsmount { |
9134 |
+ * are held, and all mnt_writer[]s on this mount have 0 as their ->count |
9135 |
+ */ |
9136 |
+ atomic_t __mnt_writers; |
9137 |
++ tag_t mnt_tag; /* tagging used for vfsmount */ |
9138 |
+ }; |
9139 |
+ |
9140 |
+ static inline struct vfsmount *mntget(struct vfsmount *mnt) |
9141 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/net.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/net.h |
9142 |
+--- linux-2.6.29.4/include/linux/net.h 2008-12-25 00:26:37.000000000 +0100 |
9143 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/net.h 2009-02-22 22:54:26.000000000 +0100 |
9144 |
+@@ -68,6 +68,7 @@ struct net; |
9145 |
+ #define SOCK_NOSPACE 2 |
9146 |
+ #define SOCK_PASSCRED 3 |
9147 |
+ #define SOCK_PASSSEC 4 |
9148 |
++#define SOCK_USER_SOCKET 5 |
9149 |
+ |
9150 |
+ #ifndef ARCH_HAS_SOCKET_TYPES |
9151 |
+ /** |
9152 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/nfs_mount.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/nfs_mount.h |
9153 |
+--- linux-2.6.29.4/include/linux/nfs_mount.h 2009-03-24 14:22:43.000000000 +0100 |
9154 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/nfs_mount.h 2009-03-24 14:48:36.000000000 +0100 |
9155 |
+@@ -63,7 +63,8 @@ struct nfs_mount_data { |
9156 |
+ #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */ |
9157 |
+ #define NFS_MOUNT_NORDIRPLUS 0x4000 /* 5 */ |
9158 |
+ #define NFS_MOUNT_UNSHARED 0x8000 /* 5 */ |
9159 |
+-#define NFS_MOUNT_FLAGMASK 0xFFFF |
9160 |
++#define NFS_MOUNT_TAGGED 0x10000 /* context tagging */ |
9161 |
++#define NFS_MOUNT_FLAGMASK 0x1FFFF |
9162 |
+ |
9163 |
+ /* The following are for internal use only */ |
9164 |
+ #define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000 |
9165 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/nsproxy.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/nsproxy.h |
9166 |
+--- linux-2.6.29.4/include/linux/nsproxy.h 2009-03-24 14:22:43.000000000 +0100 |
9167 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/nsproxy.h 2009-03-24 14:48:36.000000000 +0100 |
9168 |
+@@ -3,6 +3,7 @@ |
9169 |
+ |
9170 |
+ #include <linux/spinlock.h> |
9171 |
+ #include <linux/sched.h> |
9172 |
++#include <linux/vserver/debug.h> |
9173 |
+ |
9174 |
+ struct mnt_namespace; |
9175 |
+ struct uts_namespace; |
9176 |
+@@ -62,22 +63,33 @@ static inline struct nsproxy *task_nspro |
9177 |
+ } |
9178 |
+ |
9179 |
+ int copy_namespaces(unsigned long flags, struct task_struct *tsk); |
9180 |
++struct nsproxy *copy_nsproxy(struct nsproxy *orig); |
9181 |
+ void exit_task_namespaces(struct task_struct *tsk); |
9182 |
+ void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new); |
9183 |
+ void free_nsproxy(struct nsproxy *ns); |
9184 |
+ int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **, |
9185 |
+ struct fs_struct *); |
9186 |
+ |
9187 |
+-static inline void put_nsproxy(struct nsproxy *ns) |
9188 |
++#define get_nsproxy(n) __get_nsproxy(n, __FILE__, __LINE__) |
9189 |
++ |
9190 |
++static inline void __get_nsproxy(struct nsproxy *ns, |
9191 |
++ const char *_file, int _line) |
9192 |
+ { |
9193 |
+- if (atomic_dec_and_test(&ns->count)) { |
9194 |
+- free_nsproxy(ns); |
9195 |
+- } |
9196 |
++ vxlprintk(VXD_CBIT(space, 0), "get_nsproxy(%p[%u])", |
9197 |
++ ns, atomic_read(&ns->count), _file, _line); |
9198 |
++ atomic_inc(&ns->count); |
9199 |
+ } |
9200 |
+ |
9201 |
+-static inline void get_nsproxy(struct nsproxy *ns) |
9202 |
++#define put_nsproxy(n) __put_nsproxy(n, __FILE__, __LINE__) |
9203 |
++ |
9204 |
++static inline void __put_nsproxy(struct nsproxy *ns, |
9205 |
++ const char *_file, int _line) |
9206 |
+ { |
9207 |
+- atomic_inc(&ns->count); |
9208 |
++ vxlprintk(VXD_CBIT(space, 0), "put_nsproxy(%p[%u])", |
9209 |
++ ns, atomic_read(&ns->count), _file, _line); |
9210 |
++ if (atomic_dec_and_test(&ns->count)) { |
9211 |
++ free_nsproxy(ns); |
9212 |
++ } |
9213 |
+ } |
9214 |
+ |
9215 |
+ #ifdef CONFIG_CGROUP_NS |
9216 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/pid.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/pid.h |
9217 |
+--- linux-2.6.29.4/include/linux/pid.h 2009-03-24 14:22:43.000000000 +0100 |
9218 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/pid.h 2009-03-24 14:48:36.000000000 +0100 |
9219 |
+@@ -8,7 +8,8 @@ enum pid_type |
9220 |
+ PIDTYPE_PID, |
9221 |
+ PIDTYPE_PGID, |
9222 |
+ PIDTYPE_SID, |
9223 |
+- PIDTYPE_MAX |
9224 |
++ PIDTYPE_MAX, |
9225 |
++ PIDTYPE_REALPID |
9226 |
+ }; |
9227 |
+ |
9228 |
+ /* |
9229 |
+@@ -160,6 +161,7 @@ static inline pid_t pid_nr(struct pid *p |
9230 |
+ } |
9231 |
+ |
9232 |
+ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns); |
9233 |
++pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns); |
9234 |
+ pid_t pid_vnr(struct pid *pid); |
9235 |
+ |
9236 |
+ #define do_each_pid_task(pid, type, task) \ |
9237 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/proc_fs.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/proc_fs.h |
9238 |
+--- linux-2.6.29.4/include/linux/proc_fs.h 2008-12-25 00:26:37.000000000 +0100 |
9239 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/proc_fs.h 2009-02-22 22:54:26.000000000 +0100 |
9240 |
+@@ -59,6 +59,7 @@ struct proc_dir_entry { |
9241 |
+ nlink_t nlink; |
9242 |
+ uid_t uid; |
9243 |
+ gid_t gid; |
9244 |
++ int vx_flags; |
9245 |
+ loff_t size; |
9246 |
+ const struct inode_operations *proc_iops; |
9247 |
+ /* |
9248 |
+@@ -268,12 +269,18 @@ static inline void kclist_add(struct kco |
9249 |
+ extern void kclist_add(struct kcore_list *, void *, size_t); |
9250 |
+ #endif |
9251 |
+ |
9252 |
++struct vx_info; |
9253 |
++struct nx_info; |
9254 |
++ |
9255 |
+ union proc_op { |
9256 |
+ int (*proc_get_link)(struct inode *, struct path *); |
9257 |
+ int (*proc_read)(struct task_struct *task, char *page); |
9258 |
+ int (*proc_show)(struct seq_file *m, |
9259 |
+ struct pid_namespace *ns, struct pid *pid, |
9260 |
+ struct task_struct *task); |
9261 |
++ int (*proc_vs_read)(char *page); |
9262 |
++ int (*proc_vxi_read)(struct vx_info *vxi, char *page); |
9263 |
++ int (*proc_nxi_read)(struct nx_info *nxi, char *page); |
9264 |
+ }; |
9265 |
+ |
9266 |
+ struct ctl_table_header; |
9267 |
+@@ -281,6 +288,7 @@ struct ctl_table; |
9268 |
+ |
9269 |
+ struct proc_inode { |
9270 |
+ struct pid *pid; |
9271 |
++ int vx_flags; |
9272 |
+ int fd; |
9273 |
+ union proc_op op; |
9274 |
+ struct proc_dir_entry *pde; |
9275 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/reiserfs_fs.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/reiserfs_fs.h |
9276 |
+--- linux-2.6.29.4/include/linux/reiserfs_fs.h 2008-12-25 00:26:37.000000000 +0100 |
9277 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/reiserfs_fs.h 2009-02-22 22:54:26.000000000 +0100 |
9278 |
+@@ -837,6 +837,11 @@ struct stat_data_v1 { |
9279 |
+ #define REISERFS_COMPR_FL FS_COMPR_FL |
9280 |
+ #define REISERFS_NOTAIL_FL FS_NOTAIL_FL |
9281 |
+ |
9282 |
++/* unfortunately reiserfs sdattr is only 16 bit */ |
9283 |
++#define REISERFS_IXUNLINK_FL (FS_IXUNLINK_FL >> 16) |
9284 |
++#define REISERFS_BARRIER_FL (FS_BARRIER_FL >> 16) |
9285 |
++#define REISERFS_COW_FL (FS_COW_FL >> 16) |
9286 |
++ |
9287 |
+ /* persistent flags that file inherits from the parent directory */ |
9288 |
+ #define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL | \ |
9289 |
+ REISERFS_SYNC_FL | \ |
9290 |
+@@ -846,6 +851,9 @@ struct stat_data_v1 { |
9291 |
+ REISERFS_COMPR_FL | \ |
9292 |
+ REISERFS_NOTAIL_FL ) |
9293 |
+ |
9294 |
++#define REISERFS_FL_USER_VISIBLE 0x80FF |
9295 |
++#define REISERFS_FL_USER_MODIFIABLE 0x80FF |
9296 |
++ |
9297 |
+ /* Stat Data on disk (reiserfs version of UFS disk inode minus the |
9298 |
+ address blocks) */ |
9299 |
+ struct stat_data { |
9300 |
+@@ -1911,6 +1919,7 @@ static inline void reiserfs_update_sd(st |
9301 |
+ void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode); |
9302 |
+ void i_attrs_to_sd_attrs(struct inode *inode, __u16 * sd_attrs); |
9303 |
+ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr); |
9304 |
++int reiserfs_sync_flags(struct inode *inode); |
9305 |
+ |
9306 |
+ /* namei.c */ |
9307 |
+ void set_de_name_and_namelen(struct reiserfs_dir_entry *de); |
9308 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/reiserfs_fs_sb.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/reiserfs_fs_sb.h |
9309 |
+--- linux-2.6.29.4/include/linux/reiserfs_fs_sb.h 2008-12-25 00:26:37.000000000 +0100 |
9310 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/reiserfs_fs_sb.h 2009-02-22 22:54:26.000000000 +0100 |
9311 |
+@@ -456,6 +456,7 @@ enum reiserfs_mount_options { |
9312 |
+ REISERFS_POSIXACL, |
9313 |
+ REISERFS_BARRIER_NONE, |
9314 |
+ REISERFS_BARRIER_FLUSH, |
9315 |
++ REISERFS_TAGGED, |
9316 |
+ |
9317 |
+ /* Actions on error */ |
9318 |
+ REISERFS_ERROR_PANIC, |
9319 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/sched.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/sched.h |
9320 |
+--- linux-2.6.29.4/include/linux/sched.h 2009-05-23 23:16:53.000000000 +0200 |
9321 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/sched.h 2009-04-30 12:14:53.000000000 +0200 |
9322 |
+@@ -71,7 +71,6 @@ struct sched_param { |
9323 |
+ #include <linux/fs_struct.h> |
9324 |
+ #include <linux/compiler.h> |
9325 |
+ #include <linux/completion.h> |
9326 |
+-#include <linux/pid.h> |
9327 |
+ #include <linux/percpu.h> |
9328 |
+ #include <linux/topology.h> |
9329 |
+ #include <linux/proportions.h> |
9330 |
+@@ -88,6 +87,7 @@ struct sched_param { |
9331 |
+ #include <linux/kobject.h> |
9332 |
+ #include <linux/latencytop.h> |
9333 |
+ #include <linux/cred.h> |
9334 |
++#include <linux/pid.h> |
9335 |
+ |
9336 |
+ #include <asm/processor.h> |
9337 |
+ |
9338 |
+@@ -176,12 +176,13 @@ extern unsigned long long time_sync_thre |
9339 |
+ #define TASK_UNINTERRUPTIBLE 2 |
9340 |
+ #define __TASK_STOPPED 4 |
9341 |
+ #define __TASK_TRACED 8 |
9342 |
++#define TASK_ONHOLD 16 |
9343 |
+ /* in tsk->exit_state */ |
9344 |
+-#define EXIT_ZOMBIE 16 |
9345 |
+-#define EXIT_DEAD 32 |
9346 |
++#define EXIT_ZOMBIE 32 |
9347 |
++#define EXIT_DEAD 64 |
9348 |
+ /* in tsk->state again */ |
9349 |
+-#define TASK_DEAD 64 |
9350 |
+-#define TASK_WAKEKILL 128 |
9351 |
++#define TASK_DEAD 128 |
9352 |
++#define TASK_WAKEKILL 256 |
9353 |
+ |
9354 |
+ /* Convenience macros for the sake of set_task_state */ |
9355 |
+ #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) |
9356 |
+@@ -359,25 +360,28 @@ extern void arch_unmap_area_topdown(stru |
9357 |
+ * The mm counters are not protected by its page_table_lock, |
9358 |
+ * so must be incremented atomically. |
9359 |
+ */ |
9360 |
+-#define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value) |
9361 |
+-#define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member)) |
9362 |
+-#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member) |
9363 |
+-#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member) |
9364 |
+-#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member) |
9365 |
++#define __set_mm_counter(mm, member, value) \ |
9366 |
++ atomic_long_set(&(mm)->_##member, value) |
9367 |
++#define get_mm_counter(mm, member) \ |
9368 |
++ ((unsigned long)atomic_long_read(&(mm)->_##member)) |
9369 |
+ |
9370 |
+ #else /* !USE_SPLIT_PTLOCKS */ |
9371 |
+ /* |
9372 |
+ * The mm counters are protected by its page_table_lock, |
9373 |
+ * so can be incremented directly. |
9374 |
+ */ |
9375 |
+-#define set_mm_counter(mm, member, value) (mm)->_##member = (value) |
9376 |
++#define __set_mm_counter(mm, member, value) (mm)->_##member = (value) |
9377 |
+ #define get_mm_counter(mm, member) ((mm)->_##member) |
9378 |
+-#define add_mm_counter(mm, member, value) (mm)->_##member += (value) |
9379 |
+-#define inc_mm_counter(mm, member) (mm)->_##member++ |
9380 |
+-#define dec_mm_counter(mm, member) (mm)->_##member-- |
9381 |
+ |
9382 |
+ #endif /* !USE_SPLIT_PTLOCKS */ |
9383 |
+ |
9384 |
++#define set_mm_counter(mm, member, value) \ |
9385 |
++ vx_ ## member ## pages_sub((mm), (get_mm_counter(mm, member) - value)) |
9386 |
++#define add_mm_counter(mm, member, value) \ |
9387 |
++ vx_ ## member ## pages_add((mm), (value)) |
9388 |
++#define inc_mm_counter(mm, member) vx_ ## member ## pages_inc((mm)) |
9389 |
++#define dec_mm_counter(mm, member) vx_ ## member ## pages_dec((mm)) |
9390 |
++ |
9391 |
+ #define get_mm_rss(mm) \ |
9392 |
+ (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss)) |
9393 |
+ #define update_hiwater_rss(mm) do { \ |
9394 |
+@@ -1132,7 +1136,9 @@ struct task_struct { |
9395 |
+ const struct sched_class *sched_class; |
9396 |
+ struct sched_entity se; |
9397 |
+ struct sched_rt_entity rt; |
9398 |
+- |
9399 |
++#ifdef CONFIG_VSERVER_HARDCPU |
9400 |
++ struct list_head hq; |
9401 |
++#endif |
9402 |
+ #ifdef CONFIG_PREEMPT_NOTIFIERS |
9403 |
+ /* list of struct preempt_notifier: */ |
9404 |
+ struct hlist_head preempt_notifiers; |
9405 |
+@@ -1288,6 +1294,14 @@ struct task_struct { |
9406 |
+ #endif |
9407 |
+ seccomp_t seccomp; |
9408 |
+ |
9409 |
++/* vserver context data */ |
9410 |
++ struct vx_info *vx_info; |
9411 |
++ struct nx_info *nx_info; |
9412 |
++ |
9413 |
++ xid_t xid; |
9414 |
++ nid_t nid; |
9415 |
++ tag_t tag; |
9416 |
++ |
9417 |
+ /* Thread group tracking */ |
9418 |
+ u32 parent_exec_id; |
9419 |
+ u32 self_exec_id; |
9420 |
+@@ -1500,6 +1514,11 @@ struct pid_namespace; |
9421 |
+ * see also pid_nr() etc in include/linux/pid.h |
9422 |
+ */ |
9423 |
+ |
9424 |
++#include <linux/vserver/base.h> |
9425 |
++#include <linux/vserver/context.h> |
9426 |
++#include <linux/vserver/debug.h> |
9427 |
++#include <linux/vserver/pid.h> |
9428 |
++ |
9429 |
+ static inline pid_t task_pid_nr(struct task_struct *tsk) |
9430 |
+ { |
9431 |
+ return tsk->pid; |
9432 |
+@@ -1509,7 +1528,7 @@ pid_t task_pid_nr_ns(struct task_struct |
9433 |
+ |
9434 |
+ static inline pid_t task_pid_vnr(struct task_struct *tsk) |
9435 |
+ { |
9436 |
+- return pid_vnr(task_pid(tsk)); |
9437 |
++ return vx_map_pid(pid_vnr(task_pid(tsk))); |
9438 |
+ } |
9439 |
+ |
9440 |
+ |
9441 |
+@@ -1522,7 +1541,7 @@ pid_t task_tgid_nr_ns(struct task_struct |
9442 |
+ |
9443 |
+ static inline pid_t task_tgid_vnr(struct task_struct *tsk) |
9444 |
+ { |
9445 |
+- return pid_vnr(task_tgid(tsk)); |
9446 |
++ return vx_map_tgid(pid_vnr(task_tgid(tsk))); |
9447 |
+ } |
9448 |
+ |
9449 |
+ |
9450 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/shmem_fs.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/shmem_fs.h |
9451 |
+--- linux-2.6.29.4/include/linux/shmem_fs.h 2008-12-25 00:26:37.000000000 +0100 |
9452 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/shmem_fs.h 2009-02-22 22:54:26.000000000 +0100 |
9453 |
+@@ -8,6 +8,9 @@ |
9454 |
+ |
9455 |
+ #define SHMEM_NR_DIRECT 16 |
9456 |
+ |
9457 |
++#define TMPFS_SUPER_MAGIC 0x01021994 |
9458 |
++ |
9459 |
++ |
9460 |
+ struct shmem_inode_info { |
9461 |
+ spinlock_t lock; |
9462 |
+ unsigned long flags; |
9463 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/stat.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/stat.h |
9464 |
+--- linux-2.6.29.4/include/linux/stat.h 2008-12-25 00:26:37.000000000 +0100 |
9465 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/stat.h 2009-02-22 22:54:26.000000000 +0100 |
9466 |
+@@ -66,6 +66,7 @@ struct kstat { |
9467 |
+ unsigned int nlink; |
9468 |
+ uid_t uid; |
9469 |
+ gid_t gid; |
9470 |
++ tag_t tag; |
9471 |
+ dev_t rdev; |
9472 |
+ loff_t size; |
9473 |
+ struct timespec atime; |
9474 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/sunrpc/auth.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/sunrpc/auth.h |
9475 |
+--- linux-2.6.29.4/include/linux/sunrpc/auth.h 2008-12-25 00:26:37.000000000 +0100 |
9476 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/sunrpc/auth.h 2009-02-22 22:54:26.000000000 +0100 |
9477 |
+@@ -25,6 +25,7 @@ |
9478 |
+ struct auth_cred { |
9479 |
+ uid_t uid; |
9480 |
+ gid_t gid; |
9481 |
++ tag_t tag; |
9482 |
+ struct group_info *group_info; |
9483 |
+ unsigned char machine_cred : 1; |
9484 |
+ }; |
9485 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/sunrpc/clnt.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/sunrpc/clnt.h |
9486 |
+--- linux-2.6.29.4/include/linux/sunrpc/clnt.h 2009-03-24 14:22:43.000000000 +0100 |
9487 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/sunrpc/clnt.h 2009-03-24 14:48:36.000000000 +0100 |
9488 |
+@@ -43,7 +43,8 @@ struct rpc_clnt { |
9489 |
+ unsigned int cl_softrtry : 1,/* soft timeouts */ |
9490 |
+ cl_discrtry : 1,/* disconnect before retry */ |
9491 |
+ cl_autobind : 1,/* use getport() */ |
9492 |
+- cl_chatty : 1;/* be verbose */ |
9493 |
++ cl_chatty : 1,/* be verbose */ |
9494 |
++ cl_tag : 1;/* context tagging */ |
9495 |
+ |
9496 |
+ struct rpc_rtt * cl_rtt; /* RTO estimator data */ |
9497 |
+ const struct rpc_timeout *cl_timeout; /* Timeout strategy */ |
9498 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/syscalls.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/syscalls.h |
9499 |
+--- linux-2.6.29.4/include/linux/syscalls.h 2009-03-24 14:22:43.000000000 +0100 |
9500 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/syscalls.h 2009-03-24 14:48:36.000000000 +0100 |
9501 |
+@@ -369,6 +369,8 @@ asmlinkage long sys_symlink(const char _ |
9502 |
+ asmlinkage long sys_unlink(const char __user *pathname); |
9503 |
+ asmlinkage long sys_rename(const char __user *oldname, |
9504 |
+ const char __user *newname); |
9505 |
++asmlinkage long sys_copyfile(const char __user *from, const char __user *to, |
9506 |
++ umode_t mode); |
9507 |
+ asmlinkage long sys_chmod(const char __user *filename, mode_t mode); |
9508 |
+ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode); |
9509 |
+ |
9510 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/sysctl.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/sysctl.h |
9511 |
+--- linux-2.6.29.4/include/linux/sysctl.h 2008-12-25 00:26:37.000000000 +0100 |
9512 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/sysctl.h 2009-02-22 22:54:26.000000000 +0100 |
9513 |
+@@ -70,6 +70,7 @@ enum |
9514 |
+ CTL_ABI=9, /* Binary emulation */ |
9515 |
+ CTL_CPU=10, /* CPU stuff (speed scaling, etc) */ |
9516 |
+ CTL_ARLAN=254, /* arlan wireless driver */ |
9517 |
++ CTL_VSERVER=4242, /* Linux-VServer debug */ |
9518 |
+ CTL_S390DBF=5677, /* s390 debug */ |
9519 |
+ CTL_SUNRPC=7249, /* sunrpc debug */ |
9520 |
+ CTL_PM=9899, /* frv power management */ |
9521 |
+@@ -104,6 +105,7 @@ enum |
9522 |
+ |
9523 |
+ KERN_PANIC=15, /* int: panic timeout */ |
9524 |
+ KERN_REALROOTDEV=16, /* real root device to mount after initrd */ |
9525 |
++ KERN_VSHELPER=17, /* string: path to vshelper policy agent */ |
9526 |
+ |
9527 |
+ KERN_SPARC_REBOOT=21, /* reboot command on Sparc */ |
9528 |
+ KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */ |
9529 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/sysfs.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/sysfs.h |
9530 |
+--- linux-2.6.29.4/include/linux/sysfs.h 2008-12-25 00:26:37.000000000 +0100 |
9531 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/sysfs.h 2009-02-22 22:54:26.000000000 +0100 |
9532 |
+@@ -17,6 +17,8 @@ |
9533 |
+ #include <linux/list.h> |
9534 |
+ #include <asm/atomic.h> |
9535 |
+ |
9536 |
++#define SYSFS_SUPER_MAGIC 0x62656572 |
9537 |
++ |
9538 |
+ struct kobject; |
9539 |
+ struct module; |
9540 |
+ |
9541 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/time.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/time.h |
9542 |
+--- linux-2.6.29.4/include/linux/time.h 2009-03-24 14:22:43.000000000 +0100 |
9543 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/time.h 2009-02-22 22:54:26.000000000 +0100 |
9544 |
+@@ -190,6 +190,9 @@ static __always_inline void timespec_add |
9545 |
+ a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns); |
9546 |
+ a->tv_nsec = ns; |
9547 |
+ } |
9548 |
++ |
9549 |
++#include <linux/vs_time.h> |
9550 |
++ |
9551 |
+ #endif /* __KERNEL__ */ |
9552 |
+ |
9553 |
+ #define NFDBITS __NFDBITS |
9554 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/types.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/types.h |
9555 |
+--- linux-2.6.29.4/include/linux/types.h 2009-03-24 14:22:43.000000000 +0100 |
9556 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/types.h 2009-03-24 14:48:36.000000000 +0100 |
9557 |
+@@ -36,6 +36,9 @@ typedef __kernel_uid32_t uid_t; |
9558 |
+ typedef __kernel_gid32_t gid_t; |
9559 |
+ typedef __kernel_uid16_t uid16_t; |
9560 |
+ typedef __kernel_gid16_t gid16_t; |
9561 |
++typedef unsigned int xid_t; |
9562 |
++typedef unsigned int nid_t; |
9563 |
++typedef unsigned int tag_t; |
9564 |
+ |
9565 |
+ typedef unsigned long uintptr_t; |
9566 |
+ |
9567 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vroot.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vroot.h |
9568 |
+--- linux-2.6.29.4/include/linux/vroot.h 1970-01-01 01:00:00.000000000 +0100 |
9569 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vroot.h 2009-02-22 22:54:26.000000000 +0100 |
9570 |
+@@ -0,0 +1,51 @@ |
9571 |
++ |
9572 |
++/* |
9573 |
++ * include/linux/vroot.h |
9574 |
++ * |
9575 |
++ * written by Herbert Pötzl, 9/11/2002 |
9576 |
++ * ported to 2.6 by Herbert Pötzl, 30/12/2004 |
9577 |
++ * |
9578 |
++ * Copyright (C) 2002-2007 by Herbert Pötzl. |
9579 |
++ * Redistribution of this file is permitted under the |
9580 |
++ * GNU General Public License. |
9581 |
++ */ |
9582 |
++ |
9583 |
++#ifndef _LINUX_VROOT_H |
9584 |
++#define _LINUX_VROOT_H |
9585 |
++ |
9586 |
++ |
9587 |
++#ifdef __KERNEL__ |
9588 |
++ |
9589 |
++/* Possible states of device */ |
9590 |
++enum { |
9591 |
++ Vr_unbound, |
9592 |
++ Vr_bound, |
9593 |
++}; |
9594 |
++ |
9595 |
++struct vroot_device { |
9596 |
++ int vr_number; |
9597 |
++ int vr_refcnt; |
9598 |
++ |
9599 |
++ struct semaphore vr_ctl_mutex; |
9600 |
++ struct block_device *vr_device; |
9601 |
++ int vr_state; |
9602 |
++}; |
9603 |
++ |
9604 |
++ |
9605 |
++typedef struct block_device *(vroot_grb_func)(struct block_device *); |
9606 |
++ |
9607 |
++extern int register_vroot_grb(vroot_grb_func *); |
9608 |
++extern int unregister_vroot_grb(vroot_grb_func *); |
9609 |
++ |
9610 |
++#endif /* __KERNEL__ */ |
9611 |
++ |
9612 |
++#define MAX_VROOT_DEFAULT 8 |
9613 |
++ |
9614 |
++/* |
9615 |
++ * IOCTL commands --- we will commandeer 0x56 ('V') |
9616 |
++ */ |
9617 |
++ |
9618 |
++#define VROOT_SET_DEV 0x5600 |
9619 |
++#define VROOT_CLR_DEV 0x5601 |
9620 |
++ |
9621 |
++#endif /* _LINUX_VROOT_H */ |
9622 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_base.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_base.h |
9623 |
+--- linux-2.6.29.4/include/linux/vs_base.h 1970-01-01 01:00:00.000000000 +0100 |
9624 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_base.h 2009-02-22 22:54:26.000000000 +0100 |
9625 |
+@@ -0,0 +1,10 @@ |
9626 |
++#ifndef _VS_BASE_H |
9627 |
++#define _VS_BASE_H |
9628 |
++ |
9629 |
++#include "vserver/base.h" |
9630 |
++#include "vserver/check.h" |
9631 |
++#include "vserver/debug.h" |
9632 |
++ |
9633 |
++#else |
9634 |
++#warning duplicate inclusion |
9635 |
++#endif |
9636 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_context.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_context.h |
9637 |
+--- linux-2.6.29.4/include/linux/vs_context.h 1970-01-01 01:00:00.000000000 +0100 |
9638 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_context.h 2009-02-22 22:54:26.000000000 +0100 |
9639 |
+@@ -0,0 +1,227 @@ |
9640 |
++#ifndef _VS_CONTEXT_H |
9641 |
++#define _VS_CONTEXT_H |
9642 |
++ |
9643 |
++#include "vserver/base.h" |
9644 |
++#include "vserver/check.h" |
9645 |
++#include "vserver/context.h" |
9646 |
++#include "vserver/history.h" |
9647 |
++#include "vserver/debug.h" |
9648 |
++ |
9649 |
++#include <linux/sched.h> |
9650 |
++ |
9651 |
++ |
9652 |
++#define get_vx_info(i) __get_vx_info(i, __FILE__, __LINE__, __HERE__) |
9653 |
++ |
9654 |
++static inline struct vx_info *__get_vx_info(struct vx_info *vxi, |
9655 |
++ const char *_file, int _line, void *_here) |
9656 |
++{ |
9657 |
++ if (!vxi) |
9658 |
++ return NULL; |
9659 |
++ |
9660 |
++ vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])", |
9661 |
++ vxi, vxi ? vxi->vx_id : 0, |
9662 |
++ vxi ? atomic_read(&vxi->vx_usecnt) : 0, |
9663 |
++ _file, _line); |
9664 |
++ __vxh_get_vx_info(vxi, _here); |
9665 |
++ |
9666 |
++ atomic_inc(&vxi->vx_usecnt); |
9667 |
++ return vxi; |
9668 |
++} |
9669 |
++ |
9670 |
++ |
9671 |
++extern void free_vx_info(struct vx_info *); |
9672 |
++ |
9673 |
++#define put_vx_info(i) __put_vx_info(i, __FILE__, __LINE__, __HERE__) |
9674 |
++ |
9675 |
++static inline void __put_vx_info(struct vx_info *vxi, |
9676 |
++ const char *_file, int _line, void *_here) |
9677 |
++{ |
9678 |
++ if (!vxi) |
9679 |
++ return; |
9680 |
++ |
9681 |
++ vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])", |
9682 |
++ vxi, vxi ? vxi->vx_id : 0, |
9683 |
++ vxi ? atomic_read(&vxi->vx_usecnt) : 0, |
9684 |
++ _file, _line); |
9685 |
++ __vxh_put_vx_info(vxi, _here); |
9686 |
++ |
9687 |
++ if (atomic_dec_and_test(&vxi->vx_usecnt)) |
9688 |
++ free_vx_info(vxi); |
9689 |
++} |
9690 |
++ |
9691 |
++ |
9692 |
++#define init_vx_info(p, i) \ |
9693 |
++ __init_vx_info(p, i, __FILE__, __LINE__, __HERE__) |
9694 |
++ |
9695 |
++static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi, |
9696 |
++ const char *_file, int _line, void *_here) |
9697 |
++{ |
9698 |
++ if (vxi) { |
9699 |
++ vxlprintk(VXD_CBIT(xid, 3), |
9700 |
++ "init_vx_info(%p[#%d.%d])", |
9701 |
++ vxi, vxi ? vxi->vx_id : 0, |
9702 |
++ vxi ? atomic_read(&vxi->vx_usecnt) : 0, |
9703 |
++ _file, _line); |
9704 |
++ __vxh_init_vx_info(vxi, vxp, _here); |
9705 |
++ |
9706 |
++ atomic_inc(&vxi->vx_usecnt); |
9707 |
++ } |
9708 |
++ *vxp = vxi; |
9709 |
++} |
9710 |
++ |
9711 |
++ |
9712 |
++#define set_vx_info(p, i) \ |
9713 |
++ __set_vx_info(p, i, __FILE__, __LINE__, __HERE__) |
9714 |
++ |
9715 |
++static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi, |
9716 |
++ const char *_file, int _line, void *_here) |
9717 |
++{ |
9718 |
++ struct vx_info *vxo; |
9719 |
++ |
9720 |
++ if (!vxi) |
9721 |
++ return; |
9722 |
++ |
9723 |
++ vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])", |
9724 |
++ vxi, vxi ? vxi->vx_id : 0, |
9725 |
++ vxi ? atomic_read(&vxi->vx_usecnt) : 0, |
9726 |
++ _file, _line); |
9727 |
++ __vxh_set_vx_info(vxi, vxp, _here); |
9728 |
++ |
9729 |
++ atomic_inc(&vxi->vx_usecnt); |
9730 |
++ vxo = xchg(vxp, vxi); |
9731 |
++ BUG_ON(vxo); |
9732 |
++} |
9733 |
++ |
9734 |
++ |
9735 |
++#define clr_vx_info(p) __clr_vx_info(p, __FILE__, __LINE__, __HERE__) |
9736 |
++ |
9737 |
++static inline void __clr_vx_info(struct vx_info **vxp, |
9738 |
++ const char *_file, int _line, void *_here) |
9739 |
++{ |
9740 |
++ struct vx_info *vxo; |
9741 |
++ |
9742 |
++ vxo = xchg(vxp, NULL); |
9743 |
++ if (!vxo) |
9744 |
++ return; |
9745 |
++ |
9746 |
++ vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])", |
9747 |
++ vxo, vxo ? vxo->vx_id : 0, |
9748 |
++ vxo ? atomic_read(&vxo->vx_usecnt) : 0, |
9749 |
++ _file, _line); |
9750 |
++ __vxh_clr_vx_info(vxo, vxp, _here); |
9751 |
++ |
9752 |
++ if (atomic_dec_and_test(&vxo->vx_usecnt)) |
9753 |
++ free_vx_info(vxo); |
9754 |
++} |
9755 |
++ |
9756 |
++ |
9757 |
++#define claim_vx_info(v, p) \ |
9758 |
++ __claim_vx_info(v, p, __FILE__, __LINE__, __HERE__) |
9759 |
++ |
9760 |
++static inline void __claim_vx_info(struct vx_info *vxi, |
9761 |
++ struct task_struct *task, |
9762 |
++ const char *_file, int _line, void *_here) |
9763 |
++{ |
9764 |
++ vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p", |
9765 |
++ vxi, vxi ? vxi->vx_id : 0, |
9766 |
++ vxi ? atomic_read(&vxi->vx_usecnt) : 0, |
9767 |
++ vxi ? atomic_read(&vxi->vx_tasks) : 0, |
9768 |
++ task, _file, _line); |
9769 |
++ __vxh_claim_vx_info(vxi, task, _here); |
9770 |
++ |
9771 |
++ atomic_inc(&vxi->vx_tasks); |
9772 |
++} |
9773 |
++ |
9774 |
++ |
9775 |
++extern void unhash_vx_info(struct vx_info *); |
9776 |
++ |
9777 |
++#define release_vx_info(v, p) \ |
9778 |
++ __release_vx_info(v, p, __FILE__, __LINE__, __HERE__) |
9779 |
++ |
9780 |
++static inline void __release_vx_info(struct vx_info *vxi, |
9781 |
++ struct task_struct *task, |
9782 |
++ const char *_file, int _line, void *_here) |
9783 |
++{ |
9784 |
++ vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p", |
9785 |
++ vxi, vxi ? vxi->vx_id : 0, |
9786 |
++ vxi ? atomic_read(&vxi->vx_usecnt) : 0, |
9787 |
++ vxi ? atomic_read(&vxi->vx_tasks) : 0, |
9788 |
++ task, _file, _line); |
9789 |
++ __vxh_release_vx_info(vxi, task, _here); |
9790 |
++ |
9791 |
++ might_sleep(); |
9792 |
++ |
9793 |
++ if (atomic_dec_and_test(&vxi->vx_tasks)) |
9794 |
++ unhash_vx_info(vxi); |
9795 |
++} |
9796 |
++ |
9797 |
++ |
9798 |
++#define task_get_vx_info(p) \ |
9799 |
++ __task_get_vx_info(p, __FILE__, __LINE__, __HERE__) |
9800 |
++ |
9801 |
++static inline struct vx_info *__task_get_vx_info(struct task_struct *p, |
9802 |
++ const char *_file, int _line, void *_here) |
9803 |
++{ |
9804 |
++ struct vx_info *vxi; |
9805 |
++ |
9806 |
++ task_lock(p); |
9807 |
++ vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)", |
9808 |
++ p, _file, _line); |
9809 |
++ vxi = __get_vx_info(p->vx_info, _file, _line, _here); |
9810 |
++ task_unlock(p); |
9811 |
++ return vxi; |
9812 |
++} |
9813 |
++ |
9814 |
++ |
9815 |
++static inline void __wakeup_vx_info(struct vx_info *vxi) |
9816 |
++{ |
9817 |
++ if (waitqueue_active(&vxi->vx_wait)) |
9818 |
++ wake_up_interruptible(&vxi->vx_wait); |
9819 |
++} |
9820 |
++ |
9821 |
++ |
9822 |
++#define enter_vx_info(v, s) __enter_vx_info(v, s, __FILE__, __LINE__) |
9823 |
++ |
9824 |
++static inline void __enter_vx_info(struct vx_info *vxi, |
9825 |
++ struct vx_info_save *vxis, const char *_file, int _line) |
9826 |
++{ |
9827 |
++ vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]", |
9828 |
++ vxi, vxi ? vxi->vx_id : 0, vxis, current, |
9829 |
++ current->xid, current->vx_info, _file, _line); |
9830 |
++ vxis->vxi = xchg(¤t->vx_info, vxi); |
9831 |
++ vxis->xid = current->xid; |
9832 |
++ current->xid = vxi ? vxi->vx_id : 0; |
9833 |
++} |
9834 |
++ |
9835 |
++#define leave_vx_info(s) __leave_vx_info(s, __FILE__, __LINE__) |
9836 |
++ |
9837 |
++static inline void __leave_vx_info(struct vx_info_save *vxis, |
9838 |
++ const char *_file, int _line) |
9839 |
++{ |
9840 |
++ vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]", |
9841 |
++ vxis, vxis->xid, vxis->vxi, current, |
9842 |
++ current->xid, current->vx_info, _file, _line); |
9843 |
++ (void)xchg(¤t->vx_info, vxis->vxi); |
9844 |
++ current->xid = vxis->xid; |
9845 |
++} |
9846 |
++ |
9847 |
++ |
9848 |
++static inline void __enter_vx_admin(struct vx_info_save *vxis) |
9849 |
++{ |
9850 |
++ vxis->vxi = xchg(¤t->vx_info, NULL); |
9851 |
++ vxis->xid = xchg(¤t->xid, (xid_t)0); |
9852 |
++} |
9853 |
++ |
9854 |
++static inline void __leave_vx_admin(struct vx_info_save *vxis) |
9855 |
++{ |
9856 |
++ (void)xchg(¤t->xid, vxis->xid); |
9857 |
++ (void)xchg(¤t->vx_info, vxis->vxi); |
9858 |
++} |
9859 |
++ |
9860 |
++extern void exit_vx_info(struct task_struct *, int); |
9861 |
++extern void exit_vx_info_early(struct task_struct *, int); |
9862 |
++ |
9863 |
++ |
9864 |
++#else |
9865 |
++#warning duplicate inclusion |
9866 |
++#endif |
9867 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_cowbl.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_cowbl.h |
9868 |
+--- linux-2.6.29.4/include/linux/vs_cowbl.h 1970-01-01 01:00:00.000000000 +0100 |
9869 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_cowbl.h 2009-02-22 22:54:26.000000000 +0100 |
9870 |
+@@ -0,0 +1,47 @@ |
9871 |
++#ifndef _VS_COWBL_H |
9872 |
++#define _VS_COWBL_H |
9873 |
++ |
9874 |
++#include <linux/fs.h> |
9875 |
++#include <linux/dcache.h> |
9876 |
++#include <linux/namei.h> |
9877 |
++ |
9878 |
++extern struct dentry *cow_break_link(const char *pathname); |
9879 |
++ |
9880 |
++static inline int cow_check_and_break(struct path *path) |
9881 |
++{ |
9882 |
++ struct inode *inode = path->dentry->d_inode; |
9883 |
++ int error = 0; |
9884 |
++ |
9885 |
++ /* do we need this check? */ |
9886 |
++ if (IS_RDONLY(inode)) |
9887 |
++ return -EROFS; |
9888 |
++ |
9889 |
++ if (IS_COW(inode)) { |
9890 |
++ if (IS_COW_LINK(inode)) { |
9891 |
++ struct dentry *new_dentry, *old_dentry = path->dentry; |
9892 |
++ char *pp, *buf; |
9893 |
++ |
9894 |
++ buf = kmalloc(PATH_MAX, GFP_KERNEL); |
9895 |
++ if (!buf) { |
9896 |
++ return -ENOMEM; |
9897 |
++ } |
9898 |
++ pp = d_path(path, buf, PATH_MAX); |
9899 |
++ new_dentry = cow_break_link(pp); |
9900 |
++ kfree(buf); |
9901 |
++ if (!IS_ERR(new_dentry)) { |
9902 |
++ path->dentry = new_dentry; |
9903 |
++ dput(old_dentry); |
9904 |
++ } else |
9905 |
++ error = PTR_ERR(new_dentry); |
9906 |
++ } else { |
9907 |
++ inode->i_flags &= ~(S_IXUNLINK | S_IMMUTABLE); |
9908 |
++ inode->i_ctime = CURRENT_TIME; |
9909 |
++ mark_inode_dirty(inode); |
9910 |
++ } |
9911 |
++ } |
9912 |
++ return error; |
9913 |
++} |
9914 |
++ |
9915 |
++#else |
9916 |
++#warning duplicate inclusion |
9917 |
++#endif |
9918 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_cvirt.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_cvirt.h |
9919 |
+--- linux-2.6.29.4/include/linux/vs_cvirt.h 1970-01-01 01:00:00.000000000 +0100 |
9920 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_cvirt.h 2009-02-22 22:54:26.000000000 +0100 |
9921 |
+@@ -0,0 +1,50 @@ |
9922 |
++#ifndef _VS_CVIRT_H |
9923 |
++#define _VS_CVIRT_H |
9924 |
++ |
9925 |
++#include "vserver/cvirt.h" |
9926 |
++#include "vserver/context.h" |
9927 |
++#include "vserver/base.h" |
9928 |
++#include "vserver/check.h" |
9929 |
++#include "vserver/debug.h" |
9930 |
++ |
9931 |
++ |
9932 |
++static inline void vx_activate_task(struct task_struct *p) |
9933 |
++{ |
9934 |
++ struct vx_info *vxi; |
9935 |
++ |
9936 |
++ if ((vxi = p->vx_info)) { |
9937 |
++ vx_update_load(vxi); |
9938 |
++ atomic_inc(&vxi->cvirt.nr_running); |
9939 |
++ } |
9940 |
++} |
9941 |
++ |
9942 |
++static inline void vx_deactivate_task(struct task_struct *p) |
9943 |
++{ |
9944 |
++ struct vx_info *vxi; |
9945 |
++ |
9946 |
++ if ((vxi = p->vx_info)) { |
9947 |
++ vx_update_load(vxi); |
9948 |
++ atomic_dec(&vxi->cvirt.nr_running); |
9949 |
++ } |
9950 |
++} |
9951 |
++ |
9952 |
++static inline void vx_uninterruptible_inc(struct task_struct *p) |
9953 |
++{ |
9954 |
++ struct vx_info *vxi; |
9955 |
++ |
9956 |
++ if ((vxi = p->vx_info)) |
9957 |
++ atomic_inc(&vxi->cvirt.nr_uninterruptible); |
9958 |
++} |
9959 |
++ |
9960 |
++static inline void vx_uninterruptible_dec(struct task_struct *p) |
9961 |
++{ |
9962 |
++ struct vx_info *vxi; |
9963 |
++ |
9964 |
++ if ((vxi = p->vx_info)) |
9965 |
++ atomic_dec(&vxi->cvirt.nr_uninterruptible); |
9966 |
++} |
9967 |
++ |
9968 |
++ |
9969 |
++#else |
9970 |
++#warning duplicate inclusion |
9971 |
++#endif |
9972 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_device.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_device.h |
9973 |
+--- linux-2.6.29.4/include/linux/vs_device.h 1970-01-01 01:00:00.000000000 +0100 |
9974 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_device.h 2009-02-22 22:54:26.000000000 +0100 |
9975 |
+@@ -0,0 +1,45 @@ |
9976 |
++#ifndef _VS_DEVICE_H |
9977 |
++#define _VS_DEVICE_H |
9978 |
++ |
9979 |
++#include "vserver/base.h" |
9980 |
++#include "vserver/device.h" |
9981 |
++#include "vserver/debug.h" |
9982 |
++ |
9983 |
++ |
9984 |
++#ifdef CONFIG_VSERVER_DEVICE |
9985 |
++ |
9986 |
++int vs_map_device(struct vx_info *, dev_t, dev_t *, umode_t); |
9987 |
++ |
9988 |
++#define vs_device_perm(v, d, m, p) \ |
9989 |
++ ((vs_map_device(current_vx_info(), d, NULL, m) & (p)) == (p)) |
9990 |
++ |
9991 |
++#else |
9992 |
++ |
9993 |
++static inline |
9994 |
++int vs_map_device(struct vx_info *vxi, |
9995 |
++ dev_t device, dev_t *target, umode_t mode) |
9996 |
++{ |
9997 |
++ if (target) |
9998 |
++ *target = device; |
9999 |
++ return ~0; |
10000 |
++} |
10001 |
++ |
10002 |
++#define vs_device_perm(v, d, m, p) ((p) == (p)) |
10003 |
++ |
10004 |
++#endif |
10005 |
++ |
10006 |
++ |
10007 |
++#define vs_map_chrdev(d, t, p) \ |
10008 |
++ ((vs_map_device(current_vx_info(), d, t, S_IFCHR) & (p)) == (p)) |
10009 |
++#define vs_map_blkdev(d, t, p) \ |
10010 |
++ ((vs_map_device(current_vx_info(), d, t, S_IFBLK) & (p)) == (p)) |
10011 |
++ |
10012 |
++#define vs_chrdev_perm(d, p) \ |
10013 |
++ vs_device_perm(current_vx_info(), d, S_IFCHR, p) |
10014 |
++#define vs_blkdev_perm(d, p) \ |
10015 |
++ vs_device_perm(current_vx_info(), d, S_IFBLK, p) |
10016 |
++ |
10017 |
++ |
10018 |
++#else |
10019 |
++#warning duplicate inclusion |
10020 |
++#endif |
10021 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_dlimit.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_dlimit.h |
10022 |
+--- linux-2.6.29.4/include/linux/vs_dlimit.h 1970-01-01 01:00:00.000000000 +0100 |
10023 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_dlimit.h 2009-02-22 22:54:26.000000000 +0100 |
10024 |
+@@ -0,0 +1,211 @@ |
10025 |
++#ifndef _VS_DLIMIT_H |
10026 |
++#define _VS_DLIMIT_H |
10027 |
++ |
10028 |
++#include <linux/fs.h> |
10029 |
++ |
10030 |
++#include "vserver/dlimit.h" |
10031 |
++#include "vserver/base.h" |
10032 |
++#include "vserver/debug.h" |
10033 |
++ |
10034 |
++ |
10035 |
++#define get_dl_info(i) __get_dl_info(i, __FILE__, __LINE__) |
10036 |
++ |
10037 |
++static inline struct dl_info *__get_dl_info(struct dl_info *dli, |
10038 |
++ const char *_file, int _line) |
10039 |
++{ |
10040 |
++ if (!dli) |
10041 |
++ return NULL; |
10042 |
++ vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])", |
10043 |
++ dli, dli ? dli->dl_tag : 0, |
10044 |
++ dli ? atomic_read(&dli->dl_usecnt) : 0, |
10045 |
++ _file, _line); |
10046 |
++ atomic_inc(&dli->dl_usecnt); |
10047 |
++ return dli; |
10048 |
++} |
10049 |
++ |
10050 |
++ |
10051 |
++#define free_dl_info(i) \ |
10052 |
++ call_rcu(&(i)->dl_rcu, rcu_free_dl_info) |
10053 |
++ |
10054 |
++#define put_dl_info(i) __put_dl_info(i, __FILE__, __LINE__) |
10055 |
++ |
10056 |
++static inline void __put_dl_info(struct dl_info *dli, |
10057 |
++ const char *_file, int _line) |
10058 |
++{ |
10059 |
++ if (!dli) |
10060 |
++ return; |
10061 |
++ vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])", |
10062 |
++ dli, dli ? dli->dl_tag : 0, |
10063 |
++ dli ? atomic_read(&dli->dl_usecnt) : 0, |
10064 |
++ _file, _line); |
10065 |
++ if (atomic_dec_and_test(&dli->dl_usecnt)) |
10066 |
++ free_dl_info(dli); |
10067 |
++} |
10068 |
++ |
10069 |
++ |
10070 |
++#define __dlimit_char(d) ((d) ? '*' : ' ') |
10071 |
++ |
10072 |
++static inline int __dl_alloc_space(struct super_block *sb, |
10073 |
++ tag_t tag, dlsize_t nr, const char *file, int line) |
10074 |
++{ |
10075 |
++ struct dl_info *dli = NULL; |
10076 |
++ int ret = 0; |
10077 |
++ |
10078 |
++ if (nr == 0) |
10079 |
++ goto out; |
10080 |
++ dli = locate_dl_info(sb, tag); |
10081 |
++ if (!dli) |
10082 |
++ goto out; |
10083 |
++ |
10084 |
++ spin_lock(&dli->dl_lock); |
10085 |
++ ret = (dli->dl_space_used + nr > dli->dl_space_total); |
10086 |
++ if (!ret) |
10087 |
++ dli->dl_space_used += nr; |
10088 |
++ spin_unlock(&dli->dl_lock); |
10089 |
++ put_dl_info(dli); |
10090 |
++out: |
10091 |
++ vxlprintk(VXD_CBIT(dlim, 1), |
10092 |
++ "ALLOC (%p,#%d)%c %lld bytes (%d)", |
10093 |
++ sb, tag, __dlimit_char(dli), (long long)nr, |
10094 |
++ ret, file, line); |
10095 |
++ return ret; |
10096 |
++} |
10097 |
++ |
10098 |
++static inline void __dl_free_space(struct super_block *sb, |
10099 |
++ tag_t tag, dlsize_t nr, const char *_file, int _line) |
10100 |
++{ |
10101 |
++ struct dl_info *dli = NULL; |
10102 |
++ |
10103 |
++ if (nr == 0) |
10104 |
++ goto out; |
10105 |
++ dli = locate_dl_info(sb, tag); |
10106 |
++ if (!dli) |
10107 |
++ goto out; |
10108 |
++ |
10109 |
++ spin_lock(&dli->dl_lock); |
10110 |
++ if (dli->dl_space_used > nr) |
10111 |
++ dli->dl_space_used -= nr; |
10112 |
++ else |
10113 |
++ dli->dl_space_used = 0; |
10114 |
++ spin_unlock(&dli->dl_lock); |
10115 |
++ put_dl_info(dli); |
10116 |
++out: |
10117 |
++ vxlprintk(VXD_CBIT(dlim, 1), |
10118 |
++ "FREE (%p,#%d)%c %lld bytes", |
10119 |
++ sb, tag, __dlimit_char(dli), (long long)nr, |
10120 |
++ _file, _line); |
10121 |
++} |
10122 |
++ |
10123 |
++static inline int __dl_alloc_inode(struct super_block *sb, |
10124 |
++ tag_t tag, const char *_file, int _line) |
10125 |
++{ |
10126 |
++ struct dl_info *dli; |
10127 |
++ int ret = 0; |
10128 |
++ |
10129 |
++ dli = locate_dl_info(sb, tag); |
10130 |
++ if (!dli) |
10131 |
++ goto out; |
10132 |
++ |
10133 |
++ spin_lock(&dli->dl_lock); |
10134 |
++ ret = (dli->dl_inodes_used >= dli->dl_inodes_total); |
10135 |
++ if (!ret) |
10136 |
++ dli->dl_inodes_used++; |
10137 |
++ spin_unlock(&dli->dl_lock); |
10138 |
++ put_dl_info(dli); |
10139 |
++out: |
10140 |
++ vxlprintk(VXD_CBIT(dlim, 0), |
10141 |
++ "ALLOC (%p,#%d)%c inode (%d)", |
10142 |
++ sb, tag, __dlimit_char(dli), ret, _file, _line); |
10143 |
++ return ret; |
10144 |
++} |
10145 |
++ |
10146 |
++static inline void __dl_free_inode(struct super_block *sb, |
10147 |
++ tag_t tag, const char *_file, int _line) |
10148 |
++{ |
10149 |
++ struct dl_info *dli; |
10150 |
++ |
10151 |
++ dli = locate_dl_info(sb, tag); |
10152 |
++ if (!dli) |
10153 |
++ goto out; |
10154 |
++ |
10155 |
++ spin_lock(&dli->dl_lock); |
10156 |
++ if (dli->dl_inodes_used > 1) |
10157 |
++ dli->dl_inodes_used--; |
10158 |
++ else |
10159 |
++ dli->dl_inodes_used = 0; |
10160 |
++ spin_unlock(&dli->dl_lock); |
10161 |
++ put_dl_info(dli); |
10162 |
++out: |
10163 |
++ vxlprintk(VXD_CBIT(dlim, 0), |
10164 |
++ "FREE (%p,#%d)%c inode", |
10165 |
++ sb, tag, __dlimit_char(dli), _file, _line); |
10166 |
++} |
10167 |
++ |
10168 |
++static inline void __dl_adjust_block(struct super_block *sb, tag_t tag, |
10169 |
++ unsigned long long *free_blocks, unsigned long long *root_blocks, |
10170 |
++ const char *_file, int _line) |
10171 |
++{ |
10172 |
++ struct dl_info *dli; |
10173 |
++ uint64_t broot, bfree; |
10174 |
++ |
10175 |
++ dli = locate_dl_info(sb, tag); |
10176 |
++ if (!dli) |
10177 |
++ return; |
10178 |
++ |
10179 |
++ spin_lock(&dli->dl_lock); |
10180 |
++ broot = (dli->dl_space_total - |
10181 |
++ (dli->dl_space_total >> 10) * dli->dl_nrlmult) |
10182 |
++ >> sb->s_blocksize_bits; |
10183 |
++ bfree = (dli->dl_space_total - dli->dl_space_used) |
10184 |
++ >> sb->s_blocksize_bits; |
10185 |
++ spin_unlock(&dli->dl_lock); |
10186 |
++ |
10187 |
++ vxlprintk(VXD_CBIT(dlim, 2), |
10188 |
++ "ADJUST: %lld,%lld on %lld,%lld [mult=%d]", |
10189 |
++ (long long)bfree, (long long)broot, |
10190 |
++ *free_blocks, *root_blocks, dli->dl_nrlmult, |
10191 |
++ _file, _line); |
10192 |
++ if (free_blocks) { |
10193 |
++ if (*free_blocks > bfree) |
10194 |
++ *free_blocks = bfree; |
10195 |
++ } |
10196 |
++ if (root_blocks) { |
10197 |
++ if (*root_blocks > broot) |
10198 |
++ *root_blocks = broot; |
10199 |
++ } |
10200 |
++ put_dl_info(dli); |
10201 |
++} |
10202 |
++ |
10203 |
++#define DLIMIT_ALLOC_SPACE(in, bytes) \ |
10204 |
++ __dl_alloc_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \ |
10205 |
++ __FILE__, __LINE__ ) |
10206 |
++ |
10207 |
++#define DLIMIT_FREE_SPACE(in, bytes) \ |
10208 |
++ __dl_free_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \ |
10209 |
++ __FILE__, __LINE__ ) |
10210 |
++ |
10211 |
++#define DLIMIT_ALLOC_BLOCK(in, nr) \ |
10212 |
++ __dl_alloc_space((in)->i_sb, (in)->i_tag, \ |
10213 |
++ ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \ |
10214 |
++ __FILE__, __LINE__ ) |
10215 |
++ |
10216 |
++#define DLIMIT_FREE_BLOCK(in, nr) \ |
10217 |
++ __dl_free_space((in)->i_sb, (in)->i_tag, \ |
10218 |
++ ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \ |
10219 |
++ __FILE__, __LINE__ ) |
10220 |
++ |
10221 |
++ |
10222 |
++#define DLIMIT_ALLOC_INODE(in) \ |
10223 |
++ __dl_alloc_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ ) |
10224 |
++ |
10225 |
++#define DLIMIT_FREE_INODE(in) \ |
10226 |
++ __dl_free_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ ) |
10227 |
++ |
10228 |
++ |
10229 |
++#define DLIMIT_ADJUST_BLOCK(sb, tag, fb, rb) \ |
10230 |
++ __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ ) |
10231 |
++ |
10232 |
++ |
10233 |
++#else |
10234 |
++#warning duplicate inclusion |
10235 |
++#endif |
10236 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/base.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/base.h |
10237 |
+--- linux-2.6.29.4/include/linux/vserver/base.h 1970-01-01 01:00:00.000000000 +0100 |
10238 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/base.h 2009-03-25 00:36:15.000000000 +0100 |
10239 |
+@@ -0,0 +1,157 @@ |
10240 |
++#ifndef _VX_BASE_H |
10241 |
++#define _VX_BASE_H |
10242 |
++ |
10243 |
++ |
10244 |
++/* context state changes */ |
10245 |
++ |
10246 |
++enum { |
10247 |
++ VSC_STARTUP = 1, |
10248 |
++ VSC_SHUTDOWN, |
10249 |
++ |
10250 |
++ VSC_NETUP, |
10251 |
++ VSC_NETDOWN, |
10252 |
++}; |
10253 |
++ |
10254 |
++ |
10255 |
++ |
10256 |
++#define vx_task_xid(t) ((t)->xid) |
10257 |
++ |
10258 |
++#define vx_current_xid() vx_task_xid(current) |
10259 |
++ |
10260 |
++#define current_vx_info() (current->vx_info) |
10261 |
++ |
10262 |
++ |
10263 |
++#define nx_task_nid(t) ((t)->nid) |
10264 |
++ |
10265 |
++#define nx_current_nid() nx_task_nid(current) |
10266 |
++ |
10267 |
++#define current_nx_info() (current->nx_info) |
10268 |
++ |
10269 |
++ |
10270 |
++/* generic flag merging */ |
10271 |
++ |
10272 |
++#define vs_check_flags(v, m, f) (((v) & (m)) ^ (f)) |
10273 |
++ |
10274 |
++#define vs_mask_flags(v, f, m) (((v) & ~(m)) | ((f) & (m))) |
10275 |
++ |
10276 |
++#define vs_mask_mask(v, f, m) (((v) & ~(m)) | ((v) & (f) & (m))) |
10277 |
++ |
10278 |
++#define vs_check_bit(v, n) ((v) & (1LL << (n))) |
10279 |
++ |
10280 |
++ |
10281 |
++/* context flags */ |
10282 |
++ |
10283 |
++#define __vx_flags(v) ((v) ? (v)->vx_flags : 0) |
10284 |
++ |
10285 |
++#define vx_current_flags() __vx_flags(current->vx_info) |
10286 |
++ |
10287 |
++#define vx_info_flags(v, m, f) \ |
10288 |
++ vs_check_flags(__vx_flags(v), m, f) |
10289 |
++ |
10290 |
++#define task_vx_flags(t, m, f) \ |
10291 |
++ ((t) && vx_info_flags((t)->vx_info, m, f)) |
10292 |
++ |
10293 |
++#define vx_flags(m, f) vx_info_flags(current->vx_info, m, f) |
10294 |
++ |
10295 |
++ |
10296 |
++/* context caps */ |
10297 |
++ |
10298 |
++#define __vx_ccaps(v) ((v) ? (v)->vx_ccaps : 0) |
10299 |
++ |
10300 |
++#define vx_current_ccaps() __vx_ccaps(current->vx_info) |
10301 |
++ |
10302 |
++#define vx_info_ccaps(v, c) (__vx_ccaps(v) & (c)) |
10303 |
++ |
10304 |
++#define vx_ccaps(c) vx_info_ccaps(current->vx_info, (c)) |
10305 |
++ |
10306 |
++ |
10307 |
++ |
10308 |
++/* network flags */ |
10309 |
++ |
10310 |
++#define __nx_flags(n) ((n) ? (n)->nx_flags : 0) |
10311 |
++ |
10312 |
++#define nx_current_flags() __nx_flags(current->nx_info) |
10313 |
++ |
10314 |
++#define nx_info_flags(n, m, f) \ |
10315 |
++ vs_check_flags(__nx_flags(n), m, f) |
10316 |
++ |
10317 |
++#define task_nx_flags(t, m, f) \ |
10318 |
++ ((t) && nx_info_flags((t)->nx_info, m, f)) |
10319 |
++ |
10320 |
++#define nx_flags(m, f) nx_info_flags(current->nx_info, m, f) |
10321 |
++ |
10322 |
++ |
10323 |
++/* network caps */ |
10324 |
++ |
10325 |
++#define __nx_ncaps(n) ((n) ? (n)->nx_ncaps : 0) |
10326 |
++ |
10327 |
++#define nx_current_ncaps() __nx_ncaps(current->nx_info) |
10328 |
++ |
10329 |
++#define nx_info_ncaps(n, c) (__nx_ncaps(n) & (c)) |
10330 |
++ |
10331 |
++#define nx_ncaps(c) nx_info_ncaps(current->nx_info, c) |
10332 |
++ |
10333 |
++ |
10334 |
++/* context mask capabilities */ |
10335 |
++ |
10336 |
++#define __vx_mcaps(v) ((v) ? (v)->vx_ccaps >> 32UL : ~0 ) |
10337 |
++ |
10338 |
++#define vx_info_mcaps(v, c) (__vx_mcaps(v) & (c)) |
10339 |
++ |
10340 |
++#define vx_mcaps(c) vx_info_mcaps(current->vx_info, c) |
10341 |
++ |
10342 |
++ |
10343 |
++/* context bcap mask */ |
10344 |
++ |
10345 |
++#define __vx_bcaps(v) ((v)->vx_bcaps) |
10346 |
++ |
10347 |
++#define vx_current_bcaps() __vx_bcaps(current->vx_info) |
10348 |
++ |
10349 |
++ |
10350 |
++/* mask given bcaps */ |
10351 |
++ |
10352 |
++#define vx_info_mbcaps(v, c) ((v) ? cap_intersect(__vx_bcaps(v), c) : c) |
10353 |
++ |
10354 |
++#define vx_mbcaps(c) vx_info_mbcaps(current->vx_info, c) |
10355 |
++ |
10356 |
++ |
10357 |
++/* masked cap_bset */ |
10358 |
++ |
10359 |
++#define vx_info_cap_bset(v) vx_info_mbcaps(v, current->cap_bset) |
10360 |
++ |
10361 |
++#define vx_current_cap_bset() vx_info_cap_bset(current->vx_info) |
10362 |
++ |
10363 |
++#if 0 |
10364 |
++#define vx_info_mbcap(v, b) \ |
10365 |
++ (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \ |
10366 |
++ vx_info_bcaps(v, b) : (b)) |
10367 |
++ |
10368 |
++#define task_vx_mbcap(t, b) \ |
10369 |
++ vx_info_mbcap((t)->vx_info, (t)->b) |
10370 |
++ |
10371 |
++#define vx_mbcap(b) task_vx_mbcap(current, b) |
10372 |
++#endif |
10373 |
++ |
10374 |
++#define vx_cap_raised(v, c, f) cap_raised(vx_info_mbcaps(v, c), f) |
10375 |
++ |
10376 |
++#define vx_capable(b, c) (capable(b) || \ |
10377 |
++ (cap_raised(current_cap(), b) && vx_ccaps(c))) |
10378 |
++ |
10379 |
++#define nx_capable(b, c) (capable(b) || \ |
10380 |
++ (cap_raised(current_cap(), b) && nx_ncaps(c))) |
10381 |
++ |
10382 |
++#define vx_current_initpid(n) \ |
10383 |
++ (current->vx_info && \ |
10384 |
++ (current->vx_info->vx_initpid == (n))) |
10385 |
++ |
10386 |
++ |
10387 |
++#define __vx_state(v) ((v) ? ((v)->vx_state) : 0) |
10388 |
++ |
10389 |
++#define vx_info_state(v, m) (__vx_state(v) & (m)) |
10390 |
++ |
10391 |
++ |
10392 |
++#define __nx_state(n) ((n) ? ((n)->nx_state) : 0) |
10393 |
++ |
10394 |
++#define nx_info_state(n, m) (__nx_state(n) & (m)) |
10395 |
++ |
10396 |
++#endif |
10397 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/cacct_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cacct_cmd.h |
10398 |
+--- linux-2.6.29.4/include/linux/vserver/cacct_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
10399 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cacct_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
10400 |
+@@ -0,0 +1,23 @@ |
10401 |
++#ifndef _VX_CACCT_CMD_H |
10402 |
++#define _VX_CACCT_CMD_H |
10403 |
++ |
10404 |
++ |
10405 |
++/* virtual host info name commands */ |
10406 |
++ |
10407 |
++#define VCMD_sock_stat VC_CMD(VSTAT, 5, 0) |
10408 |
++ |
10409 |
++struct vcmd_sock_stat_v0 { |
10410 |
++ uint32_t field; |
10411 |
++ uint32_t count[3]; |
10412 |
++ uint64_t total[3]; |
10413 |
++}; |
10414 |
++ |
10415 |
++ |
10416 |
++#ifdef __KERNEL__ |
10417 |
++ |
10418 |
++#include <linux/compiler.h> |
10419 |
++ |
10420 |
++extern int vc_sock_stat(struct vx_info *, void __user *); |
10421 |
++ |
10422 |
++#endif /* __KERNEL__ */ |
10423 |
++#endif /* _VX_CACCT_CMD_H */ |
10424 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/cacct_def.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cacct_def.h |
10425 |
+--- linux-2.6.29.4/include/linux/vserver/cacct_def.h 1970-01-01 01:00:00.000000000 +0100 |
10426 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cacct_def.h 2009-02-22 22:54:26.000000000 +0100 |
10427 |
+@@ -0,0 +1,43 @@ |
10428 |
++#ifndef _VX_CACCT_DEF_H |
10429 |
++#define _VX_CACCT_DEF_H |
10430 |
++ |
10431 |
++#include <asm/atomic.h> |
10432 |
++#include <linux/vserver/cacct.h> |
10433 |
++ |
10434 |
++ |
10435 |
++struct _vx_sock_acc { |
10436 |
++ atomic_long_t count; |
10437 |
++ atomic_long_t total; |
10438 |
++}; |
10439 |
++ |
10440 |
++/* context sub struct */ |
10441 |
++ |
10442 |
++struct _vx_cacct { |
10443 |
++ struct _vx_sock_acc sock[VXA_SOCK_SIZE][3]; |
10444 |
++ atomic_t slab[8]; |
10445 |
++ atomic_t page[6][8]; |
10446 |
++}; |
10447 |
++ |
10448 |
++#ifdef CONFIG_VSERVER_DEBUG |
10449 |
++ |
10450 |
++static inline void __dump_vx_cacct(struct _vx_cacct *cacct) |
10451 |
++{ |
10452 |
++ int i, j; |
10453 |
++ |
10454 |
++ printk("\t_vx_cacct:"); |
10455 |
++ for (i = 0; i < 6; i++) { |
10456 |
++ struct _vx_sock_acc *ptr = cacct->sock[i]; |
10457 |
++ |
10458 |
++ printk("\t [%d] =", i); |
10459 |
++ for (j = 0; j < 3; j++) { |
10460 |
++ printk(" [%d] = %8lu, %8lu", j, |
10461 |
++ atomic_long_read(&ptr[j].count), |
10462 |
++ atomic_long_read(&ptr[j].total)); |
10463 |
++ } |
10464 |
++ printk("\n"); |
10465 |
++ } |
10466 |
++} |
10467 |
++ |
10468 |
++#endif |
10469 |
++ |
10470 |
++#endif /* _VX_CACCT_DEF_H */ |
10471 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/cacct.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cacct.h |
10472 |
+--- linux-2.6.29.4/include/linux/vserver/cacct.h 1970-01-01 01:00:00.000000000 +0100 |
10473 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cacct.h 2009-02-22 22:54:26.000000000 +0100 |
10474 |
+@@ -0,0 +1,15 @@ |
10475 |
++#ifndef _VX_CACCT_H |
10476 |
++#define _VX_CACCT_H |
10477 |
++ |
10478 |
++ |
10479 |
++enum sock_acc_field { |
10480 |
++ VXA_SOCK_UNSPEC = 0, |
10481 |
++ VXA_SOCK_UNIX, |
10482 |
++ VXA_SOCK_INET, |
10483 |
++ VXA_SOCK_INET6, |
10484 |
++ VXA_SOCK_PACKET, |
10485 |
++ VXA_SOCK_OTHER, |
10486 |
++ VXA_SOCK_SIZE /* array size */ |
10487 |
++}; |
10488 |
++ |
10489 |
++#endif /* _VX_CACCT_H */ |
10490 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/cacct_int.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cacct_int.h |
10491 |
+--- linux-2.6.29.4/include/linux/vserver/cacct_int.h 1970-01-01 01:00:00.000000000 +0100 |
10492 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cacct_int.h 2009-02-22 22:54:26.000000000 +0100 |
10493 |
+@@ -0,0 +1,21 @@ |
10494 |
++#ifndef _VX_CACCT_INT_H |
10495 |
++#define _VX_CACCT_INT_H |
10496 |
++ |
10497 |
++ |
10498 |
++#ifdef __KERNEL__ |
10499 |
++ |
10500 |
++static inline |
10501 |
++unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos) |
10502 |
++{ |
10503 |
++ return atomic_long_read(&cacct->sock[type][pos].count); |
10504 |
++} |
10505 |
++ |
10506 |
++ |
10507 |
++static inline |
10508 |
++unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos) |
10509 |
++{ |
10510 |
++ return atomic_long_read(&cacct->sock[type][pos].total); |
10511 |
++} |
10512 |
++ |
10513 |
++#endif /* __KERNEL__ */ |
10514 |
++#endif /* _VX_CACCT_INT_H */ |
10515 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/check.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/check.h |
10516 |
+--- linux-2.6.29.4/include/linux/vserver/check.h 1970-01-01 01:00:00.000000000 +0100 |
10517 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/check.h 2009-02-22 22:54:26.000000000 +0100 |
10518 |
+@@ -0,0 +1,89 @@ |
10519 |
++#ifndef _VS_CHECK_H |
10520 |
++#define _VS_CHECK_H |
10521 |
++ |
10522 |
++ |
10523 |
++#define MAX_S_CONTEXT 65535 /* Arbitrary limit */ |
10524 |
++ |
10525 |
++#ifdef CONFIG_VSERVER_DYNAMIC_IDS |
10526 |
++#define MIN_D_CONTEXT 49152 /* dynamic contexts start here */ |
10527 |
++#else |
10528 |
++#define MIN_D_CONTEXT 65536 |
10529 |
++#endif |
10530 |
++ |
10531 |
++/* check conditions */ |
10532 |
++ |
10533 |
++#define VS_ADMIN 0x0001 |
10534 |
++#define VS_WATCH 0x0002 |
10535 |
++#define VS_HIDE 0x0004 |
10536 |
++#define VS_HOSTID 0x0008 |
10537 |
++ |
10538 |
++#define VS_IDENT 0x0010 |
10539 |
++#define VS_EQUIV 0x0020 |
10540 |
++#define VS_PARENT 0x0040 |
10541 |
++#define VS_CHILD 0x0080 |
10542 |
++ |
10543 |
++#define VS_ARG_MASK 0x00F0 |
10544 |
++ |
10545 |
++#define VS_DYNAMIC 0x0100 |
10546 |
++#define VS_STATIC 0x0200 |
10547 |
++ |
10548 |
++#define VS_ATR_MASK 0x0F00 |
10549 |
++ |
10550 |
++#ifdef CONFIG_VSERVER_PRIVACY |
10551 |
++#define VS_ADMIN_P (0) |
10552 |
++#define VS_WATCH_P (0) |
10553 |
++#else |
10554 |
++#define VS_ADMIN_P VS_ADMIN |
10555 |
++#define VS_WATCH_P VS_WATCH |
10556 |
++#endif |
10557 |
++ |
10558 |
++#define VS_HARDIRQ 0x1000 |
10559 |
++#define VS_SOFTIRQ 0x2000 |
10560 |
++#define VS_IRQ 0x4000 |
10561 |
++ |
10562 |
++#define VS_IRQ_MASK 0xF000 |
10563 |
++ |
10564 |
++#include <linux/hardirq.h> |
10565 |
++ |
10566 |
++/* |
10567 |
++ * check current context for ADMIN/WATCH and |
10568 |
++ * optionally against supplied argument |
10569 |
++ */ |
10570 |
++static inline int __vs_check(int cid, int id, unsigned int mode) |
10571 |
++{ |
10572 |
++ if (mode & VS_ARG_MASK) { |
10573 |
++ if ((mode & VS_IDENT) && (id == cid)) |
10574 |
++ return 1; |
10575 |
++ } |
10576 |
++ if (mode & VS_ATR_MASK) { |
10577 |
++ if ((mode & VS_DYNAMIC) && |
10578 |
++ (id >= MIN_D_CONTEXT) && |
10579 |
++ (id <= MAX_S_CONTEXT)) |
10580 |
++ return 1; |
10581 |
++ if ((mode & VS_STATIC) && |
10582 |
++ (id > 1) && (id < MIN_D_CONTEXT)) |
10583 |
++ return 1; |
10584 |
++ } |
10585 |
++ if (mode & VS_IRQ_MASK) { |
10586 |
++ if ((mode & VS_IRQ) && unlikely(in_interrupt())) |
10587 |
++ return 1; |
10588 |
++ if ((mode & VS_HARDIRQ) && unlikely(in_irq())) |
10589 |
++ return 1; |
10590 |
++ if ((mode & VS_SOFTIRQ) && unlikely(in_softirq())) |
10591 |
++ return 1; |
10592 |
++ } |
10593 |
++ return (((mode & VS_ADMIN) && (cid == 0)) || |
10594 |
++ ((mode & VS_WATCH) && (cid == 1)) || |
10595 |
++ ((mode & VS_HOSTID) && (id == 0))); |
10596 |
++} |
10597 |
++ |
10598 |
++#define vx_check(c, m) __vs_check(vx_current_xid(), c, (m) | VS_IRQ) |
10599 |
++ |
10600 |
++#define vx_weak_check(c, m) ((m) ? vx_check(c, m) : 1) |
10601 |
++ |
10602 |
++ |
10603 |
++#define nx_check(c, m) __vs_check(nx_current_nid(), c, m) |
10604 |
++ |
10605 |
++#define nx_weak_check(c, m) ((m) ? nx_check(c, m) : 1) |
10606 |
++ |
10607 |
++#endif |
10608 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/context_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/context_cmd.h |
10609 |
+--- linux-2.6.29.4/include/linux/vserver/context_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
10610 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/context_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
10611 |
+@@ -0,0 +1,128 @@ |
10612 |
++#ifndef _VX_CONTEXT_CMD_H |
10613 |
++#define _VX_CONTEXT_CMD_H |
10614 |
++ |
10615 |
++ |
10616 |
++/* vinfo commands */ |
10617 |
++ |
10618 |
++#define VCMD_task_xid VC_CMD(VINFO, 1, 0) |
10619 |
++ |
10620 |
++#ifdef __KERNEL__ |
10621 |
++extern int vc_task_xid(uint32_t); |
10622 |
++ |
10623 |
++#endif /* __KERNEL__ */ |
10624 |
++ |
10625 |
++#define VCMD_vx_info VC_CMD(VINFO, 5, 0) |
10626 |
++ |
10627 |
++struct vcmd_vx_info_v0 { |
10628 |
++ uint32_t xid; |
10629 |
++ uint32_t initpid; |
10630 |
++ /* more to come */ |
10631 |
++}; |
10632 |
++ |
10633 |
++#ifdef __KERNEL__ |
10634 |
++extern int vc_vx_info(struct vx_info *, void __user *); |
10635 |
++ |
10636 |
++#endif /* __KERNEL__ */ |
10637 |
++ |
10638 |
++#define VCMD_ctx_stat VC_CMD(VSTAT, 0, 0) |
10639 |
++ |
10640 |
++struct vcmd_ctx_stat_v0 { |
10641 |
++ uint32_t usecnt; |
10642 |
++ uint32_t tasks; |
10643 |
++ /* more to come */ |
10644 |
++}; |
10645 |
++ |
10646 |
++#ifdef __KERNEL__ |
10647 |
++extern int vc_ctx_stat(struct vx_info *, void __user *); |
10648 |
++ |
10649 |
++#endif /* __KERNEL__ */ |
10650 |
++ |
10651 |
++/* context commands */ |
10652 |
++ |
10653 |
++#define VCMD_ctx_create_v0 VC_CMD(VPROC, 1, 0) |
10654 |
++#define VCMD_ctx_create VC_CMD(VPROC, 1, 1) |
10655 |
++ |
10656 |
++struct vcmd_ctx_create { |
10657 |
++ uint64_t flagword; |
10658 |
++}; |
10659 |
++ |
10660 |
++#define VCMD_ctx_migrate_v0 VC_CMD(PROCMIG, 1, 0) |
10661 |
++#define VCMD_ctx_migrate VC_CMD(PROCMIG, 1, 1) |
10662 |
++ |
10663 |
++struct vcmd_ctx_migrate { |
10664 |
++ uint64_t flagword; |
10665 |
++}; |
10666 |
++ |
10667 |
++#ifdef __KERNEL__ |
10668 |
++extern int vc_ctx_create(uint32_t, void __user *); |
10669 |
++extern int vc_ctx_migrate(struct vx_info *, void __user *); |
10670 |
++ |
10671 |
++#endif /* __KERNEL__ */ |
10672 |
++ |
10673 |
++ |
10674 |
++/* flag commands */ |
10675 |
++ |
10676 |
++#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0) |
10677 |
++#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0) |
10678 |
++ |
10679 |
++struct vcmd_ctx_flags_v0 { |
10680 |
++ uint64_t flagword; |
10681 |
++ uint64_t mask; |
10682 |
++}; |
10683 |
++ |
10684 |
++#ifdef __KERNEL__ |
10685 |
++extern int vc_get_cflags(struct vx_info *, void __user *); |
10686 |
++extern int vc_set_cflags(struct vx_info *, void __user *); |
10687 |
++ |
10688 |
++#endif /* __KERNEL__ */ |
10689 |
++ |
10690 |
++ |
10691 |
++/* context caps commands */ |
10692 |
++ |
10693 |
++#define VCMD_get_ccaps VC_CMD(FLAGS, 3, 1) |
10694 |
++#define VCMD_set_ccaps VC_CMD(FLAGS, 4, 1) |
10695 |
++ |
10696 |
++struct vcmd_ctx_caps_v1 { |
10697 |
++ uint64_t ccaps; |
10698 |
++ uint64_t cmask; |
10699 |
++}; |
10700 |
++ |
10701 |
++#ifdef __KERNEL__ |
10702 |
++extern int vc_get_ccaps(struct vx_info *, void __user *); |
10703 |
++extern int vc_set_ccaps(struct vx_info *, void __user *); |
10704 |
++ |
10705 |
++#endif /* __KERNEL__ */ |
10706 |
++ |
10707 |
++ |
10708 |
++/* bcaps commands */ |
10709 |
++ |
10710 |
++#define VCMD_get_bcaps VC_CMD(FLAGS, 9, 0) |
10711 |
++#define VCMD_set_bcaps VC_CMD(FLAGS, 10, 0) |
10712 |
++ |
10713 |
++struct vcmd_bcaps { |
10714 |
++ uint64_t bcaps; |
10715 |
++ uint64_t bmask; |
10716 |
++}; |
10717 |
++ |
10718 |
++#ifdef __KERNEL__ |
10719 |
++extern int vc_get_bcaps(struct vx_info *, void __user *); |
10720 |
++extern int vc_set_bcaps(struct vx_info *, void __user *); |
10721 |
++ |
10722 |
++#endif /* __KERNEL__ */ |
10723 |
++ |
10724 |
++ |
10725 |
++/* OOM badness */ |
10726 |
++ |
10727 |
++#define VCMD_get_badness VC_CMD(MEMCTRL, 5, 0) |
10728 |
++#define VCMD_set_badness VC_CMD(MEMCTRL, 6, 0) |
10729 |
++ |
10730 |
++struct vcmd_badness_v0 { |
10731 |
++ int64_t bias; |
10732 |
++}; |
10733 |
++ |
10734 |
++#ifdef __KERNEL__ |
10735 |
++extern int vc_get_badness(struct vx_info *, void __user *); |
10736 |
++extern int vc_set_badness(struct vx_info *, void __user *); |
10737 |
++ |
10738 |
++#endif /* __KERNEL__ */ |
10739 |
++#endif /* _VX_CONTEXT_CMD_H */ |
10740 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/context.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/context.h |
10741 |
+--- linux-2.6.29.4/include/linux/vserver/context.h 1970-01-01 01:00:00.000000000 +0100 |
10742 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/context.h 2009-02-22 22:54:26.000000000 +0100 |
10743 |
+@@ -0,0 +1,179 @@ |
10744 |
++#ifndef _VX_CONTEXT_H |
10745 |
++#define _VX_CONTEXT_H |
10746 |
++ |
10747 |
++#include <linux/types.h> |
10748 |
++#include <linux/capability.h> |
10749 |
++ |
10750 |
++ |
10751 |
++/* context flags */ |
10752 |
++ |
10753 |
++#define VXF_INFO_SCHED 0x00000002 |
10754 |
++#define VXF_INFO_NPROC 0x00000004 |
10755 |
++#define VXF_INFO_PRIVATE 0x00000008 |
10756 |
++ |
10757 |
++#define VXF_INFO_INIT 0x00000010 |
10758 |
++#define VXF_INFO_HIDE 0x00000020 |
10759 |
++#define VXF_INFO_ULIMIT 0x00000040 |
10760 |
++#define VXF_INFO_NSPACE 0x00000080 |
10761 |
++ |
10762 |
++#define VXF_SCHED_HARD 0x00000100 |
10763 |
++#define VXF_SCHED_PRIO 0x00000200 |
10764 |
++#define VXF_SCHED_PAUSE 0x00000400 |
10765 |
++ |
10766 |
++#define VXF_VIRT_MEM 0x00010000 |
10767 |
++#define VXF_VIRT_UPTIME 0x00020000 |
10768 |
++#define VXF_VIRT_CPU 0x00040000 |
10769 |
++#define VXF_VIRT_LOAD 0x00080000 |
10770 |
++#define VXF_VIRT_TIME 0x00100000 |
10771 |
++ |
10772 |
++#define VXF_HIDE_MOUNT 0x01000000 |
10773 |
++/* was VXF_HIDE_NETIF 0x02000000 */ |
10774 |
++#define VXF_HIDE_VINFO 0x04000000 |
10775 |
++ |
10776 |
++#define VXF_STATE_SETUP (1ULL << 32) |
10777 |
++#define VXF_STATE_INIT (1ULL << 33) |
10778 |
++#define VXF_STATE_ADMIN (1ULL << 34) |
10779 |
++ |
10780 |
++#define VXF_SC_HELPER (1ULL << 36) |
10781 |
++#define VXF_REBOOT_KILL (1ULL << 37) |
10782 |
++#define VXF_PERSISTENT (1ULL << 38) |
10783 |
++ |
10784 |
++#define VXF_FORK_RSS (1ULL << 48) |
10785 |
++#define VXF_PROLIFIC (1ULL << 49) |
10786 |
++ |
10787 |
++#define VXF_IGNEG_NICE (1ULL << 52) |
10788 |
++ |
10789 |
++#define VXF_ONE_TIME (0x0007ULL << 32) |
10790 |
++ |
10791 |
++#define VXF_INIT_SET (VXF_STATE_SETUP | VXF_STATE_INIT | VXF_STATE_ADMIN) |
10792 |
++ |
10793 |
++ |
10794 |
++/* context migration */ |
10795 |
++ |
10796 |
++#define VXM_SET_INIT 0x00000001 |
10797 |
++#define VXM_SET_REAPER 0x00000002 |
10798 |
++ |
10799 |
++/* context caps */ |
10800 |
++ |
10801 |
++#define VXC_CAP_MASK 0x00000000 |
10802 |
++ |
10803 |
++#define VXC_SET_UTSNAME 0x00000001 |
10804 |
++#define VXC_SET_RLIMIT 0x00000002 |
10805 |
++#define VXC_FS_SECURITY 0x00000004 |
10806 |
++ |
10807 |
++/* was VXC_RAW_ICMP 0x00000100 */ |
10808 |
++#define VXC_SYSLOG 0x00001000 |
10809 |
++ |
10810 |
++#define VXC_SECURE_MOUNT 0x00010000 |
10811 |
++#define VXC_SECURE_REMOUNT 0x00020000 |
10812 |
++#define VXC_BINARY_MOUNT 0x00040000 |
10813 |
++ |
10814 |
++#define VXC_QUOTA_CTL 0x00100000 |
10815 |
++#define VXC_ADMIN_MAPPER 0x00200000 |
10816 |
++#define VXC_ADMIN_CLOOP 0x00400000 |
10817 |
++ |
10818 |
++#define VXC_KTHREAD 0x01000000 |
10819 |
++ |
10820 |
++ |
10821 |
++#ifdef __KERNEL__ |
10822 |
++ |
10823 |
++#include <linux/list.h> |
10824 |
++#include <linux/spinlock.h> |
10825 |
++#include <linux/rcupdate.h> |
10826 |
++ |
10827 |
++#include "limit_def.h" |
10828 |
++#include "sched_def.h" |
10829 |
++#include "cvirt_def.h" |
10830 |
++#include "cacct_def.h" |
10831 |
++#include "device_def.h" |
10832 |
++ |
10833 |
++#define VX_SPACES 2 |
10834 |
++ |
10835 |
++struct _vx_info_pc { |
10836 |
++ struct _vx_sched_pc sched_pc; |
10837 |
++ struct _vx_cvirt_pc cvirt_pc; |
10838 |
++}; |
10839 |
++ |
10840 |
++struct vx_info { |
10841 |
++ struct hlist_node vx_hlist; /* linked list of contexts */ |
10842 |
++ xid_t vx_id; /* context id */ |
10843 |
++ atomic_t vx_usecnt; /* usage count */ |
10844 |
++ atomic_t vx_tasks; /* tasks count */ |
10845 |
++ struct vx_info *vx_parent; /* parent context */ |
10846 |
++ int vx_state; /* context state */ |
10847 |
++ |
10848 |
++ unsigned long vx_nsmask[VX_SPACES]; /* assignment mask */ |
10849 |
++ struct nsproxy *vx_nsproxy[VX_SPACES]; /* private namespaces */ |
10850 |
++ struct fs_struct *vx_fs[VX_SPACES]; /* private namespace fs */ |
10851 |
++ |
10852 |
++ uint64_t vx_flags; /* context flags */ |
10853 |
++ uint64_t vx_ccaps; /* context caps (vserver) */ |
10854 |
++ kernel_cap_t vx_bcaps; /* bounding caps (system) */ |
10855 |
++ // kernel_cap_t vx_cap_bset; /* the guest's bset */ |
10856 |
++ |
10857 |
++ struct task_struct *vx_reaper; /* guest reaper process */ |
10858 |
++ pid_t vx_initpid; /* PID of guest init */ |
10859 |
++ int64_t vx_badness_bias; /* OOM points bias */ |
10860 |
++ |
10861 |
++ struct _vx_limit limit; /* vserver limits */ |
10862 |
++ struct _vx_sched sched; /* vserver scheduler */ |
10863 |
++ struct _vx_cvirt cvirt; /* virtual/bias stuff */ |
10864 |
++ struct _vx_cacct cacct; /* context accounting */ |
10865 |
++ |
10866 |
++ struct _vx_device dmap; /* default device map targets */ |
10867 |
++ |
10868 |
++#ifndef CONFIG_SMP |
10869 |
++ struct _vx_info_pc info_pc; /* per cpu data */ |
10870 |
++#else |
10871 |
++ struct _vx_info_pc *ptr_pc; /* per cpu array */ |
10872 |
++#endif |
10873 |
++ |
10874 |
++ wait_queue_head_t vx_wait; /* context exit waitqueue */ |
10875 |
++ int reboot_cmd; /* last sys_reboot() cmd */ |
10876 |
++ int exit_code; /* last process exit code */ |
10877 |
++ |
10878 |
++ char vx_name[65]; /* vserver name */ |
10879 |
++}; |
10880 |
++ |
10881 |
++#ifndef CONFIG_SMP |
10882 |
++#define vx_ptr_pc(vxi) (&(vxi)->info_pc) |
10883 |
++#define vx_per_cpu(vxi, v, id) vx_ptr_pc(vxi)->v |
10884 |
++#else |
10885 |
++#define vx_ptr_pc(vxi) ((vxi)->ptr_pc) |
10886 |
++#define vx_per_cpu(vxi, v, id) per_cpu_ptr(vx_ptr_pc(vxi), id)->v |
10887 |
++#endif |
10888 |
++ |
10889 |
++#define vx_cpu(vxi, v) vx_per_cpu(vxi, v, smp_processor_id()) |
10890 |
++ |
10891 |
++ |
10892 |
++struct vx_info_save { |
10893 |
++ struct vx_info *vxi; |
10894 |
++ xid_t xid; |
10895 |
++}; |
10896 |
++ |
10897 |
++ |
10898 |
++/* status flags */ |
10899 |
++ |
10900 |
++#define VXS_HASHED 0x0001 |
10901 |
++#define VXS_PAUSED 0x0010 |
10902 |
++#define VXS_SHUTDOWN 0x0100 |
10903 |
++#define VXS_HELPER 0x1000 |
10904 |
++#define VXS_RELEASED 0x8000 |
10905 |
++ |
10906 |
++ |
10907 |
++extern void claim_vx_info(struct vx_info *, struct task_struct *); |
10908 |
++extern void release_vx_info(struct vx_info *, struct task_struct *); |
10909 |
++ |
10910 |
++extern struct vx_info *lookup_vx_info(int); |
10911 |
++extern struct vx_info *lookup_or_create_vx_info(int); |
10912 |
++ |
10913 |
++extern int get_xid_list(int, unsigned int *, int); |
10914 |
++extern int xid_is_hashed(xid_t); |
10915 |
++ |
10916 |
++extern int vx_migrate_task(struct task_struct *, struct vx_info *, int); |
10917 |
++ |
10918 |
++extern long vs_state_change(struct vx_info *, unsigned int); |
10919 |
++ |
10920 |
++ |
10921 |
++#endif /* __KERNEL__ */ |
10922 |
++#endif /* _VX_CONTEXT_H */ |
10923 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/cvirt_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cvirt_cmd.h |
10924 |
+--- linux-2.6.29.4/include/linux/vserver/cvirt_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
10925 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cvirt_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
10926 |
+@@ -0,0 +1,53 @@ |
10927 |
++#ifndef _VX_CVIRT_CMD_H |
10928 |
++#define _VX_CVIRT_CMD_H |
10929 |
++ |
10930 |
++ |
10931 |
++/* virtual host info name commands */ |
10932 |
++ |
10933 |
++#define VCMD_set_vhi_name VC_CMD(VHOST, 1, 0) |
10934 |
++#define VCMD_get_vhi_name VC_CMD(VHOST, 2, 0) |
10935 |
++ |
10936 |
++struct vcmd_vhi_name_v0 { |
10937 |
++ uint32_t field; |
10938 |
++ char name[65]; |
10939 |
++}; |
10940 |
++ |
10941 |
++ |
10942 |
++enum vhi_name_field { |
10943 |
++ VHIN_CONTEXT = 0, |
10944 |
++ VHIN_SYSNAME, |
10945 |
++ VHIN_NODENAME, |
10946 |
++ VHIN_RELEASE, |
10947 |
++ VHIN_VERSION, |
10948 |
++ VHIN_MACHINE, |
10949 |
++ VHIN_DOMAINNAME, |
10950 |
++}; |
10951 |
++ |
10952 |
++ |
10953 |
++#ifdef __KERNEL__ |
10954 |
++ |
10955 |
++#include <linux/compiler.h> |
10956 |
++ |
10957 |
++extern int vc_set_vhi_name(struct vx_info *, void __user *); |
10958 |
++extern int vc_get_vhi_name(struct vx_info *, void __user *); |
10959 |
++ |
10960 |
++#endif /* __KERNEL__ */ |
10961 |
++ |
10962 |
++#define VCMD_virt_stat VC_CMD(VSTAT, 3, 0) |
10963 |
++ |
10964 |
++struct vcmd_virt_stat_v0 { |
10965 |
++ uint64_t offset; |
10966 |
++ uint64_t uptime; |
10967 |
++ uint32_t nr_threads; |
10968 |
++ uint32_t nr_running; |
10969 |
++ uint32_t nr_uninterruptible; |
10970 |
++ uint32_t nr_onhold; |
10971 |
++ uint32_t nr_forks; |
10972 |
++ uint32_t load[3]; |
10973 |
++}; |
10974 |
++ |
10975 |
++#ifdef __KERNEL__ |
10976 |
++extern int vc_virt_stat(struct vx_info *, void __user *); |
10977 |
++ |
10978 |
++#endif /* __KERNEL__ */ |
10979 |
++#endif /* _VX_CVIRT_CMD_H */ |
10980 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/cvirt_def.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cvirt_def.h |
10981 |
+--- linux-2.6.29.4/include/linux/vserver/cvirt_def.h 1970-01-01 01:00:00.000000000 +0100 |
10982 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cvirt_def.h 2009-02-22 22:54:26.000000000 +0100 |
10983 |
+@@ -0,0 +1,80 @@ |
10984 |
++#ifndef _VX_CVIRT_DEF_H |
10985 |
++#define _VX_CVIRT_DEF_H |
10986 |
++ |
10987 |
++#include <linux/jiffies.h> |
10988 |
++#include <linux/spinlock.h> |
10989 |
++#include <linux/wait.h> |
10990 |
++#include <linux/time.h> |
10991 |
++#include <asm/atomic.h> |
10992 |
++ |
10993 |
++ |
10994 |
++struct _vx_usage_stat { |
10995 |
++ uint64_t user; |
10996 |
++ uint64_t nice; |
10997 |
++ uint64_t system; |
10998 |
++ uint64_t softirq; |
10999 |
++ uint64_t irq; |
11000 |
++ uint64_t idle; |
11001 |
++ uint64_t iowait; |
11002 |
++}; |
11003 |
++ |
11004 |
++struct _vx_syslog { |
11005 |
++ wait_queue_head_t log_wait; |
11006 |
++ spinlock_t logbuf_lock; /* lock for the log buffer */ |
11007 |
++ |
11008 |
++ unsigned long log_start; /* next char to be read by syslog() */ |
11009 |
++ unsigned long con_start; /* next char to be sent to consoles */ |
11010 |
++ unsigned long log_end; /* most-recently-written-char + 1 */ |
11011 |
++ unsigned long logged_chars; /* #chars since last read+clear operation */ |
11012 |
++ |
11013 |
++ char log_buf[1024]; |
11014 |
++}; |
11015 |
++ |
11016 |
++ |
11017 |
++/* context sub struct */ |
11018 |
++ |
11019 |
++struct _vx_cvirt { |
11020 |
++ atomic_t nr_threads; /* number of current threads */ |
11021 |
++ atomic_t nr_running; /* number of running threads */ |
11022 |
++ atomic_t nr_uninterruptible; /* number of uninterruptible threads */ |
11023 |
++ |
11024 |
++ atomic_t nr_onhold; /* processes on hold */ |
11025 |
++ uint32_t onhold_last; /* jiffies when put on hold */ |
11026 |
++ |
11027 |
++ struct timeval bias_tv; /* time offset to the host */ |
11028 |
++ struct timespec bias_idle; |
11029 |
++ struct timespec bias_uptime; /* context creation point */ |
11030 |
++ uint64_t bias_clock; /* offset in clock_t */ |
11031 |
++ |
11032 |
++ spinlock_t load_lock; /* lock for the load averages */ |
11033 |
++ atomic_t load_updates; /* nr of load updates done so far */ |
11034 |
++ uint32_t load_last; /* last time load was calculated */ |
11035 |
++ uint32_t load[3]; /* load averages 1,5,15 */ |
11036 |
++ |
11037 |
++ atomic_t total_forks; /* number of forks so far */ |
11038 |
++ |
11039 |
++ struct _vx_syslog syslog; |
11040 |
++}; |
11041 |
++ |
11042 |
++struct _vx_cvirt_pc { |
11043 |
++ struct _vx_usage_stat cpustat; |
11044 |
++}; |
11045 |
++ |
11046 |
++ |
11047 |
++#ifdef CONFIG_VSERVER_DEBUG |
11048 |
++ |
11049 |
++static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt) |
11050 |
++{ |
11051 |
++ printk("\t_vx_cvirt:\n"); |
11052 |
++ printk("\t threads: %4d, %4d, %4d, %4d\n", |
11053 |
++ atomic_read(&cvirt->nr_threads), |
11054 |
++ atomic_read(&cvirt->nr_running), |
11055 |
++ atomic_read(&cvirt->nr_uninterruptible), |
11056 |
++ atomic_read(&cvirt->nr_onhold)); |
11057 |
++ /* add rest here */ |
11058 |
++ printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks)); |
11059 |
++} |
11060 |
++ |
11061 |
++#endif |
11062 |
++ |
11063 |
++#endif /* _VX_CVIRT_DEF_H */ |
11064 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/cvirt.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cvirt.h |
11065 |
+--- linux-2.6.29.4/include/linux/vserver/cvirt.h 1970-01-01 01:00:00.000000000 +0100 |
11066 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/cvirt.h 2009-02-22 22:54:26.000000000 +0100 |
11067 |
+@@ -0,0 +1,20 @@ |
11068 |
++#ifndef _VX_CVIRT_H |
11069 |
++#define _VX_CVIRT_H |
11070 |
++ |
11071 |
++ |
11072 |
++#ifdef __KERNEL__ |
11073 |
++ |
11074 |
++struct timespec; |
11075 |
++ |
11076 |
++void vx_vsi_uptime(struct timespec *, struct timespec *); |
11077 |
++ |
11078 |
++ |
11079 |
++struct vx_info; |
11080 |
++ |
11081 |
++void vx_update_load(struct vx_info *); |
11082 |
++ |
11083 |
++ |
11084 |
++int vx_do_syslog(int, char __user *, int); |
11085 |
++ |
11086 |
++#endif /* __KERNEL__ */ |
11087 |
++#endif /* _VX_CVIRT_H */ |
11088 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/debug_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/debug_cmd.h |
11089 |
+--- linux-2.6.29.4/include/linux/vserver/debug_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
11090 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/debug_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
11091 |
+@@ -0,0 +1,58 @@ |
11092 |
++#ifndef _VX_DEBUG_CMD_H |
11093 |
++#define _VX_DEBUG_CMD_H |
11094 |
++ |
11095 |
++ |
11096 |
++/* debug commands */ |
11097 |
++ |
11098 |
++#define VCMD_dump_history VC_CMD(DEBUG, 1, 0) |
11099 |
++ |
11100 |
++#define VCMD_read_history VC_CMD(DEBUG, 5, 0) |
11101 |
++#define VCMD_read_monitor VC_CMD(DEBUG, 6, 0) |
11102 |
++ |
11103 |
++struct vcmd_read_history_v0 { |
11104 |
++ uint32_t index; |
11105 |
++ uint32_t count; |
11106 |
++ char __user *data; |
11107 |
++}; |
11108 |
++ |
11109 |
++struct vcmd_read_monitor_v0 { |
11110 |
++ uint32_t index; |
11111 |
++ uint32_t count; |
11112 |
++ char __user *data; |
11113 |
++}; |
11114 |
++ |
11115 |
++ |
11116 |
++#ifdef __KERNEL__ |
11117 |
++ |
11118 |
++#ifdef CONFIG_COMPAT |
11119 |
++ |
11120 |
++#include <asm/compat.h> |
11121 |
++ |
11122 |
++struct vcmd_read_history_v0_x32 { |
11123 |
++ uint32_t index; |
11124 |
++ uint32_t count; |
11125 |
++ compat_uptr_t data_ptr; |
11126 |
++}; |
11127 |
++ |
11128 |
++struct vcmd_read_monitor_v0_x32 { |
11129 |
++ uint32_t index; |
11130 |
++ uint32_t count; |
11131 |
++ compat_uptr_t data_ptr; |
11132 |
++}; |
11133 |
++ |
11134 |
++#endif /* CONFIG_COMPAT */ |
11135 |
++ |
11136 |
++extern int vc_dump_history(uint32_t); |
11137 |
++ |
11138 |
++extern int vc_read_history(uint32_t, void __user *); |
11139 |
++extern int vc_read_monitor(uint32_t, void __user *); |
11140 |
++ |
11141 |
++#ifdef CONFIG_COMPAT |
11142 |
++ |
11143 |
++extern int vc_read_history_x32(uint32_t, void __user *); |
11144 |
++extern int vc_read_monitor_x32(uint32_t, void __user *); |
11145 |
++ |
11146 |
++#endif /* CONFIG_COMPAT */ |
11147 |
++ |
11148 |
++#endif /* __KERNEL__ */ |
11149 |
++#endif /* _VX_DEBUG_CMD_H */ |
11150 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/debug.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/debug.h |
11151 |
+--- linux-2.6.29.4/include/linux/vserver/debug.h 1970-01-01 01:00:00.000000000 +0100 |
11152 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/debug.h 2009-02-22 22:54:26.000000000 +0100 |
11153 |
+@@ -0,0 +1,127 @@ |
11154 |
++#ifndef _VX_DEBUG_H |
11155 |
++#define _VX_DEBUG_H |
11156 |
++ |
11157 |
++ |
11158 |
++#define VXD_CBIT(n, m) (vx_debug_ ## n & (1 << (m))) |
11159 |
++#define VXD_CMIN(n, m) (vx_debug_ ## n > (m)) |
11160 |
++#define VXD_MASK(n, m) (vx_debug_ ## n & (m)) |
11161 |
++ |
11162 |
++#define VXD_DEV(d) (d), (d)->bd_inode->i_ino, \ |
11163 |
++ imajor((d)->bd_inode), iminor((d)->bd_inode) |
11164 |
++#define VXF_DEV "%p[%lu,%d:%d]" |
11165 |
++ |
11166 |
++ |
11167 |
++#define vxd_path(p) \ |
11168 |
++ ({ static char _buffer[PATH_MAX]; \ |
11169 |
++ d_path(p, _buffer, sizeof(_buffer)); }) |
11170 |
++ |
11171 |
++#define vxd_cond_path(n) \ |
11172 |
++ ((n) ? vxd_path(&(n)->path) : "<null>" ) |
11173 |
++ |
11174 |
++ |
11175 |
++#ifdef CONFIG_VSERVER_DEBUG |
11176 |
++ |
11177 |
++extern unsigned int vx_debug_switch; |
11178 |
++extern unsigned int vx_debug_xid; |
11179 |
++extern unsigned int vx_debug_nid; |
11180 |
++extern unsigned int vx_debug_tag; |
11181 |
++extern unsigned int vx_debug_net; |
11182 |
++extern unsigned int vx_debug_limit; |
11183 |
++extern unsigned int vx_debug_cres; |
11184 |
++extern unsigned int vx_debug_dlim; |
11185 |
++extern unsigned int vx_debug_quota; |
11186 |
++extern unsigned int vx_debug_cvirt; |
11187 |
++extern unsigned int vx_debug_space; |
11188 |
++extern unsigned int vx_debug_misc; |
11189 |
++ |
11190 |
++ |
11191 |
++#define VX_LOGLEVEL "vxD: " |
11192 |
++#define VX_PROC_FMT "%p: " |
11193 |
++#define VX_PROCESS current |
11194 |
++ |
11195 |
++#define vxdprintk(c, f, x...) \ |
11196 |
++ do { \ |
11197 |
++ if (c) \ |
11198 |
++ printk(VX_LOGLEVEL VX_PROC_FMT f "\n", \ |
11199 |
++ VX_PROCESS , ##x); \ |
11200 |
++ } while (0) |
11201 |
++ |
11202 |
++#define vxlprintk(c, f, x...) \ |
11203 |
++ do { \ |
11204 |
++ if (c) \ |
11205 |
++ printk(VX_LOGLEVEL f " @%s:%d\n", x); \ |
11206 |
++ } while (0) |
11207 |
++ |
11208 |
++#define vxfprintk(c, f, x...) \ |
11209 |
++ do { \ |
11210 |
++ if (c) \ |
11211 |
++ printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \ |
11212 |
++ } while (0) |
11213 |
++ |
11214 |
++ |
11215 |
++struct vx_info; |
11216 |
++ |
11217 |
++void dump_vx_info(struct vx_info *, int); |
11218 |
++void dump_vx_info_inactive(int); |
11219 |
++ |
11220 |
++#else /* CONFIG_VSERVER_DEBUG */ |
11221 |
++ |
11222 |
++#define vx_debug_switch 0 |
11223 |
++#define vx_debug_xid 0 |
11224 |
++#define vx_debug_nid 0 |
11225 |
++#define vx_debug_tag 0 |
11226 |
++#define vx_debug_net 0 |
11227 |
++#define vx_debug_limit 0 |
11228 |
++#define vx_debug_cres 0 |
11229 |
++#define vx_debug_dlim 0 |
11230 |
++#define vx_debug_cvirt 0 |
11231 |
++ |
11232 |
++#define vxdprintk(x...) do { } while (0) |
11233 |
++#define vxlprintk(x...) do { } while (0) |
11234 |
++#define vxfprintk(x...) do { } while (0) |
11235 |
++ |
11236 |
++#endif /* CONFIG_VSERVER_DEBUG */ |
11237 |
++ |
11238 |
++ |
11239 |
++#ifdef CONFIG_VSERVER_WARN |
11240 |
++ |
11241 |
++#define VX_WARNLEVEL KERN_WARNING "vxW: " |
11242 |
++#define VX_WARN_TASK "[»%s«,%u:#%u|%u|%u] " |
11243 |
++#define VX_WARN_XID "[xid #%u] " |
11244 |
++#define VX_WARN_NID "[nid #%u] " |
11245 |
++#define VX_WARN_TAG "[tag #%u] " |
11246 |
++ |
11247 |
++#define vxwprintk(c, f, x...) \ |
11248 |
++ do { \ |
11249 |
++ if (c) \ |
11250 |
++ printk(VX_WARNLEVEL f "\n", ##x); \ |
11251 |
++ } while (0) |
11252 |
++ |
11253 |
++#else /* CONFIG_VSERVER_WARN */ |
11254 |
++ |
11255 |
++#define vxwprintk(x...) do { } while (0) |
11256 |
++ |
11257 |
++#endif /* CONFIG_VSERVER_WARN */ |
11258 |
++ |
11259 |
++#define vxwprintk_task(c, f, x...) \ |
11260 |
++ vxwprintk(c, VX_WARN_TASK f, \ |
11261 |
++ current->comm, current->pid, \ |
11262 |
++ current->xid, current->nid, current->tag, ##x) |
11263 |
++#define vxwprintk_xid(c, f, x...) \ |
11264 |
++ vxwprintk(c, VX_WARN_XID f, current->xid, x) |
11265 |
++#define vxwprintk_nid(c, f, x...) \ |
11266 |
++ vxwprintk(c, VX_WARN_NID f, current->nid, x) |
11267 |
++#define vxwprintk_tag(c, f, x...) \ |
11268 |
++ vxwprintk(c, VX_WARN_TAG f, current->tag, x) |
11269 |
++ |
11270 |
++#ifdef CONFIG_VSERVER_DEBUG |
11271 |
++#define vxd_assert_lock(l) assert_spin_locked(l) |
11272 |
++#define vxd_assert(c, f, x...) vxlprintk(!(c), \ |
11273 |
++ "assertion [" f "] failed.", ##x, __FILE__, __LINE__) |
11274 |
++#else |
11275 |
++#define vxd_assert_lock(l) do { } while (0) |
11276 |
++#define vxd_assert(c, f, x...) do { } while (0) |
11277 |
++#endif |
11278 |
++ |
11279 |
++ |
11280 |
++#endif /* _VX_DEBUG_H */ |
11281 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/device_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/device_cmd.h |
11282 |
+--- linux-2.6.29.4/include/linux/vserver/device_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
11283 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/device_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
11284 |
+@@ -0,0 +1,44 @@ |
11285 |
++#ifndef _VX_DEVICE_CMD_H |
11286 |
++#define _VX_DEVICE_CMD_H |
11287 |
++ |
11288 |
++ |
11289 |
++/* device vserver commands */ |
11290 |
++ |
11291 |
++#define VCMD_set_mapping VC_CMD(DEVICE, 1, 0) |
11292 |
++#define VCMD_unset_mapping VC_CMD(DEVICE, 2, 0) |
11293 |
++ |
11294 |
++struct vcmd_set_mapping_v0 { |
11295 |
++ const char __user *device; |
11296 |
++ const char __user *target; |
11297 |
++ uint32_t flags; |
11298 |
++}; |
11299 |
++ |
11300 |
++ |
11301 |
++#ifdef __KERNEL__ |
11302 |
++ |
11303 |
++#ifdef CONFIG_COMPAT |
11304 |
++ |
11305 |
++#include <asm/compat.h> |
11306 |
++ |
11307 |
++struct vcmd_set_mapping_v0_x32 { |
11308 |
++ compat_uptr_t device_ptr; |
11309 |
++ compat_uptr_t target_ptr; |
11310 |
++ uint32_t flags; |
11311 |
++}; |
11312 |
++ |
11313 |
++#endif /* CONFIG_COMPAT */ |
11314 |
++ |
11315 |
++#include <linux/compiler.h> |
11316 |
++ |
11317 |
++extern int vc_set_mapping(struct vx_info *, void __user *); |
11318 |
++extern int vc_unset_mapping(struct vx_info *, void __user *); |
11319 |
++ |
11320 |
++#ifdef CONFIG_COMPAT |
11321 |
++ |
11322 |
++extern int vc_set_mapping_x32(struct vx_info *, void __user *); |
11323 |
++extern int vc_unset_mapping_x32(struct vx_info *, void __user *); |
11324 |
++ |
11325 |
++#endif /* CONFIG_COMPAT */ |
11326 |
++ |
11327 |
++#endif /* __KERNEL__ */ |
11328 |
++#endif /* _VX_DEVICE_CMD_H */ |
11329 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/device_def.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/device_def.h |
11330 |
+--- linux-2.6.29.4/include/linux/vserver/device_def.h 1970-01-01 01:00:00.000000000 +0100 |
11331 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/device_def.h 2009-02-22 22:54:26.000000000 +0100 |
11332 |
+@@ -0,0 +1,17 @@ |
11333 |
++#ifndef _VX_DEVICE_DEF_H |
11334 |
++#define _VX_DEVICE_DEF_H |
11335 |
++ |
11336 |
++#include <linux/types.h> |
11337 |
++ |
11338 |
++struct vx_dmap_target { |
11339 |
++ dev_t target; |
11340 |
++ uint32_t flags; |
11341 |
++}; |
11342 |
++ |
11343 |
++struct _vx_device { |
11344 |
++#ifdef CONFIG_VSERVER_DEVICE |
11345 |
++ struct vx_dmap_target targets[2]; |
11346 |
++#endif |
11347 |
++}; |
11348 |
++ |
11349 |
++#endif /* _VX_DEVICE_DEF_H */ |
11350 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/device.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/device.h |
11351 |
+--- linux-2.6.29.4/include/linux/vserver/device.h 1970-01-01 01:00:00.000000000 +0100 |
11352 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/device.h 2009-02-22 22:54:26.000000000 +0100 |
11353 |
+@@ -0,0 +1,15 @@ |
11354 |
++#ifndef _VX_DEVICE_H |
11355 |
++#define _VX_DEVICE_H |
11356 |
++ |
11357 |
++ |
11358 |
++#define DATTR_CREATE 0x00000001 |
11359 |
++#define DATTR_OPEN 0x00000002 |
11360 |
++ |
11361 |
++#define DATTR_REMAP 0x00000010 |
11362 |
++ |
11363 |
++#define DATTR_MASK 0x00000013 |
11364 |
++ |
11365 |
++ |
11366 |
++#else /* _VX_DEVICE_H */ |
11367 |
++#warning duplicate inclusion |
11368 |
++#endif /* _VX_DEVICE_H */ |
11369 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/dlimit_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/dlimit_cmd.h |
11370 |
+--- linux-2.6.29.4/include/linux/vserver/dlimit_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
11371 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/dlimit_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
11372 |
+@@ -0,0 +1,74 @@ |
11373 |
++#ifndef _VX_DLIMIT_CMD_H |
11374 |
++#define _VX_DLIMIT_CMD_H |
11375 |
++ |
11376 |
++ |
11377 |
++/* dlimit vserver commands */ |
11378 |
++ |
11379 |
++#define VCMD_add_dlimit VC_CMD(DLIMIT, 1, 0) |
11380 |
++#define VCMD_rem_dlimit VC_CMD(DLIMIT, 2, 0) |
11381 |
++ |
11382 |
++#define VCMD_set_dlimit VC_CMD(DLIMIT, 5, 0) |
11383 |
++#define VCMD_get_dlimit VC_CMD(DLIMIT, 6, 0) |
11384 |
++ |
11385 |
++struct vcmd_ctx_dlimit_base_v0 { |
11386 |
++ const char __user *name; |
11387 |
++ uint32_t flags; |
11388 |
++}; |
11389 |
++ |
11390 |
++struct vcmd_ctx_dlimit_v0 { |
11391 |
++ const char __user *name; |
11392 |
++ uint32_t space_used; /* used space in kbytes */ |
11393 |
++ uint32_t space_total; /* maximum space in kbytes */ |
11394 |
++ uint32_t inodes_used; /* used inodes */ |
11395 |
++ uint32_t inodes_total; /* maximum inodes */ |
11396 |
++ uint32_t reserved; /* reserved for root in % */ |
11397 |
++ uint32_t flags; |
11398 |
++}; |
11399 |
++ |
11400 |
++#define CDLIM_UNSET ((uint32_t)0UL) |
11401 |
++#define CDLIM_INFINITY ((uint32_t)~0UL) |
11402 |
++#define CDLIM_KEEP ((uint32_t)~1UL) |
11403 |
++ |
11404 |
++#ifdef __KERNEL__ |
11405 |
++ |
11406 |
++#ifdef CONFIG_COMPAT |
11407 |
++ |
11408 |
++#include <asm/compat.h> |
11409 |
++ |
11410 |
++struct vcmd_ctx_dlimit_base_v0_x32 { |
11411 |
++ compat_uptr_t name_ptr; |
11412 |
++ uint32_t flags; |
11413 |
++}; |
11414 |
++ |
11415 |
++struct vcmd_ctx_dlimit_v0_x32 { |
11416 |
++ compat_uptr_t name_ptr; |
11417 |
++ uint32_t space_used; /* used space in kbytes */ |
11418 |
++ uint32_t space_total; /* maximum space in kbytes */ |
11419 |
++ uint32_t inodes_used; /* used inodes */ |
11420 |
++ uint32_t inodes_total; /* maximum inodes */ |
11421 |
++ uint32_t reserved; /* reserved for root in % */ |
11422 |
++ uint32_t flags; |
11423 |
++}; |
11424 |
++ |
11425 |
++#endif /* CONFIG_COMPAT */ |
11426 |
++ |
11427 |
++#include <linux/compiler.h> |
11428 |
++ |
11429 |
++extern int vc_add_dlimit(uint32_t, void __user *); |
11430 |
++extern int vc_rem_dlimit(uint32_t, void __user *); |
11431 |
++ |
11432 |
++extern int vc_set_dlimit(uint32_t, void __user *); |
11433 |
++extern int vc_get_dlimit(uint32_t, void __user *); |
11434 |
++ |
11435 |
++#ifdef CONFIG_COMPAT |
11436 |
++ |
11437 |
++extern int vc_add_dlimit_x32(uint32_t, void __user *); |
11438 |
++extern int vc_rem_dlimit_x32(uint32_t, void __user *); |
11439 |
++ |
11440 |
++extern int vc_set_dlimit_x32(uint32_t, void __user *); |
11441 |
++extern int vc_get_dlimit_x32(uint32_t, void __user *); |
11442 |
++ |
11443 |
++#endif /* CONFIG_COMPAT */ |
11444 |
++ |
11445 |
++#endif /* __KERNEL__ */ |
11446 |
++#endif /* _VX_DLIMIT_CMD_H */ |
11447 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/dlimit.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/dlimit.h |
11448 |
+--- linux-2.6.29.4/include/linux/vserver/dlimit.h 1970-01-01 01:00:00.000000000 +0100 |
11449 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/dlimit.h 2009-02-22 22:54:26.000000000 +0100 |
11450 |
+@@ -0,0 +1,54 @@ |
11451 |
++#ifndef _VX_DLIMIT_H |
11452 |
++#define _VX_DLIMIT_H |
11453 |
++ |
11454 |
++#include "switch.h" |
11455 |
++ |
11456 |
++ |
11457 |
++#ifdef __KERNEL__ |
11458 |
++ |
11459 |
++/* keep in sync with CDLIM_INFINITY */ |
11460 |
++ |
11461 |
++#define DLIM_INFINITY (~0ULL) |
11462 |
++ |
11463 |
++#include <linux/spinlock.h> |
11464 |
++#include <linux/rcupdate.h> |
11465 |
++ |
11466 |
++struct super_block; |
11467 |
++ |
11468 |
++struct dl_info { |
11469 |
++ struct hlist_node dl_hlist; /* linked list of contexts */ |
11470 |
++ struct rcu_head dl_rcu; /* the rcu head */ |
11471 |
++ tag_t dl_tag; /* context tag */ |
11472 |
++ atomic_t dl_usecnt; /* usage count */ |
11473 |
++ atomic_t dl_refcnt; /* reference count */ |
11474 |
++ |
11475 |
++ struct super_block *dl_sb; /* associated superblock */ |
11476 |
++ |
11477 |
++ spinlock_t dl_lock; /* protect the values */ |
11478 |
++ |
11479 |
++ unsigned long long dl_space_used; /* used space in bytes */ |
11480 |
++ unsigned long long dl_space_total; /* maximum space in bytes */ |
11481 |
++ unsigned long dl_inodes_used; /* used inodes */ |
11482 |
++ unsigned long dl_inodes_total; /* maximum inodes */ |
11483 |
++ |
11484 |
++ unsigned int dl_nrlmult; /* non root limit mult */ |
11485 |
++}; |
11486 |
++ |
11487 |
++struct rcu_head; |
11488 |
++ |
11489 |
++extern void rcu_free_dl_info(struct rcu_head *); |
11490 |
++extern void unhash_dl_info(struct dl_info *); |
11491 |
++ |
11492 |
++extern struct dl_info *locate_dl_info(struct super_block *, tag_t); |
11493 |
++ |
11494 |
++ |
11495 |
++struct kstatfs; |
11496 |
++ |
11497 |
++extern void vx_vsi_statfs(struct super_block *, struct kstatfs *); |
11498 |
++ |
11499 |
++typedef uint64_t dlsize_t; |
11500 |
++ |
11501 |
++#endif /* __KERNEL__ */ |
11502 |
++#else /* _VX_DLIMIT_H */ |
11503 |
++#warning duplicate inclusion |
11504 |
++#endif /* _VX_DLIMIT_H */ |
11505 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/global.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/global.h |
11506 |
+--- linux-2.6.29.4/include/linux/vserver/global.h 1970-01-01 01:00:00.000000000 +0100 |
11507 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/global.h 2009-02-22 22:54:26.000000000 +0100 |
11508 |
+@@ -0,0 +1,20 @@ |
11509 |
++#ifndef _VX_GLOBAL_H |
11510 |
++#define _VX_GLOBAL_H |
11511 |
++ |
11512 |
++ |
11513 |
++extern atomic_t vx_global_ctotal; |
11514 |
++extern atomic_t vx_global_cactive; |
11515 |
++ |
11516 |
++extern atomic_t nx_global_ctotal; |
11517 |
++extern atomic_t nx_global_cactive; |
11518 |
++ |
11519 |
++extern atomic_t vs_global_nsproxy; |
11520 |
++extern atomic_t vs_global_fs; |
11521 |
++extern atomic_t vs_global_mnt_ns; |
11522 |
++extern atomic_t vs_global_uts_ns; |
11523 |
++extern atomic_t vs_global_ipc_ns; |
11524 |
++extern atomic_t vs_global_user_ns; |
11525 |
++extern atomic_t vs_global_pid_ns; |
11526 |
++ |
11527 |
++ |
11528 |
++#endif /* _VX_GLOBAL_H */ |
11529 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/history.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/history.h |
11530 |
+--- linux-2.6.29.4/include/linux/vserver/history.h 1970-01-01 01:00:00.000000000 +0100 |
11531 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/history.h 2009-02-22 22:54:26.000000000 +0100 |
11532 |
+@@ -0,0 +1,197 @@ |
11533 |
++#ifndef _VX_HISTORY_H |
11534 |
++#define _VX_HISTORY_H |
11535 |
++ |
11536 |
++ |
11537 |
++enum { |
11538 |
++ VXH_UNUSED = 0, |
11539 |
++ VXH_THROW_OOPS = 1, |
11540 |
++ |
11541 |
++ VXH_GET_VX_INFO, |
11542 |
++ VXH_PUT_VX_INFO, |
11543 |
++ VXH_INIT_VX_INFO, |
11544 |
++ VXH_SET_VX_INFO, |
11545 |
++ VXH_CLR_VX_INFO, |
11546 |
++ VXH_CLAIM_VX_INFO, |
11547 |
++ VXH_RELEASE_VX_INFO, |
11548 |
++ VXH_ALLOC_VX_INFO, |
11549 |
++ VXH_DEALLOC_VX_INFO, |
11550 |
++ VXH_HASH_VX_INFO, |
11551 |
++ VXH_UNHASH_VX_INFO, |
11552 |
++ VXH_LOC_VX_INFO, |
11553 |
++ VXH_LOOKUP_VX_INFO, |
11554 |
++ VXH_CREATE_VX_INFO, |
11555 |
++}; |
11556 |
++ |
11557 |
++struct _vxhe_vxi { |
11558 |
++ struct vx_info *ptr; |
11559 |
++ unsigned xid; |
11560 |
++ unsigned usecnt; |
11561 |
++ unsigned tasks; |
11562 |
++}; |
11563 |
++ |
11564 |
++struct _vxhe_set_clr { |
11565 |
++ void *data; |
11566 |
++}; |
11567 |
++ |
11568 |
++struct _vxhe_loc_lookup { |
11569 |
++ unsigned arg; |
11570 |
++}; |
11571 |
++ |
11572 |
++struct _vx_hist_entry { |
11573 |
++ void *loc; |
11574 |
++ unsigned short seq; |
11575 |
++ unsigned short type; |
11576 |
++ struct _vxhe_vxi vxi; |
11577 |
++ union { |
11578 |
++ struct _vxhe_set_clr sc; |
11579 |
++ struct _vxhe_loc_lookup ll; |
11580 |
++ }; |
11581 |
++}; |
11582 |
++ |
11583 |
++#ifdef CONFIG_VSERVER_HISTORY |
11584 |
++ |
11585 |
++extern unsigned volatile int vxh_active; |
11586 |
++ |
11587 |
++struct _vx_hist_entry *vxh_advance(void *loc); |
11588 |
++ |
11589 |
++ |
11590 |
++static inline |
11591 |
++void __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi) |
11592 |
++{ |
11593 |
++ entry->vxi.ptr = vxi; |
11594 |
++ if (vxi) { |
11595 |
++ entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt); |
11596 |
++ entry->vxi.tasks = atomic_read(&vxi->vx_tasks); |
11597 |
++ entry->vxi.xid = vxi->vx_id; |
11598 |
++ } |
11599 |
++} |
11600 |
++ |
11601 |
++ |
11602 |
++#define __HERE__ current_text_addr() |
11603 |
++ |
11604 |
++#define __VXH_BODY(__type, __data, __here) \ |
11605 |
++ struct _vx_hist_entry *entry; \ |
11606 |
++ \ |
11607 |
++ preempt_disable(); \ |
11608 |
++ entry = vxh_advance(__here); \ |
11609 |
++ __data; \ |
11610 |
++ entry->type = __type; \ |
11611 |
++ preempt_enable(); |
11612 |
++ |
11613 |
++ |
11614 |
++ /* pass vxi only */ |
11615 |
++ |
11616 |
++#define __VXH_SMPL \ |
11617 |
++ __vxh_copy_vxi(entry, vxi) |
11618 |
++ |
11619 |
++static inline |
11620 |
++void __vxh_smpl(struct vx_info *vxi, int __type, void *__here) |
11621 |
++{ |
11622 |
++ __VXH_BODY(__type, __VXH_SMPL, __here) |
11623 |
++} |
11624 |
++ |
11625 |
++ /* pass vxi and data (void *) */ |
11626 |
++ |
11627 |
++#define __VXH_DATA \ |
11628 |
++ __vxh_copy_vxi(entry, vxi); \ |
11629 |
++ entry->sc.data = data |
11630 |
++ |
11631 |
++static inline |
11632 |
++void __vxh_data(struct vx_info *vxi, void *data, |
11633 |
++ int __type, void *__here) |
11634 |
++{ |
11635 |
++ __VXH_BODY(__type, __VXH_DATA, __here) |
11636 |
++} |
11637 |
++ |
11638 |
++ /* pass vxi and arg (long) */ |
11639 |
++ |
11640 |
++#define __VXH_LONG \ |
11641 |
++ __vxh_copy_vxi(entry, vxi); \ |
11642 |
++ entry->ll.arg = arg |
11643 |
++ |
11644 |
++static inline |
11645 |
++void __vxh_long(struct vx_info *vxi, long arg, |
11646 |
++ int __type, void *__here) |
11647 |
++{ |
11648 |
++ __VXH_BODY(__type, __VXH_LONG, __here) |
11649 |
++} |
11650 |
++ |
11651 |
++ |
11652 |
++static inline |
11653 |
++void __vxh_throw_oops(void *__here) |
11654 |
++{ |
11655 |
++ __VXH_BODY(VXH_THROW_OOPS, {}, __here); |
11656 |
++ /* prevent further acquisition */ |
11657 |
++ vxh_active = 0; |
11658 |
++} |
11659 |
++ |
11660 |
++ |
11661 |
++#define vxh_throw_oops() __vxh_throw_oops(__HERE__); |
11662 |
++ |
11663 |
++#define __vxh_get_vx_info(v, h) __vxh_smpl(v, VXH_GET_VX_INFO, h); |
11664 |
++#define __vxh_put_vx_info(v, h) __vxh_smpl(v, VXH_PUT_VX_INFO, h); |
11665 |
++ |
11666 |
++#define __vxh_init_vx_info(v, d, h) \ |
11667 |
++ __vxh_data(v, d, VXH_INIT_VX_INFO, h); |
11668 |
++#define __vxh_set_vx_info(v, d, h) \ |
11669 |
++ __vxh_data(v, d, VXH_SET_VX_INFO, h); |
11670 |
++#define __vxh_clr_vx_info(v, d, h) \ |
11671 |
++ __vxh_data(v, d, VXH_CLR_VX_INFO, h); |
11672 |
++ |
11673 |
++#define __vxh_claim_vx_info(v, d, h) \ |
11674 |
++ __vxh_data(v, d, VXH_CLAIM_VX_INFO, h); |
11675 |
++#define __vxh_release_vx_info(v, d, h) \ |
11676 |
++ __vxh_data(v, d, VXH_RELEASE_VX_INFO, h); |
11677 |
++ |
11678 |
++#define vxh_alloc_vx_info(v) \ |
11679 |
++ __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__); |
11680 |
++#define vxh_dealloc_vx_info(v) \ |
11681 |
++ __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__); |
11682 |
++ |
11683 |
++#define vxh_hash_vx_info(v) \ |
11684 |
++ __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__); |
11685 |
++#define vxh_unhash_vx_info(v) \ |
11686 |
++ __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__); |
11687 |
++ |
11688 |
++#define vxh_loc_vx_info(v, l) \ |
11689 |
++ __vxh_long(v, l, VXH_LOC_VX_INFO, __HERE__); |
11690 |
++#define vxh_lookup_vx_info(v, l) \ |
11691 |
++ __vxh_long(v, l, VXH_LOOKUP_VX_INFO, __HERE__); |
11692 |
++#define vxh_create_vx_info(v, l) \ |
11693 |
++ __vxh_long(v, l, VXH_CREATE_VX_INFO, __HERE__); |
11694 |
++ |
11695 |
++extern void vxh_dump_history(void); |
11696 |
++ |
11697 |
++ |
11698 |
++#else /* CONFIG_VSERVER_HISTORY */ |
11699 |
++ |
11700 |
++#define __HERE__ 0 |
11701 |
++ |
11702 |
++#define vxh_throw_oops() do { } while (0) |
11703 |
++ |
11704 |
++#define __vxh_get_vx_info(v, h) do { } while (0) |
11705 |
++#define __vxh_put_vx_info(v, h) do { } while (0) |
11706 |
++ |
11707 |
++#define __vxh_init_vx_info(v, d, h) do { } while (0) |
11708 |
++#define __vxh_set_vx_info(v, d, h) do { } while (0) |
11709 |
++#define __vxh_clr_vx_info(v, d, h) do { } while (0) |
11710 |
++ |
11711 |
++#define __vxh_claim_vx_info(v, d, h) do { } while (0) |
11712 |
++#define __vxh_release_vx_info(v, d, h) do { } while (0) |
11713 |
++ |
11714 |
++#define vxh_alloc_vx_info(v) do { } while (0) |
11715 |
++#define vxh_dealloc_vx_info(v) do { } while (0) |
11716 |
++ |
11717 |
++#define vxh_hash_vx_info(v) do { } while (0) |
11718 |
++#define vxh_unhash_vx_info(v) do { } while (0) |
11719 |
++ |
11720 |
++#define vxh_loc_vx_info(v, l) do { } while (0) |
11721 |
++#define vxh_lookup_vx_info(v, l) do { } while (0) |
11722 |
++#define vxh_create_vx_info(v, l) do { } while (0) |
11723 |
++ |
11724 |
++#define vxh_dump_history() do { } while (0) |
11725 |
++ |
11726 |
++ |
11727 |
++#endif /* CONFIG_VSERVER_HISTORY */ |
11728 |
++ |
11729 |
++#endif /* _VX_HISTORY_H */ |
11730 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/inode_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/inode_cmd.h |
11731 |
+--- linux-2.6.29.4/include/linux/vserver/inode_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
11732 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/inode_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
11733 |
+@@ -0,0 +1,59 @@ |
11734 |
++#ifndef _VX_INODE_CMD_H |
11735 |
++#define _VX_INODE_CMD_H |
11736 |
++ |
11737 |
++ |
11738 |
++/* inode vserver commands */ |
11739 |
++ |
11740 |
++#define VCMD_get_iattr VC_CMD(INODE, 1, 1) |
11741 |
++#define VCMD_set_iattr VC_CMD(INODE, 2, 1) |
11742 |
++ |
11743 |
++#define VCMD_fget_iattr VC_CMD(INODE, 3, 0) |
11744 |
++#define VCMD_fset_iattr VC_CMD(INODE, 4, 0) |
11745 |
++ |
11746 |
++struct vcmd_ctx_iattr_v1 { |
11747 |
++ const char __user *name; |
11748 |
++ uint32_t tag; |
11749 |
++ uint32_t flags; |
11750 |
++ uint32_t mask; |
11751 |
++}; |
11752 |
++ |
11753 |
++struct vcmd_ctx_fiattr_v0 { |
11754 |
++ uint32_t tag; |
11755 |
++ uint32_t flags; |
11756 |
++ uint32_t mask; |
11757 |
++}; |
11758 |
++ |
11759 |
++ |
11760 |
++#ifdef __KERNEL__ |
11761 |
++ |
11762 |
++ |
11763 |
++#ifdef CONFIG_COMPAT |
11764 |
++ |
11765 |
++#include <asm/compat.h> |
11766 |
++ |
11767 |
++struct vcmd_ctx_iattr_v1_x32 { |
11768 |
++ compat_uptr_t name_ptr; |
11769 |
++ uint32_t tag; |
11770 |
++ uint32_t flags; |
11771 |
++ uint32_t mask; |
11772 |
++}; |
11773 |
++ |
11774 |
++#endif /* CONFIG_COMPAT */ |
11775 |
++ |
11776 |
++#include <linux/compiler.h> |
11777 |
++ |
11778 |
++extern int vc_get_iattr(void __user *); |
11779 |
++extern int vc_set_iattr(void __user *); |
11780 |
++ |
11781 |
++extern int vc_fget_iattr(uint32_t, void __user *); |
11782 |
++extern int vc_fset_iattr(uint32_t, void __user *); |
11783 |
++ |
11784 |
++#ifdef CONFIG_COMPAT |
11785 |
++ |
11786 |
++extern int vc_get_iattr_x32(void __user *); |
11787 |
++extern int vc_set_iattr_x32(void __user *); |
11788 |
++ |
11789 |
++#endif /* CONFIG_COMPAT */ |
11790 |
++ |
11791 |
++#endif /* __KERNEL__ */ |
11792 |
++#endif /* _VX_INODE_CMD_H */ |
11793 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/inode.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/inode.h |
11794 |
+--- linux-2.6.29.4/include/linux/vserver/inode.h 1970-01-01 01:00:00.000000000 +0100 |
11795 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/inode.h 2009-02-22 22:54:26.000000000 +0100 |
11796 |
+@@ -0,0 +1,38 @@ |
11797 |
++#ifndef _VX_INODE_H |
11798 |
++#define _VX_INODE_H |
11799 |
++ |
11800 |
++ |
11801 |
++#define IATTR_TAG 0x01000000 |
11802 |
++ |
11803 |
++#define IATTR_ADMIN 0x00000001 |
11804 |
++#define IATTR_WATCH 0x00000002 |
11805 |
++#define IATTR_HIDE 0x00000004 |
11806 |
++#define IATTR_FLAGS 0x00000007 |
11807 |
++ |
11808 |
++#define IATTR_BARRIER 0x00010000 |
11809 |
++#define IATTR_IXUNLINK 0x00020000 |
11810 |
++#define IATTR_IMMUTABLE 0x00040000 |
11811 |
++ |
11812 |
++#ifdef __KERNEL__ |
11813 |
++ |
11814 |
++ |
11815 |
++#ifdef CONFIG_VSERVER_PROC_SECURE |
11816 |
++#define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE ) |
11817 |
++#define IATTR_PROC_SYMLINK ( IATTR_ADMIN ) |
11818 |
++#else |
11819 |
++#define IATTR_PROC_DEFAULT ( IATTR_ADMIN ) |
11820 |
++#define IATTR_PROC_SYMLINK ( IATTR_ADMIN ) |
11821 |
++#endif |
11822 |
++ |
11823 |
++#define vx_hide_check(c, m) (((m) & IATTR_HIDE) ? vx_check(c, m) : 1) |
11824 |
++ |
11825 |
++#endif /* __KERNEL__ */ |
11826 |
++ |
11827 |
++/* inode ioctls */ |
11828 |
++ |
11829 |
++#define FIOC_GETXFLG _IOR('x', 5, long) |
11830 |
++#define FIOC_SETXFLG _IOW('x', 6, long) |
11831 |
++ |
11832 |
++#else /* _VX_INODE_H */ |
11833 |
++#warning duplicate inclusion |
11834 |
++#endif /* _VX_INODE_H */ |
11835 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/Kbuild linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/Kbuild |
11836 |
+--- linux-2.6.29.4/include/linux/vserver/Kbuild 1970-01-01 01:00:00.000000000 +0100 |
11837 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/Kbuild 2009-02-22 22:54:26.000000000 +0100 |
11838 |
+@@ -0,0 +1,8 @@ |
11839 |
++ |
11840 |
++unifdef-y += context_cmd.h network_cmd.h space_cmd.h \ |
11841 |
++ cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \ |
11842 |
++ inode_cmd.h tag_cmd.h sched_cmd.h signal_cmd.h \ |
11843 |
++ debug_cmd.h device_cmd.h |
11844 |
++ |
11845 |
++unifdef-y += switch.h network.h monitor.h inode.h device.h |
11846 |
++ |
11847 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/limit_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/limit_cmd.h |
11848 |
+--- linux-2.6.29.4/include/linux/vserver/limit_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
11849 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/limit_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
11850 |
+@@ -0,0 +1,69 @@ |
11851 |
++#ifndef _VX_LIMIT_CMD_H |
11852 |
++#define _VX_LIMIT_CMD_H |
11853 |
++ |
11854 |
++ |
11855 |
++/* rlimit vserver commands */ |
11856 |
++ |
11857 |
++#define VCMD_get_rlimit VC_CMD(RLIMIT, 1, 0) |
11858 |
++#define VCMD_set_rlimit VC_CMD(RLIMIT, 2, 0) |
11859 |
++#define VCMD_get_rlimit_mask VC_CMD(RLIMIT, 3, 0) |
11860 |
++#define VCMD_reset_minmax VC_CMD(RLIMIT, 9, 0) |
11861 |
++ |
11862 |
++struct vcmd_ctx_rlimit_v0 { |
11863 |
++ uint32_t id; |
11864 |
++ uint64_t minimum; |
11865 |
++ uint64_t softlimit; |
11866 |
++ uint64_t maximum; |
11867 |
++}; |
11868 |
++ |
11869 |
++struct vcmd_ctx_rlimit_mask_v0 { |
11870 |
++ uint32_t minimum; |
11871 |
++ uint32_t softlimit; |
11872 |
++ uint32_t maximum; |
11873 |
++}; |
11874 |
++ |
11875 |
++#define VCMD_rlimit_stat VC_CMD(VSTAT, 1, 0) |
11876 |
++ |
11877 |
++struct vcmd_rlimit_stat_v0 { |
11878 |
++ uint32_t id; |
11879 |
++ uint32_t hits; |
11880 |
++ uint64_t value; |
11881 |
++ uint64_t minimum; |
11882 |
++ uint64_t maximum; |
11883 |
++}; |
11884 |
++ |
11885 |
++#define CRLIM_UNSET (0ULL) |
11886 |
++#define CRLIM_INFINITY (~0ULL) |
11887 |
++#define CRLIM_KEEP (~1ULL) |
11888 |
++ |
11889 |
++#ifdef __KERNEL__ |
11890 |
++ |
11891 |
++#ifdef CONFIG_IA32_EMULATION |
11892 |
++ |
11893 |
++struct vcmd_ctx_rlimit_v0_x32 { |
11894 |
++ uint32_t id; |
11895 |
++ uint64_t minimum; |
11896 |
++ uint64_t softlimit; |
11897 |
++ uint64_t maximum; |
11898 |
++} __attribute__ ((packed)); |
11899 |
++ |
11900 |
++#endif /* CONFIG_IA32_EMULATION */ |
11901 |
++ |
11902 |
++#include <linux/compiler.h> |
11903 |
++ |
11904 |
++extern int vc_get_rlimit_mask(uint32_t, void __user *); |
11905 |
++extern int vc_get_rlimit(struct vx_info *, void __user *); |
11906 |
++extern int vc_set_rlimit(struct vx_info *, void __user *); |
11907 |
++extern int vc_reset_minmax(struct vx_info *, void __user *); |
11908 |
++ |
11909 |
++extern int vc_rlimit_stat(struct vx_info *, void __user *); |
11910 |
++ |
11911 |
++#ifdef CONFIG_IA32_EMULATION |
11912 |
++ |
11913 |
++extern int vc_get_rlimit_x32(struct vx_info *, void __user *); |
11914 |
++extern int vc_set_rlimit_x32(struct vx_info *, void __user *); |
11915 |
++ |
11916 |
++#endif /* CONFIG_IA32_EMULATION */ |
11917 |
++ |
11918 |
++#endif /* __KERNEL__ */ |
11919 |
++#endif /* _VX_LIMIT_CMD_H */ |
11920 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/limit_def.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/limit_def.h |
11921 |
+--- linux-2.6.29.4/include/linux/vserver/limit_def.h 1970-01-01 01:00:00.000000000 +0100 |
11922 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/limit_def.h 2009-02-22 22:54:26.000000000 +0100 |
11923 |
+@@ -0,0 +1,47 @@ |
11924 |
++#ifndef _VX_LIMIT_DEF_H |
11925 |
++#define _VX_LIMIT_DEF_H |
11926 |
++ |
11927 |
++#include <asm/atomic.h> |
11928 |
++#include <asm/resource.h> |
11929 |
++ |
11930 |
++#include "limit.h" |
11931 |
++ |
11932 |
++ |
11933 |
++struct _vx_res_limit { |
11934 |
++ rlim_t soft; /* Context soft limit */ |
11935 |
++ rlim_t hard; /* Context hard limit */ |
11936 |
++ |
11937 |
++ rlim_atomic_t rcur; /* Current value */ |
11938 |
++ rlim_t rmin; /* Context minimum */ |
11939 |
++ rlim_t rmax; /* Context maximum */ |
11940 |
++ |
11941 |
++ atomic_t lhit; /* Limit hits */ |
11942 |
++}; |
11943 |
++ |
11944 |
++/* context sub struct */ |
11945 |
++ |
11946 |
++struct _vx_limit { |
11947 |
++ struct _vx_res_limit res[NUM_LIMITS]; |
11948 |
++}; |
11949 |
++ |
11950 |
++#ifdef CONFIG_VSERVER_DEBUG |
11951 |
++ |
11952 |
++static inline void __dump_vx_limit(struct _vx_limit *limit) |
11953 |
++{ |
11954 |
++ int i; |
11955 |
++ |
11956 |
++ printk("\t_vx_limit:"); |
11957 |
++ for (i = 0; i < NUM_LIMITS; i++) { |
11958 |
++ printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n", |
11959 |
++ i, (unsigned long)__rlim_get(limit, i), |
11960 |
++ (unsigned long)__rlim_rmin(limit, i), |
11961 |
++ (unsigned long)__rlim_rmax(limit, i), |
11962 |
++ (long)__rlim_soft(limit, i), |
11963 |
++ (long)__rlim_hard(limit, i), |
11964 |
++ atomic_read(&__rlim_lhit(limit, i))); |
11965 |
++ } |
11966 |
++} |
11967 |
++ |
11968 |
++#endif |
11969 |
++ |
11970 |
++#endif /* _VX_LIMIT_DEF_H */ |
11971 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/limit.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/limit.h |
11972 |
+--- linux-2.6.29.4/include/linux/vserver/limit.h 1970-01-01 01:00:00.000000000 +0100 |
11973 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/limit.h 2009-02-22 22:54:26.000000000 +0100 |
11974 |
+@@ -0,0 +1,70 @@ |
11975 |
++#ifndef _VX_LIMIT_H |
11976 |
++#define _VX_LIMIT_H |
11977 |
++ |
11978 |
++#define VLIMIT_NSOCK 16 |
11979 |
++#define VLIMIT_OPENFD 17 |
11980 |
++#define VLIMIT_ANON 18 |
11981 |
++#define VLIMIT_SHMEM 19 |
11982 |
++#define VLIMIT_SEMARY 20 |
11983 |
++#define VLIMIT_NSEMS 21 |
11984 |
++#define VLIMIT_DENTRY 22 |
11985 |
++#define VLIMIT_MAPPED 23 |
11986 |
++ |
11987 |
++ |
11988 |
++#ifdef __KERNEL__ |
11989 |
++ |
11990 |
++#define VLIM_NOCHECK ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS)) |
11991 |
++ |
11992 |
++/* keep in sync with CRLIM_INFINITY */ |
11993 |
++ |
11994 |
++#define VLIM_INFINITY (~0ULL) |
11995 |
++ |
11996 |
++#include <asm/atomic.h> |
11997 |
++#include <asm/resource.h> |
11998 |
++ |
11999 |
++#ifndef RLIM_INFINITY |
12000 |
++#warning RLIM_INFINITY is undefined |
12001 |
++#endif |
12002 |
++ |
12003 |
++#define __rlim_val(l, r, v) ((l)->res[r].v) |
12004 |
++ |
12005 |
++#define __rlim_soft(l, r) __rlim_val(l, r, soft) |
12006 |
++#define __rlim_hard(l, r) __rlim_val(l, r, hard) |
12007 |
++ |
12008 |
++#define __rlim_rcur(l, r) __rlim_val(l, r, rcur) |
12009 |
++#define __rlim_rmin(l, r) __rlim_val(l, r, rmin) |
12010 |
++#define __rlim_rmax(l, r) __rlim_val(l, r, rmax) |
12011 |
++ |
12012 |
++#define __rlim_lhit(l, r) __rlim_val(l, r, lhit) |
12013 |
++#define __rlim_hit(l, r) atomic_inc(&__rlim_lhit(l, r)) |
12014 |
++ |
12015 |
++typedef atomic_long_t rlim_atomic_t; |
12016 |
++typedef unsigned long rlim_t; |
12017 |
++ |
12018 |
++#define __rlim_get(l, r) atomic_long_read(&__rlim_rcur(l, r)) |
12019 |
++#define __rlim_set(l, r, v) atomic_long_set(&__rlim_rcur(l, r), v) |
12020 |
++#define __rlim_inc(l, r) atomic_long_inc(&__rlim_rcur(l, r)) |
12021 |
++#define __rlim_dec(l, r) atomic_long_dec(&__rlim_rcur(l, r)) |
12022 |
++#define __rlim_add(l, r, v) atomic_long_add(v, &__rlim_rcur(l, r)) |
12023 |
++#define __rlim_sub(l, r, v) atomic_long_sub(v, &__rlim_rcur(l, r)) |
12024 |
++ |
12025 |
++ |
12026 |
++#if (RLIM_INFINITY == VLIM_INFINITY) |
12027 |
++#define VX_VLIM(r) ((long long)(long)(r)) |
12028 |
++#define VX_RLIM(v) ((rlim_t)(v)) |
12029 |
++#else |
12030 |
++#define VX_VLIM(r) (((r) == RLIM_INFINITY) \ |
12031 |
++ ? VLIM_INFINITY : (long long)(r)) |
12032 |
++#define VX_RLIM(v) (((v) == VLIM_INFINITY) \ |
12033 |
++ ? RLIM_INFINITY : (rlim_t)(v)) |
12034 |
++#endif |
12035 |
++ |
12036 |
++struct sysinfo; |
12037 |
++ |
12038 |
++void vx_vsi_meminfo(struct sysinfo *); |
12039 |
++void vx_vsi_swapinfo(struct sysinfo *); |
12040 |
++ |
12041 |
++#define NUM_LIMITS 24 |
12042 |
++ |
12043 |
++#endif /* __KERNEL__ */ |
12044 |
++#endif /* _VX_LIMIT_H */ |
12045 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/limit_int.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/limit_int.h |
12046 |
+--- linux-2.6.29.4/include/linux/vserver/limit_int.h 1970-01-01 01:00:00.000000000 +0100 |
12047 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/limit_int.h 2009-02-22 22:54:26.000000000 +0100 |
12048 |
+@@ -0,0 +1,198 @@ |
12049 |
++#ifndef _VX_LIMIT_INT_H |
12050 |
++#define _VX_LIMIT_INT_H |
12051 |
++ |
12052 |
++#include "context.h" |
12053 |
++ |
12054 |
++#ifdef __KERNEL__ |
12055 |
++ |
12056 |
++#define VXD_RCRES_COND(r) VXD_CBIT(cres, r) |
12057 |
++#define VXD_RLIMIT_COND(r) VXD_CBIT(limit, r) |
12058 |
++ |
12059 |
++extern const char *vlimit_name[NUM_LIMITS]; |
12060 |
++ |
12061 |
++static inline void __vx_acc_cres(struct vx_info *vxi, |
12062 |
++ int res, int dir, void *_data, char *_file, int _line) |
12063 |
++{ |
12064 |
++ if (VXD_RCRES_COND(res)) |
12065 |
++ vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)", |
12066 |
++ (vxi ? vxi->vx_id : -1), vlimit_name[res], res, |
12067 |
++ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0), |
12068 |
++ (dir > 0) ? "++" : "--", _data, _file, _line); |
12069 |
++ if (!vxi) |
12070 |
++ return; |
12071 |
++ |
12072 |
++ if (dir > 0) |
12073 |
++ __rlim_inc(&vxi->limit, res); |
12074 |
++ else |
12075 |
++ __rlim_dec(&vxi->limit, res); |
12076 |
++} |
12077 |
++ |
12078 |
++static inline void __vx_add_cres(struct vx_info *vxi, |
12079 |
++ int res, int amount, void *_data, char *_file, int _line) |
12080 |
++{ |
12081 |
++ if (VXD_RCRES_COND(res)) |
12082 |
++ vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)", |
12083 |
++ (vxi ? vxi->vx_id : -1), vlimit_name[res], res, |
12084 |
++ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0), |
12085 |
++ amount, _data, _file, _line); |
12086 |
++ if (amount == 0) |
12087 |
++ return; |
12088 |
++ if (!vxi) |
12089 |
++ return; |
12090 |
++ __rlim_add(&vxi->limit, res, amount); |
12091 |
++} |
12092 |
++ |
12093 |
++static inline |
12094 |
++int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value) |
12095 |
++{ |
12096 |
++ int cond = (value > __rlim_rmax(limit, res)); |
12097 |
++ |
12098 |
++ if (cond) |
12099 |
++ __rlim_rmax(limit, res) = value; |
12100 |
++ return cond; |
12101 |
++} |
12102 |
++ |
12103 |
++static inline |
12104 |
++int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value) |
12105 |
++{ |
12106 |
++ int cond = (value < __rlim_rmin(limit, res)); |
12107 |
++ |
12108 |
++ if (cond) |
12109 |
++ __rlim_rmin(limit, res) = value; |
12110 |
++ return cond; |
12111 |
++} |
12112 |
++ |
12113 |
++static inline |
12114 |
++void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value) |
12115 |
++{ |
12116 |
++ if (!__vx_cres_adjust_max(limit, res, value)) |
12117 |
++ __vx_cres_adjust_min(limit, res, value); |
12118 |
++} |
12119 |
++ |
12120 |
++ |
12121 |
++/* return values: |
12122 |
++ +1 ... no limit hit |
12123 |
++ -1 ... over soft limit |
12124 |
++ 0 ... over hard limit */ |
12125 |
++ |
12126 |
++static inline int __vx_cres_avail(struct vx_info *vxi, |
12127 |
++ int res, int num, char *_file, int _line) |
12128 |
++{ |
12129 |
++ struct _vx_limit *limit; |
12130 |
++ rlim_t value; |
12131 |
++ |
12132 |
++ if (VXD_RLIMIT_COND(res)) |
12133 |
++ vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d", |
12134 |
++ (vxi ? vxi->vx_id : -1), vlimit_name[res], res, |
12135 |
++ (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1), |
12136 |
++ (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1), |
12137 |
++ (vxi ? (long)__rlim_get(&vxi->limit, res) : 0), |
12138 |
++ num, _file, _line); |
12139 |
++ if (!vxi) |
12140 |
++ return 1; |
12141 |
++ |
12142 |
++ limit = &vxi->limit; |
12143 |
++ value = __rlim_get(limit, res); |
12144 |
++ |
12145 |
++ if (!__vx_cres_adjust_max(limit, res, value)) |
12146 |
++ __vx_cres_adjust_min(limit, res, value); |
12147 |
++ |
12148 |
++ if (num == 0) |
12149 |
++ return 1; |
12150 |
++ |
12151 |
++ if (__rlim_soft(limit, res) == RLIM_INFINITY) |
12152 |
++ return -1; |
12153 |
++ if (value + num <= __rlim_soft(limit, res)) |
12154 |
++ return -1; |
12155 |
++ |
12156 |
++ if (__rlim_hard(limit, res) == RLIM_INFINITY) |
12157 |
++ return 1; |
12158 |
++ if (value + num <= __rlim_hard(limit, res)) |
12159 |
++ return 1; |
12160 |
++ |
12161 |
++ __rlim_hit(limit, res); |
12162 |
++ return 0; |
12163 |
++} |
12164 |
++ |
12165 |
++ |
12166 |
++static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 }; |
12167 |
++ |
12168 |
++static inline |
12169 |
++rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array) |
12170 |
++{ |
12171 |
++ rlim_t value, sum = 0; |
12172 |
++ int res; |
12173 |
++ |
12174 |
++ while ((res = *array++)) { |
12175 |
++ value = __rlim_get(limit, res); |
12176 |
++ __vx_cres_fixup(limit, res, value); |
12177 |
++ sum += value; |
12178 |
++ } |
12179 |
++ return sum; |
12180 |
++} |
12181 |
++ |
12182 |
++static inline |
12183 |
++rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array) |
12184 |
++{ |
12185 |
++ rlim_t value = __vx_cres_array_sum(limit, array + 1); |
12186 |
++ int res = *array; |
12187 |
++ |
12188 |
++ if (value == __rlim_get(limit, res)) |
12189 |
++ return value; |
12190 |
++ |
12191 |
++ __rlim_set(limit, res, value); |
12192 |
++ /* now adjust min/max */ |
12193 |
++ if (!__vx_cres_adjust_max(limit, res, value)) |
12194 |
++ __vx_cres_adjust_min(limit, res, value); |
12195 |
++ |
12196 |
++ return value; |
12197 |
++} |
12198 |
++ |
12199 |
++static inline int __vx_cres_array_avail(struct vx_info *vxi, |
12200 |
++ const int *array, int num, char *_file, int _line) |
12201 |
++{ |
12202 |
++ struct _vx_limit *limit; |
12203 |
++ rlim_t value = 0; |
12204 |
++ int res; |
12205 |
++ |
12206 |
++ if (num == 0) |
12207 |
++ return 1; |
12208 |
++ if (!vxi) |
12209 |
++ return 1; |
12210 |
++ |
12211 |
++ limit = &vxi->limit; |
12212 |
++ res = *array; |
12213 |
++ value = __vx_cres_array_sum(limit, array + 1); |
12214 |
++ |
12215 |
++ __rlim_set(limit, res, value); |
12216 |
++ __vx_cres_fixup(limit, res, value); |
12217 |
++ |
12218 |
++ return __vx_cres_avail(vxi, res, num, _file, _line); |
12219 |
++} |
12220 |
++ |
12221 |
++ |
12222 |
++static inline void vx_limit_fixup(struct _vx_limit *limit, int id) |
12223 |
++{ |
12224 |
++ rlim_t value; |
12225 |
++ int res; |
12226 |
++ |
12227 |
++ /* complex resources first */ |
12228 |
++ if ((id < 0) || (id == RLIMIT_RSS)) |
12229 |
++ __vx_cres_array_fixup(limit, VLA_RSS); |
12230 |
++ |
12231 |
++ for (res = 0; res < NUM_LIMITS; res++) { |
12232 |
++ if ((id > 0) && (res != id)) |
12233 |
++ continue; |
12234 |
++ |
12235 |
++ value = __rlim_get(limit, res); |
12236 |
++ __vx_cres_fixup(limit, res, value); |
12237 |
++ |
12238 |
++ /* not supposed to happen, maybe warn? */ |
12239 |
++ if (__rlim_rmax(limit, res) > __rlim_hard(limit, res)) |
12240 |
++ __rlim_rmax(limit, res) = __rlim_hard(limit, res); |
12241 |
++ } |
12242 |
++} |
12243 |
++ |
12244 |
++ |
12245 |
++#endif /* __KERNEL__ */ |
12246 |
++#endif /* _VX_LIMIT_INT_H */ |
12247 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/monitor.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/monitor.h |
12248 |
+--- linux-2.6.29.4/include/linux/vserver/monitor.h 1970-01-01 01:00:00.000000000 +0100 |
12249 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/monitor.h 2009-02-22 22:54:26.000000000 +0100 |
12250 |
+@@ -0,0 +1,96 @@ |
12251 |
++#ifndef _VX_MONITOR_H |
12252 |
++#define _VX_MONITOR_H |
12253 |
++ |
12254 |
++#include <linux/types.h> |
12255 |
++ |
12256 |
++enum { |
12257 |
++ VXM_UNUSED = 0, |
12258 |
++ |
12259 |
++ VXM_SYNC = 0x10, |
12260 |
++ |
12261 |
++ VXM_UPDATE = 0x20, |
12262 |
++ VXM_UPDATE_1, |
12263 |
++ VXM_UPDATE_2, |
12264 |
++ |
12265 |
++ VXM_RQINFO_1 = 0x24, |
12266 |
++ VXM_RQINFO_2, |
12267 |
++ |
12268 |
++ VXM_ACTIVATE = 0x40, |
12269 |
++ VXM_DEACTIVATE, |
12270 |
++ VXM_IDLE, |
12271 |
++ |
12272 |
++ VXM_HOLD = 0x44, |
12273 |
++ VXM_UNHOLD, |
12274 |
++ |
12275 |
++ VXM_MIGRATE = 0x48, |
12276 |
++ VXM_RESCHED, |
12277 |
++ |
12278 |
++ /* all other bits are flags */ |
12279 |
++ VXM_SCHED = 0x80, |
12280 |
++}; |
12281 |
++ |
12282 |
++struct _vxm_update_1 { |
12283 |
++ uint32_t tokens_max; |
12284 |
++ uint32_t fill_rate; |
12285 |
++ uint32_t interval; |
12286 |
++}; |
12287 |
++ |
12288 |
++struct _vxm_update_2 { |
12289 |
++ uint32_t tokens_min; |
12290 |
++ uint32_t fill_rate; |
12291 |
++ uint32_t interval; |
12292 |
++}; |
12293 |
++ |
12294 |
++struct _vxm_rqinfo_1 { |
12295 |
++ uint16_t running; |
12296 |
++ uint16_t onhold; |
12297 |
++ uint16_t iowait; |
12298 |
++ uint16_t uintr; |
12299 |
++ uint32_t idle_tokens; |
12300 |
++}; |
12301 |
++ |
12302 |
++struct _vxm_rqinfo_2 { |
12303 |
++ uint32_t norm_time; |
12304 |
++ uint32_t idle_time; |
12305 |
++ uint32_t idle_skip; |
12306 |
++}; |
12307 |
++ |
12308 |
++struct _vxm_sched { |
12309 |
++ uint32_t tokens; |
12310 |
++ uint32_t norm_time; |
12311 |
++ uint32_t idle_time; |
12312 |
++}; |
12313 |
++ |
12314 |
++struct _vxm_task { |
12315 |
++ uint16_t pid; |
12316 |
++ uint16_t state; |
12317 |
++}; |
12318 |
++ |
12319 |
++struct _vxm_event { |
12320 |
++ uint32_t jif; |
12321 |
++ union { |
12322 |
++ uint32_t seq; |
12323 |
++ uint32_t sec; |
12324 |
++ }; |
12325 |
++ union { |
12326 |
++ uint32_t tokens; |
12327 |
++ uint32_t nsec; |
12328 |
++ struct _vxm_task tsk; |
12329 |
++ }; |
12330 |
++}; |
12331 |
++ |
12332 |
++struct _vx_mon_entry { |
12333 |
++ uint16_t type; |
12334 |
++ uint16_t xid; |
12335 |
++ union { |
12336 |
++ struct _vxm_event ev; |
12337 |
++ struct _vxm_sched sd; |
12338 |
++ struct _vxm_update_1 u1; |
12339 |
++ struct _vxm_update_2 u2; |
12340 |
++ struct _vxm_rqinfo_1 q1; |
12341 |
++ struct _vxm_rqinfo_2 q2; |
12342 |
++ }; |
12343 |
++}; |
12344 |
++ |
12345 |
++ |
12346 |
++#endif /* _VX_MONITOR_H */ |
12347 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/network_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/network_cmd.h |
12348 |
+--- linux-2.6.29.4/include/linux/vserver/network_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
12349 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/network_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
12350 |
+@@ -0,0 +1,150 @@ |
12351 |
++#ifndef _VX_NETWORK_CMD_H |
12352 |
++#define _VX_NETWORK_CMD_H |
12353 |
++ |
12354 |
++ |
12355 |
++/* vinfo commands */ |
12356 |
++ |
12357 |
++#define VCMD_task_nid VC_CMD(VINFO, 2, 0) |
12358 |
++ |
12359 |
++#ifdef __KERNEL__ |
12360 |
++extern int vc_task_nid(uint32_t); |
12361 |
++ |
12362 |
++#endif /* __KERNEL__ */ |
12363 |
++ |
12364 |
++#define VCMD_nx_info VC_CMD(VINFO, 6, 0) |
12365 |
++ |
12366 |
++struct vcmd_nx_info_v0 { |
12367 |
++ uint32_t nid; |
12368 |
++ /* more to come */ |
12369 |
++}; |
12370 |
++ |
12371 |
++#ifdef __KERNEL__ |
12372 |
++extern int vc_nx_info(struct nx_info *, void __user *); |
12373 |
++ |
12374 |
++#endif /* __KERNEL__ */ |
12375 |
++ |
12376 |
++#include <linux/in.h> |
12377 |
++#include <linux/in6.h> |
12378 |
++ |
12379 |
++#define VCMD_net_create_v0 VC_CMD(VNET, 1, 0) |
12380 |
++#define VCMD_net_create VC_CMD(VNET, 1, 1) |
12381 |
++ |
12382 |
++struct vcmd_net_create { |
12383 |
++ uint64_t flagword; |
12384 |
++}; |
12385 |
++ |
12386 |
++#define VCMD_net_migrate VC_CMD(NETMIG, 1, 0) |
12387 |
++ |
12388 |
++#define VCMD_net_add VC_CMD(NETALT, 1, 0) |
12389 |
++#define VCMD_net_remove VC_CMD(NETALT, 2, 0) |
12390 |
++ |
12391 |
++struct vcmd_net_addr_v0 { |
12392 |
++ uint16_t type; |
12393 |
++ uint16_t count; |
12394 |
++ struct in_addr ip[4]; |
12395 |
++ struct in_addr mask[4]; |
12396 |
++}; |
12397 |
++ |
12398 |
++#define VCMD_net_add_ipv4 VC_CMD(NETALT, 1, 1) |
12399 |
++#define VCMD_net_remove_ipv4 VC_CMD(NETALT, 2, 1) |
12400 |
++ |
12401 |
++struct vcmd_net_addr_ipv4_v1 { |
12402 |
++ uint16_t type; |
12403 |
++ uint16_t flags; |
12404 |
++ struct in_addr ip; |
12405 |
++ struct in_addr mask; |
12406 |
++}; |
12407 |
++ |
12408 |
++#define VCMD_net_add_ipv6 VC_CMD(NETALT, 3, 1) |
12409 |
++#define VCMD_net_remove_ipv6 VC_CMD(NETALT, 4, 1) |
12410 |
++ |
12411 |
++struct vcmd_net_addr_ipv6_v1 { |
12412 |
++ uint16_t type; |
12413 |
++ uint16_t flags; |
12414 |
++ uint32_t prefix; |
12415 |
++ struct in6_addr ip; |
12416 |
++ struct in6_addr mask; |
12417 |
++}; |
12418 |
++ |
12419 |
++#define VCMD_add_match_ipv4 VC_CMD(NETALT, 5, 0) |
12420 |
++#define VCMD_get_match_ipv4 VC_CMD(NETALT, 6, 0) |
12421 |
++ |
12422 |
++struct vcmd_match_ipv4_v0 { |
12423 |
++ uint16_t type; |
12424 |
++ uint16_t flags; |
12425 |
++ uint16_t parent; |
12426 |
++ uint16_t prefix; |
12427 |
++ struct in_addr ip; |
12428 |
++ struct in_addr ip2; |
12429 |
++ struct in_addr mask; |
12430 |
++}; |
12431 |
++ |
12432 |
++#define VCMD_add_match_ipv6 VC_CMD(NETALT, 7, 0) |
12433 |
++#define VCMD_get_match_ipv6 VC_CMD(NETALT, 8, 0) |
12434 |
++ |
12435 |
++struct vcmd_match_ipv6_v0 { |
12436 |
++ uint16_t type; |
12437 |
++ uint16_t flags; |
12438 |
++ uint16_t parent; |
12439 |
++ uint16_t prefix; |
12440 |
++ struct in6_addr ip; |
12441 |
++ struct in6_addr ip2; |
12442 |
++ struct in6_addr mask; |
12443 |
++}; |
12444 |
++ |
12445 |
++ |
12446 |
++#ifdef __KERNEL__ |
12447 |
++extern int vc_net_create(uint32_t, void __user *); |
12448 |
++extern int vc_net_migrate(struct nx_info *, void __user *); |
12449 |
++ |
12450 |
++extern int vc_net_add(struct nx_info *, void __user *); |
12451 |
++extern int vc_net_remove(struct nx_info *, void __user *); |
12452 |
++ |
12453 |
++extern int vc_net_add_ipv4(struct nx_info *, void __user *); |
12454 |
++extern int vc_net_remove_ipv4(struct nx_info *, void __user *); |
12455 |
++ |
12456 |
++extern int vc_net_add_ipv6(struct nx_info *, void __user *); |
12457 |
++extern int vc_net_remove_ipv6(struct nx_info *, void __user *); |
12458 |
++ |
12459 |
++extern int vc_add_match_ipv4(struct nx_info *, void __user *); |
12460 |
++extern int vc_get_match_ipv4(struct nx_info *, void __user *); |
12461 |
++ |
12462 |
++extern int vc_add_match_ipv6(struct nx_info *, void __user *); |
12463 |
++extern int vc_get_match_ipv6(struct nx_info *, void __user *); |
12464 |
++ |
12465 |
++#endif /* __KERNEL__ */ |
12466 |
++ |
12467 |
++ |
12468 |
++/* flag commands */ |
12469 |
++ |
12470 |
++#define VCMD_get_nflags VC_CMD(FLAGS, 5, 0) |
12471 |
++#define VCMD_set_nflags VC_CMD(FLAGS, 6, 0) |
12472 |
++ |
12473 |
++struct vcmd_net_flags_v0 { |
12474 |
++ uint64_t flagword; |
12475 |
++ uint64_t mask; |
12476 |
++}; |
12477 |
++ |
12478 |
++#ifdef __KERNEL__ |
12479 |
++extern int vc_get_nflags(struct nx_info *, void __user *); |
12480 |
++extern int vc_set_nflags(struct nx_info *, void __user *); |
12481 |
++ |
12482 |
++#endif /* __KERNEL__ */ |
12483 |
++ |
12484 |
++ |
12485 |
++/* network caps commands */ |
12486 |
++ |
12487 |
++#define VCMD_get_ncaps VC_CMD(FLAGS, 7, 0) |
12488 |
++#define VCMD_set_ncaps VC_CMD(FLAGS, 8, 0) |
12489 |
++ |
12490 |
++struct vcmd_net_caps_v0 { |
12491 |
++ uint64_t ncaps; |
12492 |
++ uint64_t cmask; |
12493 |
++}; |
12494 |
++ |
12495 |
++#ifdef __KERNEL__ |
12496 |
++extern int vc_get_ncaps(struct nx_info *, void __user *); |
12497 |
++extern int vc_set_ncaps(struct nx_info *, void __user *); |
12498 |
++ |
12499 |
++#endif /* __KERNEL__ */ |
12500 |
++#endif /* _VX_CONTEXT_CMD_H */ |
12501 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/network.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/network.h |
12502 |
+--- linux-2.6.29.4/include/linux/vserver/network.h 1970-01-01 01:00:00.000000000 +0100 |
12503 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/network.h 2009-02-22 22:54:26.000000000 +0100 |
12504 |
+@@ -0,0 +1,146 @@ |
12505 |
++#ifndef _VX_NETWORK_H |
12506 |
++#define _VX_NETWORK_H |
12507 |
++ |
12508 |
++#include <linux/types.h> |
12509 |
++ |
12510 |
++ |
12511 |
++#define MAX_N_CONTEXT 65535 /* Arbitrary limit */ |
12512 |
++ |
12513 |
++ |
12514 |
++/* network flags */ |
12515 |
++ |
12516 |
++#define NXF_INFO_PRIVATE 0x00000008 |
12517 |
++ |
12518 |
++#define NXF_SINGLE_IP 0x00000100 |
12519 |
++#define NXF_LBACK_REMAP 0x00000200 |
12520 |
++#define NXF_LBACK_ALLOW 0x00000400 |
12521 |
++ |
12522 |
++#define NXF_HIDE_NETIF 0x02000000 |
12523 |
++#define NXF_HIDE_LBACK 0x04000000 |
12524 |
++ |
12525 |
++#define NXF_STATE_SETUP (1ULL << 32) |
12526 |
++#define NXF_STATE_ADMIN (1ULL << 34) |
12527 |
++ |
12528 |
++#define NXF_SC_HELPER (1ULL << 36) |
12529 |
++#define NXF_PERSISTENT (1ULL << 38) |
12530 |
++ |
12531 |
++#define NXF_ONE_TIME (0x0005ULL << 32) |
12532 |
++ |
12533 |
++ |
12534 |
++#define NXF_INIT_SET (__nxf_init_set()) |
12535 |
++ |
12536 |
++static inline uint64_t __nxf_init_set(void) { |
12537 |
++ return NXF_STATE_ADMIN |
12538 |
++#ifdef CONFIG_VSERVER_AUTO_LBACK |
12539 |
++ | NXF_LBACK_REMAP |
12540 |
++ | NXF_HIDE_LBACK |
12541 |
++#endif |
12542 |
++#ifdef CONFIG_VSERVER_AUTO_SINGLE |
12543 |
++ | NXF_SINGLE_IP |
12544 |
++#endif |
12545 |
++ | NXF_HIDE_NETIF; |
12546 |
++} |
12547 |
++ |
12548 |
++ |
12549 |
++/* network caps */ |
12550 |
++ |
12551 |
++#define NXC_TUN_CREATE 0x00000001 |
12552 |
++ |
12553 |
++#define NXC_RAW_ICMP 0x00000100 |
12554 |
++ |
12555 |
++ |
12556 |
++/* address types */ |
12557 |
++ |
12558 |
++#define NXA_TYPE_IPV4 0x0001 |
12559 |
++#define NXA_TYPE_IPV6 0x0002 |
12560 |
++ |
12561 |
++#define NXA_TYPE_NONE 0x0000 |
12562 |
++#define NXA_TYPE_ANY 0x00FF |
12563 |
++ |
12564 |
++#define NXA_TYPE_ADDR 0x0010 |
12565 |
++#define NXA_TYPE_MASK 0x0020 |
12566 |
++#define NXA_TYPE_RANGE 0x0040 |
12567 |
++ |
12568 |
++#define NXA_MASK_ALL (NXA_TYPE_ADDR | NXA_TYPE_MASK | NXA_TYPE_RANGE) |
12569 |
++ |
12570 |
++#define NXA_MOD_BCAST 0x0100 |
12571 |
++#define NXA_MOD_LBACK 0x0200 |
12572 |
++ |
12573 |
++#define NXA_LOOPBACK 0x1000 |
12574 |
++ |
12575 |
++#define NXA_MASK_BIND (NXA_MASK_ALL | NXA_MOD_BCAST | NXA_MOD_LBACK) |
12576 |
++#define NXA_MASK_SHOW (NXA_MASK_ALL | NXA_LOOPBACK) |
12577 |
++ |
12578 |
++#ifdef __KERNEL__ |
12579 |
++ |
12580 |
++#include <linux/list.h> |
12581 |
++#include <linux/spinlock.h> |
12582 |
++#include <linux/rcupdate.h> |
12583 |
++#include <linux/in.h> |
12584 |
++#include <linux/in6.h> |
12585 |
++#include <asm/atomic.h> |
12586 |
++ |
12587 |
++struct nx_addr_v4 { |
12588 |
++ struct nx_addr_v4 *next; |
12589 |
++ struct in_addr ip[2]; |
12590 |
++ struct in_addr mask; |
12591 |
++ uint16_t type; |
12592 |
++ uint16_t flags; |
12593 |
++}; |
12594 |
++ |
12595 |
++struct nx_addr_v6 { |
12596 |
++ struct nx_addr_v6 *next; |
12597 |
++ struct in6_addr ip; |
12598 |
++ struct in6_addr mask; |
12599 |
++ uint32_t prefix; |
12600 |
++ uint16_t type; |
12601 |
++ uint16_t flags; |
12602 |
++}; |
12603 |
++ |
12604 |
++struct nx_info { |
12605 |
++ struct hlist_node nx_hlist; /* linked list of nxinfos */ |
12606 |
++ nid_t nx_id; /* vnet id */ |
12607 |
++ atomic_t nx_usecnt; /* usage count */ |
12608 |
++ atomic_t nx_tasks; /* tasks count */ |
12609 |
++ int nx_state; /* context state */ |
12610 |
++ |
12611 |
++ uint64_t nx_flags; /* network flag word */ |
12612 |
++ uint64_t nx_ncaps; /* network capabilities */ |
12613 |
++ |
12614 |
++ struct in_addr v4_lback; /* Loopback address */ |
12615 |
++ struct in_addr v4_bcast; /* Broadcast address */ |
12616 |
++ struct nx_addr_v4 v4; /* First/Single ipv4 address */ |
12617 |
++#ifdef CONFIG_IPV6 |
12618 |
++ struct nx_addr_v6 v6; /* First/Single ipv6 address */ |
12619 |
++#endif |
12620 |
++ char nx_name[65]; /* network context name */ |
12621 |
++}; |
12622 |
++ |
12623 |
++ |
12624 |
++/* status flags */ |
12625 |
++ |
12626 |
++#define NXS_HASHED 0x0001 |
12627 |
++#define NXS_SHUTDOWN 0x0100 |
12628 |
++#define NXS_RELEASED 0x8000 |
12629 |
++ |
12630 |
++extern struct nx_info *lookup_nx_info(int); |
12631 |
++ |
12632 |
++extern int get_nid_list(int, unsigned int *, int); |
12633 |
++extern int nid_is_hashed(nid_t); |
12634 |
++ |
12635 |
++extern int nx_migrate_task(struct task_struct *, struct nx_info *); |
12636 |
++ |
12637 |
++extern long vs_net_change(struct nx_info *, unsigned int); |
12638 |
++ |
12639 |
++struct sock; |
12640 |
++ |
12641 |
++ |
12642 |
++#define NX_IPV4(n) ((n)->v4.type != NXA_TYPE_NONE) |
12643 |
++#ifdef CONFIG_IPV6 |
12644 |
++#define NX_IPV6(n) ((n)->v6.type != NXA_TYPE_NONE) |
12645 |
++#else |
12646 |
++#define NX_IPV6(n) (0) |
12647 |
++#endif |
12648 |
++ |
12649 |
++#endif /* __KERNEL__ */ |
12650 |
++#endif /* _VX_NETWORK_H */ |
12651 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/percpu.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/percpu.h |
12652 |
+--- linux-2.6.29.4/include/linux/vserver/percpu.h 1970-01-01 01:00:00.000000000 +0100 |
12653 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/percpu.h 2009-02-22 22:54:26.000000000 +0100 |
12654 |
+@@ -0,0 +1,14 @@ |
12655 |
++#ifndef _VX_PERCPU_H |
12656 |
++#define _VX_PERCPU_H |
12657 |
++ |
12658 |
++#include "cvirt_def.h" |
12659 |
++#include "sched_def.h" |
12660 |
++ |
12661 |
++struct _vx_percpu { |
12662 |
++ struct _vx_cvirt_pc cvirt; |
12663 |
++ struct _vx_sched_pc sched; |
12664 |
++}; |
12665 |
++ |
12666 |
++#define PERCPU_PERCTX (sizeof(struct _vx_percpu)) |
12667 |
++ |
12668 |
++#endif /* _VX_PERCPU_H */ |
12669 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/pid.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/pid.h |
12670 |
+--- linux-2.6.29.4/include/linux/vserver/pid.h 1970-01-01 01:00:00.000000000 +0100 |
12671 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/pid.h 2009-02-22 22:54:26.000000000 +0100 |
12672 |
+@@ -0,0 +1,51 @@ |
12673 |
++#ifndef _VSERVER_PID_H |
12674 |
++#define _VSERVER_PID_H |
12675 |
++ |
12676 |
++/* pid faking stuff */ |
12677 |
++ |
12678 |
++#define vx_info_map_pid(v, p) \ |
12679 |
++ __vx_info_map_pid((v), (p), __func__, __FILE__, __LINE__) |
12680 |
++#define vx_info_map_tgid(v,p) vx_info_map_pid(v,p) |
12681 |
++#define vx_map_pid(p) vx_info_map_pid(current->vx_info, p) |
12682 |
++#define vx_map_tgid(p) vx_map_pid(p) |
12683 |
++ |
12684 |
++static inline int __vx_info_map_pid(struct vx_info *vxi, int pid, |
12685 |
++ const char *func, const char *file, int line) |
12686 |
++{ |
12687 |
++ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) { |
12688 |
++ vxfprintk(VXD_CBIT(cvirt, 2), |
12689 |
++ "vx_map_tgid: %p/%llx: %d -> %d", |
12690 |
++ vxi, (long long)vxi->vx_flags, pid, |
12691 |
++ (pid && pid == vxi->vx_initpid) ? 1 : pid, |
12692 |
++ func, file, line); |
12693 |
++ if (pid == 0) |
12694 |
++ return 0; |
12695 |
++ if (pid == vxi->vx_initpid) |
12696 |
++ return 1; |
12697 |
++ } |
12698 |
++ return pid; |
12699 |
++} |
12700 |
++ |
12701 |
++#define vx_info_rmap_pid(v, p) \ |
12702 |
++ __vx_info_rmap_pid((v), (p), __func__, __FILE__, __LINE__) |
12703 |
++#define vx_rmap_pid(p) vx_info_rmap_pid(current->vx_info, p) |
12704 |
++#define vx_rmap_tgid(p) vx_rmap_pid(p) |
12705 |
++ |
12706 |
++static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid, |
12707 |
++ const char *func, const char *file, int line) |
12708 |
++{ |
12709 |
++ if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) { |
12710 |
++ vxfprintk(VXD_CBIT(cvirt, 2), |
12711 |
++ "vx_rmap_tgid: %p/%llx: %d -> %d", |
12712 |
++ vxi, (long long)vxi->vx_flags, pid, |
12713 |
++ (pid == 1) ? vxi->vx_initpid : pid, |
12714 |
++ func, file, line); |
12715 |
++ if ((pid == 1) && vxi->vx_initpid) |
12716 |
++ return vxi->vx_initpid; |
12717 |
++ if (pid == vxi->vx_initpid) |
12718 |
++ return ~0U; |
12719 |
++ } |
12720 |
++ return pid; |
12721 |
++} |
12722 |
++ |
12723 |
++#endif |
12724 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/sched_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/sched_cmd.h |
12725 |
+--- linux-2.6.29.4/include/linux/vserver/sched_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
12726 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/sched_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
12727 |
+@@ -0,0 +1,108 @@ |
12728 |
++#ifndef _VX_SCHED_CMD_H |
12729 |
++#define _VX_SCHED_CMD_H |
12730 |
++ |
12731 |
++ |
12732 |
++/* sched vserver commands */ |
12733 |
++ |
12734 |
++#define VCMD_set_sched_v2 VC_CMD(SCHED, 1, 2) |
12735 |
++#define VCMD_set_sched_v3 VC_CMD(SCHED, 1, 3) |
12736 |
++#define VCMD_set_sched_v4 VC_CMD(SCHED, 1, 4) |
12737 |
++ |
12738 |
++struct vcmd_set_sched_v2 { |
12739 |
++ int32_t fill_rate; |
12740 |
++ int32_t interval; |
12741 |
++ int32_t tokens; |
12742 |
++ int32_t tokens_min; |
12743 |
++ int32_t tokens_max; |
12744 |
++ uint64_t cpu_mask; |
12745 |
++}; |
12746 |
++ |
12747 |
++struct vcmd_set_sched_v3 { |
12748 |
++ uint32_t set_mask; |
12749 |
++ int32_t fill_rate; |
12750 |
++ int32_t interval; |
12751 |
++ int32_t tokens; |
12752 |
++ int32_t tokens_min; |
12753 |
++ int32_t tokens_max; |
12754 |
++ int32_t priority_bias; |
12755 |
++}; |
12756 |
++ |
12757 |
++struct vcmd_set_sched_v4 { |
12758 |
++ uint32_t set_mask; |
12759 |
++ int32_t fill_rate; |
12760 |
++ int32_t interval; |
12761 |
++ int32_t tokens; |
12762 |
++ int32_t tokens_min; |
12763 |
++ int32_t tokens_max; |
12764 |
++ int32_t prio_bias; |
12765 |
++ int32_t cpu_id; |
12766 |
++ int32_t bucket_id; |
12767 |
++}; |
12768 |
++ |
12769 |
++#define VCMD_set_sched VC_CMD(SCHED, 1, 5) |
12770 |
++#define VCMD_get_sched VC_CMD(SCHED, 2, 5) |
12771 |
++ |
12772 |
++struct vcmd_sched_v5 { |
12773 |
++ uint32_t mask; |
12774 |
++ int32_t cpu_id; |
12775 |
++ int32_t bucket_id; |
12776 |
++ int32_t fill_rate[2]; |
12777 |
++ int32_t interval[2]; |
12778 |
++ int32_t tokens; |
12779 |
++ int32_t tokens_min; |
12780 |
++ int32_t tokens_max; |
12781 |
++ int32_t prio_bias; |
12782 |
++}; |
12783 |
++ |
12784 |
++#define VXSM_FILL_RATE 0x0001 |
12785 |
++#define VXSM_INTERVAL 0x0002 |
12786 |
++#define VXSM_FILL_RATE2 0x0004 |
12787 |
++#define VXSM_INTERVAL2 0x0008 |
12788 |
++#define VXSM_TOKENS 0x0010 |
12789 |
++#define VXSM_TOKENS_MIN 0x0020 |
12790 |
++#define VXSM_TOKENS_MAX 0x0040 |
12791 |
++#define VXSM_PRIO_BIAS 0x0100 |
12792 |
++ |
12793 |
++#define VXSM_IDLE_TIME 0x0200 |
12794 |
++#define VXSM_FORCE 0x0400 |
12795 |
++ |
12796 |
++#define VXSM_V3_MASK 0x0173 |
12797 |
++#define VXSM_SET_MASK 0x01FF |
12798 |
++ |
12799 |
++#define VXSM_CPU_ID 0x1000 |
12800 |
++#define VXSM_BUCKET_ID 0x2000 |
12801 |
++ |
12802 |
++#define VXSM_MSEC 0x4000 |
12803 |
++ |
12804 |
++#define SCHED_KEEP (-2) /* only for v2 */ |
12805 |
++ |
12806 |
++#ifdef __KERNEL__ |
12807 |
++ |
12808 |
++#include <linux/compiler.h> |
12809 |
++ |
12810 |
++extern int vc_set_sched_v2(struct vx_info *, void __user *); |
12811 |
++extern int vc_set_sched_v3(struct vx_info *, void __user *); |
12812 |
++extern int vc_set_sched_v4(struct vx_info *, void __user *); |
12813 |
++extern int vc_set_sched(struct vx_info *, void __user *); |
12814 |
++extern int vc_get_sched(struct vx_info *, void __user *); |
12815 |
++ |
12816 |
++#endif /* __KERNEL__ */ |
12817 |
++ |
12818 |
++#define VCMD_sched_info VC_CMD(SCHED, 3, 0) |
12819 |
++ |
12820 |
++struct vcmd_sched_info { |
12821 |
++ int32_t cpu_id; |
12822 |
++ int32_t bucket_id; |
12823 |
++ uint64_t user_msec; |
12824 |
++ uint64_t sys_msec; |
12825 |
++ uint64_t hold_msec; |
12826 |
++ uint32_t token_usec; |
12827 |
++ int32_t vavavoom; |
12828 |
++}; |
12829 |
++ |
12830 |
++#ifdef __KERNEL__ |
12831 |
++ |
12832 |
++extern int vc_sched_info(struct vx_info *, void __user *); |
12833 |
++ |
12834 |
++#endif /* __KERNEL__ */ |
12835 |
++#endif /* _VX_SCHED_CMD_H */ |
12836 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/sched_def.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/sched_def.h |
12837 |
+--- linux-2.6.29.4/include/linux/vserver/sched_def.h 1970-01-01 01:00:00.000000000 +0100 |
12838 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/sched_def.h 2009-02-22 22:54:26.000000000 +0100 |
12839 |
+@@ -0,0 +1,68 @@ |
12840 |
++#ifndef _VX_SCHED_DEF_H |
12841 |
++#define _VX_SCHED_DEF_H |
12842 |
++ |
12843 |
++#include <linux/spinlock.h> |
12844 |
++#include <linux/jiffies.h> |
12845 |
++#include <linux/cpumask.h> |
12846 |
++#include <asm/atomic.h> |
12847 |
++#include <asm/param.h> |
12848 |
++ |
12849 |
++ |
12850 |
++/* context sub struct */ |
12851 |
++ |
12852 |
++struct _vx_sched { |
12853 |
++ spinlock_t tokens_lock; /* lock for token bucket */ |
12854 |
++ |
12855 |
++ int tokens; /* number of CPU tokens */ |
12856 |
++ int fill_rate[2]; /* Fill rate: add X tokens... */ |
12857 |
++ int interval[2]; /* Divisor: per Y jiffies */ |
12858 |
++ int tokens_min; /* Limit: minimum for unhold */ |
12859 |
++ int tokens_max; /* Limit: no more than N tokens */ |
12860 |
++ |
12861 |
++ int prio_bias; /* bias offset for priority */ |
12862 |
++ |
12863 |
++ unsigned update_mask; /* which features should be updated */ |
12864 |
++ cpumask_t update; /* CPUs which should update */ |
12865 |
++}; |
12866 |
++ |
12867 |
++struct _vx_sched_pc { |
12868 |
++ int tokens; /* number of CPU tokens */ |
12869 |
++ int flags; /* bucket flags */ |
12870 |
++ |
12871 |
++ int fill_rate[2]; /* Fill rate: add X tokens... */ |
12872 |
++ int interval[2]; /* Divisor: per Y jiffies */ |
12873 |
++ int tokens_min; /* Limit: minimum for unhold */ |
12874 |
++ int tokens_max; /* Limit: no more than N tokens */ |
12875 |
++ |
12876 |
++ int prio_bias; /* bias offset for priority */ |
12877 |
++ int vavavoom; /* last calculated vavavoom */ |
12878 |
++ |
12879 |
++ unsigned long norm_time; /* last time accounted */ |
12880 |
++ unsigned long idle_time; /* non linear time for fair sched */ |
12881 |
++ unsigned long token_time; /* token time for accounting */ |
12882 |
++ unsigned long onhold; /* jiffies when put on hold */ |
12883 |
++ |
12884 |
++ uint64_t user_ticks; /* token tick events */ |
12885 |
++ uint64_t sys_ticks; /* token tick events */ |
12886 |
++ uint64_t hold_ticks; /* token ticks paused */ |
12887 |
++}; |
12888 |
++ |
12889 |
++ |
12890 |
++#define VXSF_ONHOLD 0x0001 |
12891 |
++#define VXSF_IDLE_TIME 0x0100 |
12892 |
++ |
12893 |
++#ifdef CONFIG_VSERVER_DEBUG |
12894 |
++ |
12895 |
++static inline void __dump_vx_sched(struct _vx_sched *sched) |
12896 |
++{ |
12897 |
++ printk("\t_vx_sched:\n"); |
12898 |
++ printk("\t tokens: %4d/%4d, %4d/%4d, %4d, %4d\n", |
12899 |
++ sched->fill_rate[0], sched->interval[0], |
12900 |
++ sched->fill_rate[1], sched->interval[1], |
12901 |
++ sched->tokens_min, sched->tokens_max); |
12902 |
++ printk("\t priority = %4d\n", sched->prio_bias); |
12903 |
++} |
12904 |
++ |
12905 |
++#endif |
12906 |
++ |
12907 |
++#endif /* _VX_SCHED_DEF_H */ |
12908 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/sched.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/sched.h |
12909 |
+--- linux-2.6.29.4/include/linux/vserver/sched.h 1970-01-01 01:00:00.000000000 +0100 |
12910 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/sched.h 2009-02-22 22:54:26.000000000 +0100 |
12911 |
+@@ -0,0 +1,26 @@ |
12912 |
++#ifndef _VX_SCHED_H |
12913 |
++#define _VX_SCHED_H |
12914 |
++ |
12915 |
++ |
12916 |
++#ifdef __KERNEL__ |
12917 |
++ |
12918 |
++struct timespec; |
12919 |
++ |
12920 |
++void vx_vsi_uptime(struct timespec *, struct timespec *); |
12921 |
++ |
12922 |
++ |
12923 |
++struct vx_info; |
12924 |
++ |
12925 |
++void vx_update_load(struct vx_info *); |
12926 |
++ |
12927 |
++ |
12928 |
++int vx_tokens_recalc(struct _vx_sched_pc *, |
12929 |
++ unsigned long *, unsigned long *, int [2]); |
12930 |
++ |
12931 |
++void vx_update_sched_param(struct _vx_sched *sched, |
12932 |
++ struct _vx_sched_pc *sched_pc); |
12933 |
++ |
12934 |
++#endif /* __KERNEL__ */ |
12935 |
++#else /* _VX_SCHED_H */ |
12936 |
++#warning duplicate inclusion |
12937 |
++#endif /* _VX_SCHED_H */ |
12938 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/signal_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/signal_cmd.h |
12939 |
+--- linux-2.6.29.4/include/linux/vserver/signal_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
12940 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/signal_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
12941 |
+@@ -0,0 +1,43 @@ |
12942 |
++#ifndef _VX_SIGNAL_CMD_H |
12943 |
++#define _VX_SIGNAL_CMD_H |
12944 |
++ |
12945 |
++ |
12946 |
++/* signalling vserver commands */ |
12947 |
++ |
12948 |
++#define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0) |
12949 |
++#define VCMD_wait_exit VC_CMD(EVENT, 99, 0) |
12950 |
++ |
12951 |
++struct vcmd_ctx_kill_v0 { |
12952 |
++ int32_t pid; |
12953 |
++ int32_t sig; |
12954 |
++}; |
12955 |
++ |
12956 |
++struct vcmd_wait_exit_v0 { |
12957 |
++ int32_t reboot_cmd; |
12958 |
++ int32_t exit_code; |
12959 |
++}; |
12960 |
++ |
12961 |
++#ifdef __KERNEL__ |
12962 |
++ |
12963 |
++extern int vc_ctx_kill(struct vx_info *, void __user *); |
12964 |
++extern int vc_wait_exit(struct vx_info *, void __user *); |
12965 |
++ |
12966 |
++#endif /* __KERNEL__ */ |
12967 |
++ |
12968 |
++/* process alteration commands */ |
12969 |
++ |
12970 |
++#define VCMD_get_pflags VC_CMD(PROCALT, 5, 0) |
12971 |
++#define VCMD_set_pflags VC_CMD(PROCALT, 6, 0) |
12972 |
++ |
12973 |
++struct vcmd_pflags_v0 { |
12974 |
++ uint32_t flagword; |
12975 |
++ uint32_t mask; |
12976 |
++}; |
12977 |
++ |
12978 |
++#ifdef __KERNEL__ |
12979 |
++ |
12980 |
++extern int vc_get_pflags(uint32_t pid, void __user *); |
12981 |
++extern int vc_set_pflags(uint32_t pid, void __user *); |
12982 |
++ |
12983 |
++#endif /* __KERNEL__ */ |
12984 |
++#endif /* _VX_SIGNAL_CMD_H */ |
12985 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/signal.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/signal.h |
12986 |
+--- linux-2.6.29.4/include/linux/vserver/signal.h 1970-01-01 01:00:00.000000000 +0100 |
12987 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/signal.h 2009-02-22 22:54:26.000000000 +0100 |
12988 |
+@@ -0,0 +1,14 @@ |
12989 |
++#ifndef _VX_SIGNAL_H |
12990 |
++#define _VX_SIGNAL_H |
12991 |
++ |
12992 |
++ |
12993 |
++#ifdef __KERNEL__ |
12994 |
++ |
12995 |
++struct vx_info; |
12996 |
++ |
12997 |
++int vx_info_kill(struct vx_info *, int, int); |
12998 |
++ |
12999 |
++#endif /* __KERNEL__ */ |
13000 |
++#else /* _VX_SIGNAL_H */ |
13001 |
++#warning duplicate inclusion |
13002 |
++#endif /* _VX_SIGNAL_H */ |
13003 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/space_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/space_cmd.h |
13004 |
+--- linux-2.6.29.4/include/linux/vserver/space_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
13005 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/space_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
13006 |
+@@ -0,0 +1,38 @@ |
13007 |
++#ifndef _VX_SPACE_CMD_H |
13008 |
++#define _VX_SPACE_CMD_H |
13009 |
++ |
13010 |
++ |
13011 |
++#define VCMD_enter_space_v0 VC_CMD(PROCALT, 1, 0) |
13012 |
++#define VCMD_enter_space_v1 VC_CMD(PROCALT, 1, 1) |
13013 |
++#define VCMD_enter_space VC_CMD(PROCALT, 1, 2) |
13014 |
++ |
13015 |
++#define VCMD_set_space_v0 VC_CMD(PROCALT, 3, 0) |
13016 |
++#define VCMD_set_space_v1 VC_CMD(PROCALT, 3, 1) |
13017 |
++#define VCMD_set_space VC_CMD(PROCALT, 3, 2) |
13018 |
++ |
13019 |
++#define VCMD_get_space_mask_v0 VC_CMD(PROCALT, 4, 0) |
13020 |
++ |
13021 |
++#define VCMD_get_space_mask VC_CMD(VSPACE, 0, 1) |
13022 |
++#define VCMD_get_space_default VC_CMD(VSPACE, 1, 0) |
13023 |
++ |
13024 |
++ |
13025 |
++struct vcmd_space_mask_v1 { |
13026 |
++ uint64_t mask; |
13027 |
++}; |
13028 |
++ |
13029 |
++struct vcmd_space_mask_v2 { |
13030 |
++ uint64_t mask; |
13031 |
++ uint32_t index; |
13032 |
++}; |
13033 |
++ |
13034 |
++ |
13035 |
++#ifdef __KERNEL__ |
13036 |
++ |
13037 |
++extern int vc_enter_space_v1(struct vx_info *, void __user *); |
13038 |
++extern int vc_set_space_v1(struct vx_info *, void __user *); |
13039 |
++extern int vc_enter_space(struct vx_info *, void __user *); |
13040 |
++extern int vc_set_space(struct vx_info *, void __user *); |
13041 |
++extern int vc_get_space_mask(void __user *, int); |
13042 |
++ |
13043 |
++#endif /* __KERNEL__ */ |
13044 |
++#endif /* _VX_SPACE_CMD_H */ |
13045 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/space.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/space.h |
13046 |
+--- linux-2.6.29.4/include/linux/vserver/space.h 1970-01-01 01:00:00.000000000 +0100 |
13047 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/space.h 2009-02-22 22:54:26.000000000 +0100 |
13048 |
+@@ -0,0 +1,12 @@ |
13049 |
++#ifndef _VX_SPACE_H |
13050 |
++#define _VX_SPACE_H |
13051 |
++ |
13052 |
++#include <linux/types.h> |
13053 |
++ |
13054 |
++struct vx_info; |
13055 |
++ |
13056 |
++int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index); |
13057 |
++ |
13058 |
++#else /* _VX_SPACE_H */ |
13059 |
++#warning duplicate inclusion |
13060 |
++#endif /* _VX_SPACE_H */ |
13061 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/switch.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/switch.h |
13062 |
+--- linux-2.6.29.4/include/linux/vserver/switch.h 1970-01-01 01:00:00.000000000 +0100 |
13063 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/switch.h 2009-02-22 22:54:26.000000000 +0100 |
13064 |
+@@ -0,0 +1,98 @@ |
13065 |
++#ifndef _VX_SWITCH_H |
13066 |
++#define _VX_SWITCH_H |
13067 |
++ |
13068 |
++#include <linux/types.h> |
13069 |
++ |
13070 |
++ |
13071 |
++#define VC_CATEGORY(c) (((c) >> 24) & 0x3F) |
13072 |
++#define VC_COMMAND(c) (((c) >> 16) & 0xFF) |
13073 |
++#define VC_VERSION(c) ((c) & 0xFFF) |
13074 |
++ |
13075 |
++#define VC_CMD(c, i, v) ((((VC_CAT_ ## c) & 0x3F) << 24) \ |
13076 |
++ | (((i) & 0xFF) << 16) | ((v) & 0xFFF)) |
13077 |
++ |
13078 |
++/* |
13079 |
++ |
13080 |
++ Syscall Matrix V2.8 |
13081 |
++ |
13082 |
++ |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL| |
13083 |
++ |STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | | |
13084 |
++ |INFO |SETUP | |MOVE | | | | | | |
13085 |
++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ |
13086 |
++ SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICE | | |
13087 |
++ HOST | 00| 01| 02| 03| 04| 05| | 06| 07| |
13088 |
++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ |
13089 |
++ CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | | |
13090 |
++ PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15| |
13091 |
++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ |
13092 |
++ MEMORY | | | | |MEMCTRL| | |SWAP | | |
13093 |
++ | 16| 17| 18| 19| 20| 21| | 22| 23| |
13094 |
++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ |
13095 |
++ NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | | |
13096 |
++ | 24| 25| 26| 27| 28| 29| | 30| 31| |
13097 |
++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ |
13098 |
++ DISK | | | |TAGMIG |DLIMIT | | |INODE | | |
13099 |
++ VFS | 32| 33| 34| 35| 36| 37| | 38| 39| |
13100 |
++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ |
13101 |
++ OTHER |VSTAT | | | | | | |VINFO | | |
13102 |
++ | 40| 41| 42| 43| 44| 45| | 46| 47| |
13103 |
++ =======+=======+=======+=======+=======+=======+=======+ +=======+=======+ |
13104 |
++ SPECIAL|EVENT | | | |FLAGS | | |VSPACE | | |
13105 |
++ | 48| 49| 50| 51| 52| 53| | 54| 55| |
13106 |
++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ |
13107 |
++ SPECIAL|DEBUG | | | |RLIMIT |SYSCALL| | |COMPAT | |
13108 |
++ | 56| 57| 58| 59| 60|TEST 61| | 62| 63| |
13109 |
++ -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ |
13110 |
++ |
13111 |
++*/ |
13112 |
++ |
13113 |
++#define VC_CAT_VERSION 0 |
13114 |
++ |
13115 |
++#define VC_CAT_VSETUP 1 |
13116 |
++#define VC_CAT_VHOST 2 |
13117 |
++ |
13118 |
++#define VC_CAT_DEVICE 6 |
13119 |
++ |
13120 |
++#define VC_CAT_VPROC 9 |
13121 |
++#define VC_CAT_PROCALT 10 |
13122 |
++#define VC_CAT_PROCMIG 11 |
13123 |
++#define VC_CAT_PROCTRL 12 |
13124 |
++ |
13125 |
++#define VC_CAT_SCHED 14 |
13126 |
++#define VC_CAT_MEMCTRL 20 |
13127 |
++ |
13128 |
++#define VC_CAT_VNET 25 |
13129 |
++#define VC_CAT_NETALT 26 |
13130 |
++#define VC_CAT_NETMIG 27 |
13131 |
++#define VC_CAT_NETCTRL 28 |
13132 |
++ |
13133 |
++#define VC_CAT_TAGMIG 35 |
13134 |
++#define VC_CAT_DLIMIT 36 |
13135 |
++#define VC_CAT_INODE 38 |
13136 |
++ |
13137 |
++#define VC_CAT_VSTAT 40 |
13138 |
++#define VC_CAT_VINFO 46 |
13139 |
++#define VC_CAT_EVENT 48 |
13140 |
++ |
13141 |
++#define VC_CAT_FLAGS 52 |
13142 |
++#define VC_CAT_VSPACE 54 |
13143 |
++#define VC_CAT_DEBUG 56 |
13144 |
++#define VC_CAT_RLIMIT 60 |
13145 |
++ |
13146 |
++#define VC_CAT_SYSTEST 61 |
13147 |
++#define VC_CAT_COMPAT 63 |
13148 |
++ |
13149 |
++/* query version */ |
13150 |
++ |
13151 |
++#define VCMD_get_version VC_CMD(VERSION, 0, 0) |
13152 |
++#define VCMD_get_vci VC_CMD(VERSION, 1, 0) |
13153 |
++ |
13154 |
++ |
13155 |
++#ifdef __KERNEL__ |
13156 |
++ |
13157 |
++#include <linux/errno.h> |
13158 |
++ |
13159 |
++#endif /* __KERNEL__ */ |
13160 |
++ |
13161 |
++#endif /* _VX_SWITCH_H */ |
13162 |
++ |
13163 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/tag_cmd.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/tag_cmd.h |
13164 |
+--- linux-2.6.29.4/include/linux/vserver/tag_cmd.h 1970-01-01 01:00:00.000000000 +0100 |
13165 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/tag_cmd.h 2009-02-22 22:54:26.000000000 +0100 |
13166 |
+@@ -0,0 +1,22 @@ |
13167 |
++#ifndef _VX_TAG_CMD_H |
13168 |
++#define _VX_TAG_CMD_H |
13169 |
++ |
13170 |
++ |
13171 |
++/* vinfo commands */ |
13172 |
++ |
13173 |
++#define VCMD_task_tag VC_CMD(VINFO, 3, 0) |
13174 |
++ |
13175 |
++#ifdef __KERNEL__ |
13176 |
++extern int vc_task_tag(uint32_t); |
13177 |
++ |
13178 |
++#endif /* __KERNEL__ */ |
13179 |
++ |
13180 |
++/* context commands */ |
13181 |
++ |
13182 |
++#define VCMD_tag_migrate VC_CMD(TAGMIG, 1, 0) |
13183 |
++ |
13184 |
++#ifdef __KERNEL__ |
13185 |
++extern int vc_tag_migrate(uint32_t); |
13186 |
++ |
13187 |
++#endif /* __KERNEL__ */ |
13188 |
++#endif /* _VX_TAG_CMD_H */ |
13189 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vserver/tag.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/tag.h |
13190 |
+--- linux-2.6.29.4/include/linux/vserver/tag.h 1970-01-01 01:00:00.000000000 +0100 |
13191 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vserver/tag.h 2009-02-22 22:54:26.000000000 +0100 |
13192 |
+@@ -0,0 +1,143 @@ |
13193 |
++#ifndef _DX_TAG_H |
13194 |
++#define _DX_TAG_H |
13195 |
++ |
13196 |
++#include <linux/types.h> |
13197 |
++ |
13198 |
++ |
13199 |
++#define DX_TAG(in) (IS_TAGGED(in)) |
13200 |
++ |
13201 |
++ |
13202 |
++#ifdef CONFIG_TAG_NFSD |
13203 |
++#define DX_TAG_NFSD 1 |
13204 |
++#else |
13205 |
++#define DX_TAG_NFSD 0 |
13206 |
++#endif |
13207 |
++ |
13208 |
++ |
13209 |
++#ifdef CONFIG_TAGGING_NONE |
13210 |
++ |
13211 |
++#define MAX_UID 0xFFFFFFFF |
13212 |
++#define MAX_GID 0xFFFFFFFF |
13213 |
++ |
13214 |
++#define INOTAG_TAG(cond, uid, gid, tag) (0) |
13215 |
++ |
13216 |
++#define TAGINO_UID(cond, uid, tag) (uid) |
13217 |
++#define TAGINO_GID(cond, gid, tag) (gid) |
13218 |
++ |
13219 |
++#endif |
13220 |
++ |
13221 |
++ |
13222 |
++#ifdef CONFIG_TAGGING_GID16 |
13223 |
++ |
13224 |
++#define MAX_UID 0xFFFFFFFF |
13225 |
++#define MAX_GID 0x0000FFFF |
13226 |
++ |
13227 |
++#define INOTAG_TAG(cond, uid, gid, tag) \ |
13228 |
++ ((cond) ? (((gid) >> 16) & 0xFFFF) : 0) |
13229 |
++ |
13230 |
++#define TAGINO_UID(cond, uid, tag) (uid) |
13231 |
++#define TAGINO_GID(cond, gid, tag) \ |
13232 |
++ ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid)) |
13233 |
++ |
13234 |
++#endif |
13235 |
++ |
13236 |
++ |
13237 |
++#ifdef CONFIG_TAGGING_ID24 |
13238 |
++ |
13239 |
++#define MAX_UID 0x00FFFFFF |
13240 |
++#define MAX_GID 0x00FFFFFF |
13241 |
++ |
13242 |
++#define INOTAG_TAG(cond, uid, gid, tag) \ |
13243 |
++ ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0) |
13244 |
++ |
13245 |
++#define TAGINO_UID(cond, uid, tag) \ |
13246 |
++ ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid)) |
13247 |
++#define TAGINO_GID(cond, gid, tag) \ |
13248 |
++ ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid)) |
13249 |
++ |
13250 |
++#endif |
13251 |
++ |
13252 |
++ |
13253 |
++#ifdef CONFIG_TAGGING_UID16 |
13254 |
++ |
13255 |
++#define MAX_UID 0x0000FFFF |
13256 |
++#define MAX_GID 0xFFFFFFFF |
13257 |
++ |
13258 |
++#define INOTAG_TAG(cond, uid, gid, tag) \ |
13259 |
++ ((cond) ? (((uid) >> 16) & 0xFFFF) : 0) |
13260 |
++ |
13261 |
++#define TAGINO_UID(cond, uid, tag) \ |
13262 |
++ ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid)) |
13263 |
++#define TAGINO_GID(cond, gid, tag) (gid) |
13264 |
++ |
13265 |
++#endif |
13266 |
++ |
13267 |
++ |
13268 |
++#ifdef CONFIG_TAGGING_INTERN |
13269 |
++ |
13270 |
++#define MAX_UID 0xFFFFFFFF |
13271 |
++#define MAX_GID 0xFFFFFFFF |
13272 |
++ |
13273 |
++#define INOTAG_TAG(cond, uid, gid, tag) \ |
13274 |
++ ((cond) ? (tag) : 0) |
13275 |
++ |
13276 |
++#define TAGINO_UID(cond, uid, tag) (uid) |
13277 |
++#define TAGINO_GID(cond, gid, tag) (gid) |
13278 |
++ |
13279 |
++#endif |
13280 |
++ |
13281 |
++ |
13282 |
++#ifndef CONFIG_TAGGING_NONE |
13283 |
++#define dx_current_fstag(sb) \ |
13284 |
++ ((sb)->s_flags & MS_TAGGED ? dx_current_tag() : 0) |
13285 |
++#else |
13286 |
++#define dx_current_fstag(sb) (0) |
13287 |
++#endif |
13288 |
++ |
13289 |
++#ifndef CONFIG_TAGGING_INTERN |
13290 |
++#define TAGINO_TAG(cond, tag) (0) |
13291 |
++#else |
13292 |
++#define TAGINO_TAG(cond, tag) ((cond) ? (tag) : 0) |
13293 |
++#endif |
13294 |
++ |
13295 |
++#define INOTAG_UID(cond, uid, gid) \ |
13296 |
++ ((cond) ? ((uid) & MAX_UID) : (uid)) |
13297 |
++#define INOTAG_GID(cond, uid, gid) \ |
13298 |
++ ((cond) ? ((gid) & MAX_GID) : (gid)) |
13299 |
++ |
13300 |
++ |
13301 |
++static inline uid_t dx_map_uid(uid_t uid) |
13302 |
++{ |
13303 |
++ if ((uid > MAX_UID) && (uid != -1)) |
13304 |
++ uid = -2; |
13305 |
++ return (uid & MAX_UID); |
13306 |
++} |
13307 |
++ |
13308 |
++static inline gid_t dx_map_gid(gid_t gid) |
13309 |
++{ |
13310 |
++ if ((gid > MAX_GID) && (gid != -1)) |
13311 |
++ gid = -2; |
13312 |
++ return (gid & MAX_GID); |
13313 |
++} |
13314 |
++ |
13315 |
++struct peer_tag { |
13316 |
++ int32_t xid; |
13317 |
++ int32_t nid; |
13318 |
++}; |
13319 |
++ |
13320 |
++#define dx_notagcheck(sb) ((sb) && ((sb)->s_flags & MS_NOTAGCHECK)) |
13321 |
++ |
13322 |
++int dx_parse_tag(char *string, tag_t *tag, int remove, int *mnt_flags, |
13323 |
++ unsigned long *flags); |
13324 |
++ |
13325 |
++#ifdef CONFIG_PROPAGATE |
13326 |
++ |
13327 |
++void __dx_propagate_tag(struct nameidata *nd, struct inode *inode); |
13328 |
++ |
13329 |
++#define dx_propagate_tag(n, i) __dx_propagate_tag(n, i) |
13330 |
++ |
13331 |
++#else |
13332 |
++#define dx_propagate_tag(n, i) do { } while (0) |
13333 |
++#endif |
13334 |
++ |
13335 |
++#endif /* _DX_TAG_H */ |
13336 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_inet6.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_inet6.h |
13337 |
+--- linux-2.6.29.4/include/linux/vs_inet6.h 1970-01-01 01:00:00.000000000 +0100 |
13338 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_inet6.h 2009-03-25 00:46:50.000000000 +0100 |
13339 |
+@@ -0,0 +1,246 @@ |
13340 |
++#ifndef _VS_INET6_H |
13341 |
++#define _VS_INET6_H |
13342 |
++ |
13343 |
++#include "vserver/base.h" |
13344 |
++#include "vserver/network.h" |
13345 |
++#include "vserver/debug.h" |
13346 |
++ |
13347 |
++#include <net/ipv6.h> |
13348 |
++ |
13349 |
++#define NXAV6(a) &(a)->ip, &(a)->mask, (a)->prefix, (a)->type |
13350 |
++#define NXAV6_FMT "[%pI6/%pI6/%d:%04x]" |
13351 |
++ |
13352 |
++ |
13353 |
++#ifdef CONFIG_IPV6 |
13354 |
++ |
13355 |
++static inline |
13356 |
++int v6_addr_match(struct nx_addr_v6 *nxa, |
13357 |
++ const struct in6_addr *addr, uint16_t mask) |
13358 |
++{ |
13359 |
++ int ret = 0; |
13360 |
++ |
13361 |
++ switch (nxa->type & mask) { |
13362 |
++ case NXA_TYPE_MASK: |
13363 |
++ ret = ipv6_masked_addr_cmp(&nxa->ip, &nxa->mask, addr); |
13364 |
++ break; |
13365 |
++ case NXA_TYPE_ADDR: |
13366 |
++ ret = ipv6_addr_equal(&nxa->ip, addr); |
13367 |
++ break; |
13368 |
++ case NXA_TYPE_ANY: |
13369 |
++ ret = 1; |
13370 |
++ break; |
13371 |
++ } |
13372 |
++ vxdprintk(VXD_CBIT(net, 0), |
13373 |
++ "v6_addr_match(%p" NXAV6_FMT ",%pI6,%04x) = %d", |
13374 |
++ nxa, NXAV6(nxa), addr, mask, ret); |
13375 |
++ return ret; |
13376 |
++} |
13377 |
++ |
13378 |
++static inline |
13379 |
++int v6_addr_in_nx_info(struct nx_info *nxi, |
13380 |
++ const struct in6_addr *addr, uint16_t mask) |
13381 |
++{ |
13382 |
++ struct nx_addr_v6 *nxa; |
13383 |
++ int ret = 1; |
13384 |
++ |
13385 |
++ if (!nxi) |
13386 |
++ goto out; |
13387 |
++ for (nxa = &nxi->v6; nxa; nxa = nxa->next) |
13388 |
++ if (v6_addr_match(nxa, addr, mask)) |
13389 |
++ goto out; |
13390 |
++ ret = 0; |
13391 |
++out: |
13392 |
++ vxdprintk(VXD_CBIT(net, 0), |
13393 |
++ "v6_addr_in_nx_info(%p[#%u],%pI6,%04x) = %d", |
13394 |
++ nxi, nxi ? nxi->nx_id : 0, addr, mask, ret); |
13395 |
++ return ret; |
13396 |
++} |
13397 |
++ |
13398 |
++static inline |
13399 |
++int v6_nx_addr_match(struct nx_addr_v6 *nxa, struct nx_addr_v6 *addr, uint16_t mask) |
13400 |
++{ |
13401 |
++ /* FIXME: needs full range checks */ |
13402 |
++ return v6_addr_match(nxa, &addr->ip, mask); |
13403 |
++} |
13404 |
++ |
13405 |
++static inline |
13406 |
++int v6_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v6 *nxa, uint16_t mask) |
13407 |
++{ |
13408 |
++ struct nx_addr_v6 *ptr; |
13409 |
++ |
13410 |
++ for (ptr = &nxi->v6; ptr; ptr = ptr->next) |
13411 |
++ if (v6_nx_addr_match(ptr, nxa, mask)) |
13412 |
++ return 1; |
13413 |
++ return 0; |
13414 |
++} |
13415 |
++ |
13416 |
++ |
13417 |
++/* |
13418 |
++ * Check if a given address matches for a socket |
13419 |
++ * |
13420 |
++ * nxi: the socket's nx_info if any |
13421 |
++ * addr: to be verified address |
13422 |
++ */ |
13423 |
++static inline |
13424 |
++int v6_sock_addr_match ( |
13425 |
++ struct nx_info *nxi, |
13426 |
++ struct inet_sock *inet, |
13427 |
++ struct in6_addr *addr) |
13428 |
++{ |
13429 |
++ struct sock *sk = &inet->sk; |
13430 |
++ struct in6_addr *saddr = inet6_rcv_saddr(sk); |
13431 |
++ |
13432 |
++ if (!ipv6_addr_any(addr) && |
13433 |
++ ipv6_addr_equal(saddr, addr)) |
13434 |
++ return 1; |
13435 |
++ if (ipv6_addr_any(saddr)) |
13436 |
++ return v6_addr_in_nx_info(nxi, addr, -1); |
13437 |
++ return 0; |
13438 |
++} |
13439 |
++ |
13440 |
++/* |
13441 |
++ * check if address is covered by socket |
13442 |
++ * |
13443 |
++ * sk: the socket to check against |
13444 |
++ * addr: the address in question (must be != 0) |
13445 |
++ */ |
13446 |
++ |
13447 |
++static inline |
13448 |
++int __v6_addr_match_socket(const struct sock *sk, struct nx_addr_v6 *nxa) |
13449 |
++{ |
13450 |
++ struct nx_info *nxi = sk->sk_nx_info; |
13451 |
++ struct in6_addr *saddr = inet6_rcv_saddr(sk); |
13452 |
++ |
13453 |
++ vxdprintk(VXD_CBIT(net, 5), |
13454 |
++ "__v6_addr_in_socket(%p," NXAV6_FMT ") %p:%pI6 %p;%lx", |
13455 |
++ sk, NXAV6(nxa), nxi, saddr, sk->sk_socket, |
13456 |
++ (sk->sk_socket?sk->sk_socket->flags:0)); |
13457 |
++ |
13458 |
++ if (!ipv6_addr_any(saddr)) { /* direct address match */ |
13459 |
++ return v6_addr_match(nxa, saddr, -1); |
13460 |
++ } else if (nxi) { /* match against nx_info */ |
13461 |
++ return v6_nx_addr_in_nx_info(nxi, nxa, -1); |
13462 |
++ } else { /* unrestricted any socket */ |
13463 |
++ return 1; |
13464 |
++ } |
13465 |
++} |
13466 |
++ |
13467 |
++ |
13468 |
++/* inet related checks and helpers */ |
13469 |
++ |
13470 |
++ |
13471 |
++struct in_ifaddr; |
13472 |
++struct net_device; |
13473 |
++struct sock; |
13474 |
++ |
13475 |
++ |
13476 |
++#include <linux/netdevice.h> |
13477 |
++#include <linux/inetdevice.h> |
13478 |
++#include <net/inet_timewait_sock.h> |
13479 |
++ |
13480 |
++ |
13481 |
++int dev_in_nx_info(struct net_device *, struct nx_info *); |
13482 |
++int v6_dev_in_nx_info(struct net_device *, struct nx_info *); |
13483 |
++int nx_v6_addr_conflict(struct nx_info *, struct nx_info *); |
13484 |
++ |
13485 |
++ |
13486 |
++ |
13487 |
++static inline |
13488 |
++int v6_ifa_in_nx_info(struct inet6_ifaddr *ifa, struct nx_info *nxi) |
13489 |
++{ |
13490 |
++ if (!nxi) |
13491 |
++ return 1; |
13492 |
++ if (!ifa) |
13493 |
++ return 0; |
13494 |
++ return v6_addr_in_nx_info(nxi, &ifa->addr, -1); |
13495 |
++} |
13496 |
++ |
13497 |
++static inline |
13498 |
++int nx_v6_ifa_visible(struct nx_info *nxi, struct inet6_ifaddr *ifa) |
13499 |
++{ |
13500 |
++ vxdprintk(VXD_CBIT(net, 1), "nx_v6_ifa_visible(%p[#%u],%p) %d", |
13501 |
++ nxi, nxi ? nxi->nx_id : 0, ifa, |
13502 |
++ nxi ? v6_ifa_in_nx_info(ifa, nxi) : 0); |
13503 |
++ |
13504 |
++ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0)) |
13505 |
++ return 1; |
13506 |
++ if (v6_ifa_in_nx_info(ifa, nxi)) |
13507 |
++ return 1; |
13508 |
++ return 0; |
13509 |
++} |
13510 |
++ |
13511 |
++ |
13512 |
++struct nx_v6_sock_addr { |
13513 |
++ struct in6_addr saddr; /* Address used for validation */ |
13514 |
++ struct in6_addr baddr; /* Address used for socket bind */ |
13515 |
++}; |
13516 |
++ |
13517 |
++static inline |
13518 |
++int v6_map_sock_addr(struct inet_sock *inet, struct sockaddr_in6 *addr, |
13519 |
++ struct nx_v6_sock_addr *nsa) |
13520 |
++{ |
13521 |
++ // struct sock *sk = &inet->sk; |
13522 |
++ // struct nx_info *nxi = sk->sk_nx_info; |
13523 |
++ struct in6_addr saddr = addr->sin6_addr; |
13524 |
++ struct in6_addr baddr = saddr; |
13525 |
++ |
13526 |
++ nsa->saddr = saddr; |
13527 |
++ nsa->baddr = baddr; |
13528 |
++ return 0; |
13529 |
++} |
13530 |
++ |
13531 |
++static inline |
13532 |
++void v6_set_sock_addr(struct inet_sock *inet, struct nx_v6_sock_addr *nsa) |
13533 |
++{ |
13534 |
++ // struct sock *sk = &inet->sk; |
13535 |
++ // struct in6_addr *saddr = inet6_rcv_saddr(sk); |
13536 |
++ |
13537 |
++ // *saddr = nsa->baddr; |
13538 |
++ // inet->saddr = nsa->baddr; |
13539 |
++} |
13540 |
++ |
13541 |
++static inline |
13542 |
++int nx_info_has_v6(struct nx_info *nxi) |
13543 |
++{ |
13544 |
++ if (!nxi) |
13545 |
++ return 1; |
13546 |
++ if (NX_IPV6(nxi)) |
13547 |
++ return 1; |
13548 |
++ return 0; |
13549 |
++} |
13550 |
++ |
13551 |
++#else /* CONFIG_IPV6 */ |
13552 |
++ |
13553 |
++static inline |
13554 |
++int nx_v6_dev_visible(struct nx_info *n, struct net_device *d) |
13555 |
++{ |
13556 |
++ return 1; |
13557 |
++} |
13558 |
++ |
13559 |
++ |
13560 |
++static inline |
13561 |
++int nx_v6_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s) |
13562 |
++{ |
13563 |
++ return 1; |
13564 |
++} |
13565 |
++ |
13566 |
++static inline |
13567 |
++int v6_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n) |
13568 |
++{ |
13569 |
++ return 1; |
13570 |
++} |
13571 |
++ |
13572 |
++static inline |
13573 |
++int nx_info_has_v6(struct nx_info *nxi) |
13574 |
++{ |
13575 |
++ return 0; |
13576 |
++} |
13577 |
++ |
13578 |
++#endif /* CONFIG_IPV6 */ |
13579 |
++ |
13580 |
++#define current_nx_info_has_v6() \ |
13581 |
++ nx_info_has_v6(current_nx_info()) |
13582 |
++ |
13583 |
++#else |
13584 |
++#warning duplicate inclusion |
13585 |
++#endif |
13586 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_inet.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_inet.h |
13587 |
+--- linux-2.6.29.4/include/linux/vs_inet.h 1970-01-01 01:00:00.000000000 +0100 |
13588 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_inet.h 2009-02-22 22:54:26.000000000 +0100 |
13589 |
+@@ -0,0 +1,342 @@ |
13590 |
++#ifndef _VS_INET_H |
13591 |
++#define _VS_INET_H |
13592 |
++ |
13593 |
++#include "vserver/base.h" |
13594 |
++#include "vserver/network.h" |
13595 |
++#include "vserver/debug.h" |
13596 |
++ |
13597 |
++#define IPI_LOOPBACK htonl(INADDR_LOOPBACK) |
13598 |
++ |
13599 |
++#define NXAV4(a) NIPQUAD((a)->ip[0]), NIPQUAD((a)->ip[1]), \ |
13600 |
++ NIPQUAD((a)->mask), (a)->type |
13601 |
++#define NXAV4_FMT "[" NIPQUAD_FMT "-" NIPQUAD_FMT "/" NIPQUAD_FMT ":%04x]" |
13602 |
++ |
13603 |
++ |
13604 |
++static inline |
13605 |
++int v4_addr_match(struct nx_addr_v4 *nxa, __be32 addr, uint16_t tmask) |
13606 |
++{ |
13607 |
++ __be32 ip = nxa->ip[0].s_addr; |
13608 |
++ __be32 mask = nxa->mask.s_addr; |
13609 |
++ __be32 bcast = ip | ~mask; |
13610 |
++ int ret = 0; |
13611 |
++ |
13612 |
++ switch (nxa->type & tmask) { |
13613 |
++ case NXA_TYPE_MASK: |
13614 |
++ ret = (ip == (addr & mask)); |
13615 |
++ break; |
13616 |
++ case NXA_TYPE_ADDR: |
13617 |
++ ret = 3; |
13618 |
++ if (addr == ip) |
13619 |
++ break; |
13620 |
++ /* fall through to broadcast */ |
13621 |
++ case NXA_MOD_BCAST: |
13622 |
++ ret = ((tmask & NXA_MOD_BCAST) && (addr == bcast)); |
13623 |
++ break; |
13624 |
++ case NXA_TYPE_RANGE: |
13625 |
++ ret = ((nxa->ip[0].s_addr <= addr) && |
13626 |
++ (nxa->ip[1].s_addr > addr)); |
13627 |
++ break; |
13628 |
++ case NXA_TYPE_ANY: |
13629 |
++ ret = 2; |
13630 |
++ break; |
13631 |
++ } |
13632 |
++ |
13633 |
++ vxdprintk(VXD_CBIT(net, 0), |
13634 |
++ "v4_addr_match(%p" NXAV4_FMT "," NIPQUAD_FMT ",%04x) = %d", |
13635 |
++ nxa, NXAV4(nxa), NIPQUAD(addr), tmask, ret); |
13636 |
++ return ret; |
13637 |
++} |
13638 |
++ |
13639 |
++static inline |
13640 |
++int v4_addr_in_nx_info(struct nx_info *nxi, __be32 addr, uint16_t tmask) |
13641 |
++{ |
13642 |
++ struct nx_addr_v4 *nxa; |
13643 |
++ int ret = 1; |
13644 |
++ |
13645 |
++ if (!nxi) |
13646 |
++ goto out; |
13647 |
++ |
13648 |
++ ret = 2; |
13649 |
++ /* allow 127.0.0.1 when remapping lback */ |
13650 |
++ if ((tmask & NXA_LOOPBACK) && |
13651 |
++ (addr == IPI_LOOPBACK) && |
13652 |
++ nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) |
13653 |
++ goto out; |
13654 |
++ ret = 3; |
13655 |
++ /* check for lback address */ |
13656 |
++ if ((tmask & NXA_MOD_LBACK) && |
13657 |
++ (nxi->v4_lback.s_addr == addr)) |
13658 |
++ goto out; |
13659 |
++ ret = 4; |
13660 |
++ /* check for broadcast address */ |
13661 |
++ if ((tmask & NXA_MOD_BCAST) && |
13662 |
++ (nxi->v4_bcast.s_addr == addr)) |
13663 |
++ goto out; |
13664 |
++ ret = 5; |
13665 |
++ /* check for v4 addresses */ |
13666 |
++ for (nxa = &nxi->v4; nxa; nxa = nxa->next) |
13667 |
++ if (v4_addr_match(nxa, addr, tmask)) |
13668 |
++ goto out; |
13669 |
++ ret = 0; |
13670 |
++out: |
13671 |
++ vxdprintk(VXD_CBIT(net, 0), |
13672 |
++ "v4_addr_in_nx_info(%p[#%u]," NIPQUAD_FMT ",%04x) = %d", |
13673 |
++ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(addr), tmask, ret); |
13674 |
++ return ret; |
13675 |
++} |
13676 |
++ |
13677 |
++static inline |
13678 |
++int v4_nx_addr_match(struct nx_addr_v4 *nxa, struct nx_addr_v4 *addr, uint16_t mask) |
13679 |
++{ |
13680 |
++ /* FIXME: needs full range checks */ |
13681 |
++ return v4_addr_match(nxa, addr->ip[0].s_addr, mask); |
13682 |
++} |
13683 |
++ |
13684 |
++static inline |
13685 |
++int v4_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v4 *nxa, uint16_t mask) |
13686 |
++{ |
13687 |
++ struct nx_addr_v4 *ptr; |
13688 |
++ |
13689 |
++ for (ptr = &nxi->v4; ptr; ptr = ptr->next) |
13690 |
++ if (v4_nx_addr_match(ptr, nxa, mask)) |
13691 |
++ return 1; |
13692 |
++ return 0; |
13693 |
++} |
13694 |
++ |
13695 |
++#include <net/inet_sock.h> |
13696 |
++ |
13697 |
++/* |
13698 |
++ * Check if a given address matches for a socket |
13699 |
++ * |
13700 |
++ * nxi: the socket's nx_info if any |
13701 |
++ * addr: to be verified address |
13702 |
++ */ |
13703 |
++static inline |
13704 |
++int v4_sock_addr_match ( |
13705 |
++ struct nx_info *nxi, |
13706 |
++ struct inet_sock *inet, |
13707 |
++ __be32 addr) |
13708 |
++{ |
13709 |
++ __be32 saddr = inet->rcv_saddr; |
13710 |
++ __be32 bcast = nxi ? nxi->v4_bcast.s_addr : INADDR_BROADCAST; |
13711 |
++ |
13712 |
++ if (addr && (saddr == addr || bcast == addr)) |
13713 |
++ return 1; |
13714 |
++ if (!saddr) |
13715 |
++ return v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND); |
13716 |
++ return 0; |
13717 |
++} |
13718 |
++ |
13719 |
++ |
13720 |
++/* inet related checks and helpers */ |
13721 |
++ |
13722 |
++ |
13723 |
++struct in_ifaddr; |
13724 |
++struct net_device; |
13725 |
++struct sock; |
13726 |
++ |
13727 |
++#ifdef CONFIG_INET |
13728 |
++ |
13729 |
++#include <linux/netdevice.h> |
13730 |
++#include <linux/inetdevice.h> |
13731 |
++#include <net/inet_sock.h> |
13732 |
++#include <net/inet_timewait_sock.h> |
13733 |
++ |
13734 |
++ |
13735 |
++int dev_in_nx_info(struct net_device *, struct nx_info *); |
13736 |
++int v4_dev_in_nx_info(struct net_device *, struct nx_info *); |
13737 |
++int nx_v4_addr_conflict(struct nx_info *, struct nx_info *); |
13738 |
++ |
13739 |
++ |
13740 |
++/* |
13741 |
++ * check if address is covered by socket |
13742 |
++ * |
13743 |
++ * sk: the socket to check against |
13744 |
++ * addr: the address in question (must be != 0) |
13745 |
++ */ |
13746 |
++ |
13747 |
++static inline |
13748 |
++int __v4_addr_match_socket(const struct sock *sk, struct nx_addr_v4 *nxa) |
13749 |
++{ |
13750 |
++ struct nx_info *nxi = sk->sk_nx_info; |
13751 |
++ __be32 saddr = inet_rcv_saddr(sk); |
13752 |
++ |
13753 |
++ vxdprintk(VXD_CBIT(net, 5), |
13754 |
++ "__v4_addr_in_socket(%p," NXAV4_FMT ") %p:" NIPQUAD_FMT " %p;%lx", |
13755 |
++ sk, NXAV4(nxa), nxi, NIPQUAD(saddr), sk->sk_socket, |
13756 |
++ (sk->sk_socket?sk->sk_socket->flags:0)); |
13757 |
++ |
13758 |
++ if (saddr) { /* direct address match */ |
13759 |
++ return v4_addr_match(nxa, saddr, -1); |
13760 |
++ } else if (nxi) { /* match against nx_info */ |
13761 |
++ return v4_nx_addr_in_nx_info(nxi, nxa, -1); |
13762 |
++ } else { /* unrestricted any socket */ |
13763 |
++ return 1; |
13764 |
++ } |
13765 |
++} |
13766 |
++ |
13767 |
++ |
13768 |
++ |
13769 |
++static inline |
13770 |
++int nx_dev_visible(struct nx_info *nxi, struct net_device *dev) |
13771 |
++{ |
13772 |
++ vxdprintk(VXD_CBIT(net, 1), "nx_dev_visible(%p[#%u],%p »%s«) %d", |
13773 |
++ nxi, nxi ? nxi->nx_id : 0, dev, dev->name, |
13774 |
++ nxi ? dev_in_nx_info(dev, nxi) : 0); |
13775 |
++ |
13776 |
++ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0)) |
13777 |
++ return 1; |
13778 |
++ if (dev_in_nx_info(dev, nxi)) |
13779 |
++ return 1; |
13780 |
++ return 0; |
13781 |
++} |
13782 |
++ |
13783 |
++ |
13784 |
++static inline |
13785 |
++int v4_ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi) |
13786 |
++{ |
13787 |
++ if (!nxi) |
13788 |
++ return 1; |
13789 |
++ if (!ifa) |
13790 |
++ return 0; |
13791 |
++ return v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW); |
13792 |
++} |
13793 |
++ |
13794 |
++static inline |
13795 |
++int nx_v4_ifa_visible(struct nx_info *nxi, struct in_ifaddr *ifa) |
13796 |
++{ |
13797 |
++ vxdprintk(VXD_CBIT(net, 1), "nx_v4_ifa_visible(%p[#%u],%p) %d", |
13798 |
++ nxi, nxi ? nxi->nx_id : 0, ifa, |
13799 |
++ nxi ? v4_ifa_in_nx_info(ifa, nxi) : 0); |
13800 |
++ |
13801 |
++ if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0)) |
13802 |
++ return 1; |
13803 |
++ if (v4_ifa_in_nx_info(ifa, nxi)) |
13804 |
++ return 1; |
13805 |
++ return 0; |
13806 |
++} |
13807 |
++ |
13808 |
++ |
13809 |
++struct nx_v4_sock_addr { |
13810 |
++ __be32 saddr; /* Address used for validation */ |
13811 |
++ __be32 baddr; /* Address used for socket bind */ |
13812 |
++}; |
13813 |
++ |
13814 |
++static inline |
13815 |
++int v4_map_sock_addr(struct inet_sock *inet, struct sockaddr_in *addr, |
13816 |
++ struct nx_v4_sock_addr *nsa) |
13817 |
++{ |
13818 |
++ struct sock *sk = &inet->sk; |
13819 |
++ struct nx_info *nxi = sk->sk_nx_info; |
13820 |
++ __be32 saddr = addr->sin_addr.s_addr; |
13821 |
++ __be32 baddr = saddr; |
13822 |
++ |
13823 |
++ vxdprintk(VXD_CBIT(net, 3), |
13824 |
++ "inet_bind(%p)* %p,%p;%lx " NIPQUAD_FMT, |
13825 |
++ sk, sk->sk_nx_info, sk->sk_socket, |
13826 |
++ (sk->sk_socket ? sk->sk_socket->flags : 0), |
13827 |
++ NIPQUAD(saddr)); |
13828 |
++ |
13829 |
++ if (nxi) { |
13830 |
++ if (saddr == INADDR_ANY) { |
13831 |
++ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0)) |
13832 |
++ baddr = nxi->v4.ip[0].s_addr; |
13833 |
++ } else if (saddr == IPI_LOOPBACK) { |
13834 |
++ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) |
13835 |
++ baddr = nxi->v4_lback.s_addr; |
13836 |
++ } else { /* normal address bind */ |
13837 |
++ if (!v4_addr_in_nx_info(nxi, saddr, NXA_MASK_BIND)) |
13838 |
++ return -EADDRNOTAVAIL; |
13839 |
++ } |
13840 |
++ } |
13841 |
++ |
13842 |
++ vxdprintk(VXD_CBIT(net, 3), |
13843 |
++ "inet_bind(%p) " NIPQUAD_FMT ", " NIPQUAD_FMT, |
13844 |
++ sk, NIPQUAD(saddr), NIPQUAD(baddr)); |
13845 |
++ |
13846 |
++ nsa->saddr = saddr; |
13847 |
++ nsa->baddr = baddr; |
13848 |
++ return 0; |
13849 |
++} |
13850 |
++ |
13851 |
++static inline |
13852 |
++void v4_set_sock_addr(struct inet_sock *inet, struct nx_v4_sock_addr *nsa) |
13853 |
++{ |
13854 |
++ inet->saddr = nsa->baddr; |
13855 |
++ inet->rcv_saddr = nsa->baddr; |
13856 |
++} |
13857 |
++ |
13858 |
++ |
13859 |
++/* |
13860 |
++ * helper to simplify inet_lookup_listener |
13861 |
++ * |
13862 |
++ * nxi: the socket's nx_info if any |
13863 |
++ * addr: to be verified address |
13864 |
++ * saddr: socket address |
13865 |
++ */ |
13866 |
++static inline int v4_inet_addr_match ( |
13867 |
++ struct nx_info *nxi, |
13868 |
++ __be32 addr, |
13869 |
++ __be32 saddr) |
13870 |
++{ |
13871 |
++ if (addr && (saddr == addr)) |
13872 |
++ return 1; |
13873 |
++ if (!saddr) |
13874 |
++ return nxi ? v4_addr_in_nx_info(nxi, addr, NXA_MASK_BIND) : 1; |
13875 |
++ return 0; |
13876 |
++} |
13877 |
++ |
13878 |
++static inline __be32 nx_map_sock_lback(struct nx_info *nxi, __be32 addr) |
13879 |
++{ |
13880 |
++ if (nx_info_flags(nxi, NXF_HIDE_LBACK, 0) && |
13881 |
++ (addr == nxi->v4_lback.s_addr)) |
13882 |
++ return IPI_LOOPBACK; |
13883 |
++ return addr; |
13884 |
++} |
13885 |
++ |
13886 |
++static inline |
13887 |
++int nx_info_has_v4(struct nx_info *nxi) |
13888 |
++{ |
13889 |
++ if (!nxi) |
13890 |
++ return 1; |
13891 |
++ if (NX_IPV4(nxi)) |
13892 |
++ return 1; |
13893 |
++ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) |
13894 |
++ return 1; |
13895 |
++ return 0; |
13896 |
++} |
13897 |
++ |
13898 |
++#else /* CONFIG_INET */ |
13899 |
++ |
13900 |
++static inline |
13901 |
++int nx_dev_visible(struct nx_info *n, struct net_device *d) |
13902 |
++{ |
13903 |
++ return 1; |
13904 |
++} |
13905 |
++ |
13906 |
++static inline |
13907 |
++int nx_v4_addr_conflict(struct nx_info *n, uint32_t a, const struct sock *s) |
13908 |
++{ |
13909 |
++ return 1; |
13910 |
++} |
13911 |
++ |
13912 |
++static inline |
13913 |
++int v4_ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n) |
13914 |
++{ |
13915 |
++ return 1; |
13916 |
++} |
13917 |
++ |
13918 |
++static inline |
13919 |
++int nx_info_has_v4(struct nx_info *nxi) |
13920 |
++{ |
13921 |
++ return 0; |
13922 |
++} |
13923 |
++ |
13924 |
++#endif /* CONFIG_INET */ |
13925 |
++ |
13926 |
++#define current_nx_info_has_v4() \ |
13927 |
++ nx_info_has_v4(current_nx_info()) |
13928 |
++ |
13929 |
++#else |
13930 |
++// #warning duplicate inclusion |
13931 |
++#endif |
13932 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_limit.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_limit.h |
13933 |
+--- linux-2.6.29.4/include/linux/vs_limit.h 1970-01-01 01:00:00.000000000 +0100 |
13934 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_limit.h 2009-02-22 22:54:26.000000000 +0100 |
13935 |
+@@ -0,0 +1,140 @@ |
13936 |
++#ifndef _VS_LIMIT_H |
13937 |
++#define _VS_LIMIT_H |
13938 |
++ |
13939 |
++#include "vserver/limit.h" |
13940 |
++#include "vserver/base.h" |
13941 |
++#include "vserver/context.h" |
13942 |
++#include "vserver/debug.h" |
13943 |
++#include "vserver/context.h" |
13944 |
++#include "vserver/limit_int.h" |
13945 |
++ |
13946 |
++ |
13947 |
++#define vx_acc_cres(v, d, p, r) \ |
13948 |
++ __vx_acc_cres(v, r, d, p, __FILE__, __LINE__) |
13949 |
++ |
13950 |
++#define vx_acc_cres_cond(x, d, p, r) \ |
13951 |
++ __vx_acc_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \ |
13952 |
++ r, d, p, __FILE__, __LINE__) |
13953 |
++ |
13954 |
++ |
13955 |
++#define vx_add_cres(v, a, p, r) \ |
13956 |
++ __vx_add_cres(v, r, a, p, __FILE__, __LINE__) |
13957 |
++#define vx_sub_cres(v, a, p, r) vx_add_cres(v, -(a), p, r) |
13958 |
++ |
13959 |
++#define vx_add_cres_cond(x, a, p, r) \ |
13960 |
++ __vx_add_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \ |
13961 |
++ r, a, p, __FILE__, __LINE__) |
13962 |
++#define vx_sub_cres_cond(x, a, p, r) vx_add_cres_cond(x, -(a), p, r) |
13963 |
++ |
13964 |
++ |
13965 |
++/* process and file limits */ |
13966 |
++ |
13967 |
++#define vx_nproc_inc(p) \ |
13968 |
++ vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC) |
13969 |
++ |
13970 |
++#define vx_nproc_dec(p) \ |
13971 |
++ vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC) |
13972 |
++ |
13973 |
++#define vx_files_inc(f) \ |
13974 |
++ vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE) |
13975 |
++ |
13976 |
++#define vx_files_dec(f) \ |
13977 |
++ vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE) |
13978 |
++ |
13979 |
++#define vx_locks_inc(l) \ |
13980 |
++ vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS) |
13981 |
++ |
13982 |
++#define vx_locks_dec(l) \ |
13983 |
++ vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS) |
13984 |
++ |
13985 |
++#define vx_openfd_inc(f) \ |
13986 |
++ vx_acc_cres(current->vx_info, 1, (void *)(long)(f), VLIMIT_OPENFD) |
13987 |
++ |
13988 |
++#define vx_openfd_dec(f) \ |
13989 |
++ vx_acc_cres(current->vx_info,-1, (void *)(long)(f), VLIMIT_OPENFD) |
13990 |
++ |
13991 |
++ |
13992 |
++#define vx_cres_avail(v, n, r) \ |
13993 |
++ __vx_cres_avail(v, r, n, __FILE__, __LINE__) |
13994 |
++ |
13995 |
++ |
13996 |
++#define vx_nproc_avail(n) \ |
13997 |
++ vx_cres_avail(current->vx_info, n, RLIMIT_NPROC) |
13998 |
++ |
13999 |
++#define vx_files_avail(n) \ |
14000 |
++ vx_cres_avail(current->vx_info, n, RLIMIT_NOFILE) |
14001 |
++ |
14002 |
++#define vx_locks_avail(n) \ |
14003 |
++ vx_cres_avail(current->vx_info, n, RLIMIT_LOCKS) |
14004 |
++ |
14005 |
++#define vx_openfd_avail(n) \ |
14006 |
++ vx_cres_avail(current->vx_info, n, VLIMIT_OPENFD) |
14007 |
++ |
14008 |
++ |
14009 |
++/* dentry limits */ |
14010 |
++ |
14011 |
++#define vx_dentry_inc(d) do { \ |
14012 |
++ if (atomic_read(&d->d_count) == 1) \ |
14013 |
++ vx_acc_cres(current->vx_info, 1, d, VLIMIT_DENTRY); \ |
14014 |
++ } while (0) |
14015 |
++ |
14016 |
++#define vx_dentry_dec(d) do { \ |
14017 |
++ if (atomic_read(&d->d_count) == 0) \ |
14018 |
++ vx_acc_cres(current->vx_info,-1, d, VLIMIT_DENTRY); \ |
14019 |
++ } while (0) |
14020 |
++ |
14021 |
++#define vx_dentry_avail(n) \ |
14022 |
++ vx_cres_avail(current->vx_info, n, VLIMIT_DENTRY) |
14023 |
++ |
14024 |
++ |
14025 |
++/* socket limits */ |
14026 |
++ |
14027 |
++#define vx_sock_inc(s) \ |
14028 |
++ vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK) |
14029 |
++ |
14030 |
++#define vx_sock_dec(s) \ |
14031 |
++ vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK) |
14032 |
++ |
14033 |
++#define vx_sock_avail(n) \ |
14034 |
++ vx_cres_avail(current->vx_info, n, VLIMIT_NSOCK) |
14035 |
++ |
14036 |
++ |
14037 |
++/* ipc resource limits */ |
14038 |
++ |
14039 |
++#define vx_ipcmsg_add(v, u, a) \ |
14040 |
++ vx_add_cres(v, a, u, RLIMIT_MSGQUEUE) |
14041 |
++ |
14042 |
++#define vx_ipcmsg_sub(v, u, a) \ |
14043 |
++ vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE) |
14044 |
++ |
14045 |
++#define vx_ipcmsg_avail(v, a) \ |
14046 |
++ vx_cres_avail(v, a, RLIMIT_MSGQUEUE) |
14047 |
++ |
14048 |
++ |
14049 |
++#define vx_ipcshm_add(v, k, a) \ |
14050 |
++ vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM) |
14051 |
++ |
14052 |
++#define vx_ipcshm_sub(v, k, a) \ |
14053 |
++ vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM) |
14054 |
++ |
14055 |
++#define vx_ipcshm_avail(v, a) \ |
14056 |
++ vx_cres_avail(v, a, VLIMIT_SHMEM) |
14057 |
++ |
14058 |
++ |
14059 |
++#define vx_semary_inc(a) \ |
14060 |
++ vx_acc_cres(current->vx_info, 1, a, VLIMIT_SEMARY) |
14061 |
++ |
14062 |
++#define vx_semary_dec(a) \ |
14063 |
++ vx_acc_cres(current->vx_info, -1, a, VLIMIT_SEMARY) |
14064 |
++ |
14065 |
++ |
14066 |
++#define vx_nsems_add(a,n) \ |
14067 |
++ vx_add_cres(current->vx_info, n, a, VLIMIT_NSEMS) |
14068 |
++ |
14069 |
++#define vx_nsems_sub(a,n) \ |
14070 |
++ vx_sub_cres(current->vx_info, n, a, VLIMIT_NSEMS) |
14071 |
++ |
14072 |
++ |
14073 |
++#else |
14074 |
++#warning duplicate inclusion |
14075 |
++#endif |
14076 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_memory.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_memory.h |
14077 |
+--- linux-2.6.29.4/include/linux/vs_memory.h 1970-01-01 01:00:00.000000000 +0100 |
14078 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_memory.h 2009-02-22 22:54:26.000000000 +0100 |
14079 |
+@@ -0,0 +1,159 @@ |
14080 |
++#ifndef _VS_MEMORY_H |
14081 |
++#define _VS_MEMORY_H |
14082 |
++ |
14083 |
++#include "vserver/limit.h" |
14084 |
++#include "vserver/base.h" |
14085 |
++#include "vserver/context.h" |
14086 |
++#include "vserver/debug.h" |
14087 |
++#include "vserver/context.h" |
14088 |
++#include "vserver/limit_int.h" |
14089 |
++ |
14090 |
++ |
14091 |
++#define __acc_add_long(a, v) (*(v) += (a)) |
14092 |
++#define __acc_inc_long(v) (++*(v)) |
14093 |
++#define __acc_dec_long(v) (--*(v)) |
14094 |
++ |
14095 |
++#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS |
14096 |
++#define __acc_add_atomic(a, v) atomic_long_add(a, v) |
14097 |
++#define __acc_inc_atomic(v) atomic_long_inc(v) |
14098 |
++#define __acc_dec_atomic(v) atomic_long_dec(v) |
14099 |
++#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ |
14100 |
++#define __acc_add_atomic(a, v) __acc_add_long(a, v) |
14101 |
++#define __acc_inc_atomic(v) __acc_inc_long(v) |
14102 |
++#define __acc_dec_atomic(v) __acc_dec_long(v) |
14103 |
++#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ |
14104 |
++ |
14105 |
++ |
14106 |
++#define vx_acc_page(m, d, v, r) do { \ |
14107 |
++ if ((d) > 0) \ |
14108 |
++ __acc_inc_long(&(m)->v); \ |
14109 |
++ else \ |
14110 |
++ __acc_dec_long(&(m)->v); \ |
14111 |
++ __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__); \ |
14112 |
++} while (0) |
14113 |
++ |
14114 |
++#define vx_acc_page_atomic(m, d, v, r) do { \ |
14115 |
++ if ((d) > 0) \ |
14116 |
++ __acc_inc_atomic(&(m)->v); \ |
14117 |
++ else \ |
14118 |
++ __acc_dec_atomic(&(m)->v); \ |
14119 |
++ __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__); \ |
14120 |
++} while (0) |
14121 |
++ |
14122 |
++ |
14123 |
++#define vx_acc_pages(m, p, v, r) do { \ |
14124 |
++ unsigned long __p = (p); \ |
14125 |
++ __acc_add_long(__p, &(m)->v); \ |
14126 |
++ __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__); \ |
14127 |
++} while (0) |
14128 |
++ |
14129 |
++#define vx_acc_pages_atomic(m, p, v, r) do { \ |
14130 |
++ unsigned long __p = (p); \ |
14131 |
++ __acc_add_atomic(__p, &(m)->v); \ |
14132 |
++ __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__); \ |
14133 |
++} while (0) |
14134 |
++ |
14135 |
++ |
14136 |
++ |
14137 |
++#define vx_acc_vmpage(m, d) \ |
14138 |
++ vx_acc_page(m, d, total_vm, RLIMIT_AS) |
14139 |
++#define vx_acc_vmlpage(m, d) \ |
14140 |
++ vx_acc_page(m, d, locked_vm, RLIMIT_MEMLOCK) |
14141 |
++#define vx_acc_file_rsspage(m, d) \ |
14142 |
++ vx_acc_page_atomic(m, d, _file_rss, VLIMIT_MAPPED) |
14143 |
++#define vx_acc_anon_rsspage(m, d) \ |
14144 |
++ vx_acc_page_atomic(m, d, _anon_rss, VLIMIT_ANON) |
14145 |
++ |
14146 |
++#define vx_acc_vmpages(m, p) \ |
14147 |
++ vx_acc_pages(m, p, total_vm, RLIMIT_AS) |
14148 |
++#define vx_acc_vmlpages(m, p) \ |
14149 |
++ vx_acc_pages(m, p, locked_vm, RLIMIT_MEMLOCK) |
14150 |
++#define vx_acc_file_rsspages(m, p) \ |
14151 |
++ vx_acc_pages_atomic(m, p, _file_rss, VLIMIT_MAPPED) |
14152 |
++#define vx_acc_anon_rsspages(m, p) \ |
14153 |
++ vx_acc_pages_atomic(m, p, _anon_rss, VLIMIT_ANON) |
14154 |
++ |
14155 |
++#define vx_pages_add(s, r, p) __vx_add_cres(s, r, p, 0, __FILE__, __LINE__) |
14156 |
++#define vx_pages_sub(s, r, p) vx_pages_add(s, r, -(p)) |
14157 |
++ |
14158 |
++#define vx_vmpages_inc(m) vx_acc_vmpage(m, 1) |
14159 |
++#define vx_vmpages_dec(m) vx_acc_vmpage(m, -1) |
14160 |
++#define vx_vmpages_add(m, p) vx_acc_vmpages(m, p) |
14161 |
++#define vx_vmpages_sub(m, p) vx_acc_vmpages(m, -(p)) |
14162 |
++ |
14163 |
++#define vx_vmlocked_inc(m) vx_acc_vmlpage(m, 1) |
14164 |
++#define vx_vmlocked_dec(m) vx_acc_vmlpage(m, -1) |
14165 |
++#define vx_vmlocked_add(m, p) vx_acc_vmlpages(m, p) |
14166 |
++#define vx_vmlocked_sub(m, p) vx_acc_vmlpages(m, -(p)) |
14167 |
++ |
14168 |
++#define vx_file_rsspages_inc(m) vx_acc_file_rsspage(m, 1) |
14169 |
++#define vx_file_rsspages_dec(m) vx_acc_file_rsspage(m, -1) |
14170 |
++#define vx_file_rsspages_add(m, p) vx_acc_file_rsspages(m, p) |
14171 |
++#define vx_file_rsspages_sub(m, p) vx_acc_file_rsspages(m, -(p)) |
14172 |
++ |
14173 |
++#define vx_anon_rsspages_inc(m) vx_acc_anon_rsspage(m, 1) |
14174 |
++#define vx_anon_rsspages_dec(m) vx_acc_anon_rsspage(m, -1) |
14175 |
++#define vx_anon_rsspages_add(m, p) vx_acc_anon_rsspages(m, p) |
14176 |
++#define vx_anon_rsspages_sub(m, p) vx_acc_anon_rsspages(m, -(p)) |
14177 |
++ |
14178 |
++ |
14179 |
++#define vx_pages_avail(m, p, r) \ |
14180 |
++ __vx_cres_avail((m)->mm_vx_info, r, p, __FILE__, __LINE__) |
14181 |
++ |
14182 |
++#define vx_vmpages_avail(m, p) vx_pages_avail(m, p, RLIMIT_AS) |
14183 |
++#define vx_vmlocked_avail(m, p) vx_pages_avail(m, p, RLIMIT_MEMLOCK) |
14184 |
++#define vx_anon_avail(m, p) vx_pages_avail(m, p, VLIMIT_ANON) |
14185 |
++#define vx_mapped_avail(m, p) vx_pages_avail(m, p, VLIMIT_MAPPED) |
14186 |
++ |
14187 |
++#define vx_rss_avail(m, p) \ |
14188 |
++ __vx_cres_array_avail((m)->mm_vx_info, VLA_RSS, p, __FILE__, __LINE__) |
14189 |
++ |
14190 |
++ |
14191 |
++enum { |
14192 |
++ VXPT_UNKNOWN = 0, |
14193 |
++ VXPT_ANON, |
14194 |
++ VXPT_NONE, |
14195 |
++ VXPT_FILE, |
14196 |
++ VXPT_SWAP, |
14197 |
++ VXPT_WRITE |
14198 |
++}; |
14199 |
++ |
14200 |
++#if 0 |
14201 |
++#define vx_page_fault(mm, vma, type, ret) |
14202 |
++#else |
14203 |
++ |
14204 |
++static inline |
14205 |
++void __vx_page_fault(struct mm_struct *mm, |
14206 |
++ struct vm_area_struct *vma, int type, int ret) |
14207 |
++{ |
14208 |
++ struct vx_info *vxi = mm->mm_vx_info; |
14209 |
++ int what; |
14210 |
++/* |
14211 |
++ static char *page_type[6] = |
14212 |
++ { "UNKNOWN", "ANON", "NONE", "FILE", "SWAP", "WRITE" }; |
14213 |
++ static char *page_what[4] = |
14214 |
++ { "FAULT_OOM", "FAULT_SIGBUS", "FAULT_MINOR", "FAULT_MAJOR" }; |
14215 |
++*/ |
14216 |
++ |
14217 |
++ if (!vxi) |
14218 |
++ return; |
14219 |
++ |
14220 |
++ what = (ret & 0x3); |
14221 |
++ |
14222 |
++/* printk("[%d] page[%d][%d] %2x %s %s\n", vxi->vx_id, |
14223 |
++ type, what, ret, page_type[type], page_what[what]); |
14224 |
++*/ |
14225 |
++ if (ret & VM_FAULT_WRITE) |
14226 |
++ what |= 0x4; |
14227 |
++ atomic_inc(&vxi->cacct.page[type][what]); |
14228 |
++} |
14229 |
++ |
14230 |
++#define vx_page_fault(mm, vma, type, ret) __vx_page_fault(mm, vma, type, ret) |
14231 |
++#endif |
14232 |
++ |
14233 |
++ |
14234 |
++extern unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm); |
14235 |
++ |
14236 |
++#else |
14237 |
++#warning duplicate inclusion |
14238 |
++#endif |
14239 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_network.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_network.h |
14240 |
+--- linux-2.6.29.4/include/linux/vs_network.h 1970-01-01 01:00:00.000000000 +0100 |
14241 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_network.h 2009-02-22 22:54:26.000000000 +0100 |
14242 |
+@@ -0,0 +1,169 @@ |
14243 |
++#ifndef _NX_VS_NETWORK_H |
14244 |
++#define _NX_VS_NETWORK_H |
14245 |
++ |
14246 |
++#include "vserver/context.h" |
14247 |
++#include "vserver/network.h" |
14248 |
++#include "vserver/base.h" |
14249 |
++#include "vserver/check.h" |
14250 |
++#include "vserver/debug.h" |
14251 |
++ |
14252 |
++#include <linux/sched.h> |
14253 |
++ |
14254 |
++ |
14255 |
++#define get_nx_info(i) __get_nx_info(i, __FILE__, __LINE__) |
14256 |
++ |
14257 |
++static inline struct nx_info *__get_nx_info(struct nx_info *nxi, |
14258 |
++ const char *_file, int _line) |
14259 |
++{ |
14260 |
++ if (!nxi) |
14261 |
++ return NULL; |
14262 |
++ |
14263 |
++ vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])", |
14264 |
++ nxi, nxi ? nxi->nx_id : 0, |
14265 |
++ nxi ? atomic_read(&nxi->nx_usecnt) : 0, |
14266 |
++ _file, _line); |
14267 |
++ |
14268 |
++ atomic_inc(&nxi->nx_usecnt); |
14269 |
++ return nxi; |
14270 |
++} |
14271 |
++ |
14272 |
++ |
14273 |
++extern void free_nx_info(struct nx_info *); |
14274 |
++ |
14275 |
++#define put_nx_info(i) __put_nx_info(i, __FILE__, __LINE__) |
14276 |
++ |
14277 |
++static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line) |
14278 |
++{ |
14279 |
++ if (!nxi) |
14280 |
++ return; |
14281 |
++ |
14282 |
++ vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])", |
14283 |
++ nxi, nxi ? nxi->nx_id : 0, |
14284 |
++ nxi ? atomic_read(&nxi->nx_usecnt) : 0, |
14285 |
++ _file, _line); |
14286 |
++ |
14287 |
++ if (atomic_dec_and_test(&nxi->nx_usecnt)) |
14288 |
++ free_nx_info(nxi); |
14289 |
++} |
14290 |
++ |
14291 |
++ |
14292 |
++#define init_nx_info(p, i) __init_nx_info(p, i, __FILE__, __LINE__) |
14293 |
++ |
14294 |
++static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi, |
14295 |
++ const char *_file, int _line) |
14296 |
++{ |
14297 |
++ if (nxi) { |
14298 |
++ vxlprintk(VXD_CBIT(nid, 3), |
14299 |
++ "init_nx_info(%p[#%d.%d])", |
14300 |
++ nxi, nxi ? nxi->nx_id : 0, |
14301 |
++ nxi ? atomic_read(&nxi->nx_usecnt) : 0, |
14302 |
++ _file, _line); |
14303 |
++ |
14304 |
++ atomic_inc(&nxi->nx_usecnt); |
14305 |
++ } |
14306 |
++ *nxp = nxi; |
14307 |
++} |
14308 |
++ |
14309 |
++ |
14310 |
++#define set_nx_info(p, i) __set_nx_info(p, i, __FILE__, __LINE__) |
14311 |
++ |
14312 |
++static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi, |
14313 |
++ const char *_file, int _line) |
14314 |
++{ |
14315 |
++ struct nx_info *nxo; |
14316 |
++ |
14317 |
++ if (!nxi) |
14318 |
++ return; |
14319 |
++ |
14320 |
++ vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])", |
14321 |
++ nxi, nxi ? nxi->nx_id : 0, |
14322 |
++ nxi ? atomic_read(&nxi->nx_usecnt) : 0, |
14323 |
++ _file, _line); |
14324 |
++ |
14325 |
++ atomic_inc(&nxi->nx_usecnt); |
14326 |
++ nxo = xchg(nxp, nxi); |
14327 |
++ BUG_ON(nxo); |
14328 |
++} |
14329 |
++ |
14330 |
++#define clr_nx_info(p) __clr_nx_info(p, __FILE__, __LINE__) |
14331 |
++ |
14332 |
++static inline void __clr_nx_info(struct nx_info **nxp, |
14333 |
++ const char *_file, int _line) |
14334 |
++{ |
14335 |
++ struct nx_info *nxo; |
14336 |
++ |
14337 |
++ nxo = xchg(nxp, NULL); |
14338 |
++ if (!nxo) |
14339 |
++ return; |
14340 |
++ |
14341 |
++ vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])", |
14342 |
++ nxo, nxo ? nxo->nx_id : 0, |
14343 |
++ nxo ? atomic_read(&nxo->nx_usecnt) : 0, |
14344 |
++ _file, _line); |
14345 |
++ |
14346 |
++ if (atomic_dec_and_test(&nxo->nx_usecnt)) |
14347 |
++ free_nx_info(nxo); |
14348 |
++} |
14349 |
++ |
14350 |
++ |
14351 |
++#define claim_nx_info(v, p) __claim_nx_info(v, p, __FILE__, __LINE__) |
14352 |
++ |
14353 |
++static inline void __claim_nx_info(struct nx_info *nxi, |
14354 |
++ struct task_struct *task, const char *_file, int _line) |
14355 |
++{ |
14356 |
++ vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p", |
14357 |
++ nxi, nxi ? nxi->nx_id : 0, |
14358 |
++ nxi?atomic_read(&nxi->nx_usecnt):0, |
14359 |
++ nxi?atomic_read(&nxi->nx_tasks):0, |
14360 |
++ task, _file, _line); |
14361 |
++ |
14362 |
++ atomic_inc(&nxi->nx_tasks); |
14363 |
++} |
14364 |
++ |
14365 |
++ |
14366 |
++extern void unhash_nx_info(struct nx_info *); |
14367 |
++ |
14368 |
++#define release_nx_info(v, p) __release_nx_info(v, p, __FILE__, __LINE__) |
14369 |
++ |
14370 |
++static inline void __release_nx_info(struct nx_info *nxi, |
14371 |
++ struct task_struct *task, const char *_file, int _line) |
14372 |
++{ |
14373 |
++ vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p", |
14374 |
++ nxi, nxi ? nxi->nx_id : 0, |
14375 |
++ nxi ? atomic_read(&nxi->nx_usecnt) : 0, |
14376 |
++ nxi ? atomic_read(&nxi->nx_tasks) : 0, |
14377 |
++ task, _file, _line); |
14378 |
++ |
14379 |
++ might_sleep(); |
14380 |
++ |
14381 |
++ if (atomic_dec_and_test(&nxi->nx_tasks)) |
14382 |
++ unhash_nx_info(nxi); |
14383 |
++} |
14384 |
++ |
14385 |
++ |
14386 |
++#define task_get_nx_info(i) __task_get_nx_info(i, __FILE__, __LINE__) |
14387 |
++ |
14388 |
++static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p, |
14389 |
++ const char *_file, int _line) |
14390 |
++{ |
14391 |
++ struct nx_info *nxi; |
14392 |
++ |
14393 |
++ task_lock(p); |
14394 |
++ vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)", |
14395 |
++ p, _file, _line); |
14396 |
++ nxi = __get_nx_info(p->nx_info, _file, _line); |
14397 |
++ task_unlock(p); |
14398 |
++ return nxi; |
14399 |
++} |
14400 |
++ |
14401 |
++ |
14402 |
++static inline void exit_nx_info(struct task_struct *p) |
14403 |
++{ |
14404 |
++ if (p->nx_info) |
14405 |
++ release_nx_info(p->nx_info, p); |
14406 |
++} |
14407 |
++ |
14408 |
++ |
14409 |
++#else |
14410 |
++#warning duplicate inclusion |
14411 |
++#endif |
14412 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_pid.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_pid.h |
14413 |
+--- linux-2.6.29.4/include/linux/vs_pid.h 1970-01-01 01:00:00.000000000 +0100 |
14414 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_pid.h 2009-02-22 22:54:26.000000000 +0100 |
14415 |
+@@ -0,0 +1,95 @@ |
14416 |
++#ifndef _VS_PID_H |
14417 |
++#define _VS_PID_H |
14418 |
++ |
14419 |
++#include "vserver/base.h" |
14420 |
++#include "vserver/check.h" |
14421 |
++#include "vserver/context.h" |
14422 |
++#include "vserver/debug.h" |
14423 |
++#include "vserver/pid.h" |
14424 |
++#include <linux/pid_namespace.h> |
14425 |
++ |
14426 |
++ |
14427 |
++#define VXF_FAKE_INIT (VXF_INFO_INIT | VXF_STATE_INIT) |
14428 |
++ |
14429 |
++static inline |
14430 |
++int vx_proc_task_visible(struct task_struct *task) |
14431 |
++{ |
14432 |
++ if ((task->pid == 1) && |
14433 |
++ !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT)) |
14434 |
++ /* show a blend through init */ |
14435 |
++ goto visible; |
14436 |
++ if (vx_check(vx_task_xid(task), VS_WATCH | VS_IDENT)) |
14437 |
++ goto visible; |
14438 |
++ return 0; |
14439 |
++visible: |
14440 |
++ return 1; |
14441 |
++} |
14442 |
++ |
14443 |
++#define find_task_by_real_pid(pid) find_task_by_pid_ns(pid, &init_pid_ns) |
14444 |
++ |
14445 |
++#if 0 |
14446 |
++ |
14447 |
++static inline |
14448 |
++struct task_struct *vx_find_proc_task_by_pid(int pid) |
14449 |
++{ |
14450 |
++ struct task_struct *task = find_task_by_real_pid(pid); |
14451 |
++ |
14452 |
++ if (task && !vx_proc_task_visible(task)) { |
14453 |
++ vxdprintk(VXD_CBIT(misc, 6), |
14454 |
++ "dropping task (find) %p[#%u,%u] for %p[#%u,%u]", |
14455 |
++ task, task->xid, task->pid, |
14456 |
++ current, current->xid, current->pid); |
14457 |
++ task = NULL; |
14458 |
++ } |
14459 |
++ return task; |
14460 |
++} |
14461 |
++ |
14462 |
++#endif |
14463 |
++ |
14464 |
++static inline |
14465 |
++struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid) |
14466 |
++{ |
14467 |
++ struct task_struct *task = get_pid_task(pid, PIDTYPE_PID); |
14468 |
++ |
14469 |
++ if (task && !vx_proc_task_visible(task)) { |
14470 |
++ vxdprintk(VXD_CBIT(misc, 6), |
14471 |
++ "dropping task (get) %p[#%u,%u] for %p[#%u,%u]", |
14472 |
++ task, task->xid, task->pid, |
14473 |
++ current, current->xid, current->pid); |
14474 |
++ put_task_struct(task); |
14475 |
++ task = NULL; |
14476 |
++ } |
14477 |
++ return task; |
14478 |
++} |
14479 |
++ |
14480 |
++#if 0 |
14481 |
++ |
14482 |
++static inline |
14483 |
++struct task_struct *vx_child_reaper(struct task_struct *p) |
14484 |
++{ |
14485 |
++ struct vx_info *vxi = p->vx_info; |
14486 |
++ struct task_struct *reaper = child_reaper(p); |
14487 |
++ |
14488 |
++ if (!vxi) |
14489 |
++ goto out; |
14490 |
++ |
14491 |
++ BUG_ON(!p->vx_info->vx_reaper); |
14492 |
++ |
14493 |
++ /* child reaper for the guest reaper */ |
14494 |
++ if (vxi->vx_reaper == p) |
14495 |
++ goto out; |
14496 |
++ |
14497 |
++ reaper = vxi->vx_reaper; |
14498 |
++out: |
14499 |
++ vxdprintk(VXD_CBIT(xid, 7), |
14500 |
++ "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]", |
14501 |
++ p, p->xid, p->pid, reaper, reaper->xid, reaper->pid); |
14502 |
++ return reaper; |
14503 |
++} |
14504 |
++ |
14505 |
++#endif |
14506 |
++ |
14507 |
++ |
14508 |
++#else |
14509 |
++#warning duplicate inclusion |
14510 |
++#endif |
14511 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_sched.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_sched.h |
14512 |
+--- linux-2.6.29.4/include/linux/vs_sched.h 1970-01-01 01:00:00.000000000 +0100 |
14513 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_sched.h 2009-02-22 22:54:26.000000000 +0100 |
14514 |
+@@ -0,0 +1,110 @@ |
14515 |
++#ifndef _VS_SCHED_H |
14516 |
++#define _VS_SCHED_H |
14517 |
++ |
14518 |
++#include "vserver/base.h" |
14519 |
++#include "vserver/context.h" |
14520 |
++#include "vserver/sched.h" |
14521 |
++ |
14522 |
++ |
14523 |
++#define VAVAVOOM_RATIO 50 |
14524 |
++ |
14525 |
++#define MAX_PRIO_BIAS 20 |
14526 |
++#define MIN_PRIO_BIAS -20 |
14527 |
++ |
14528 |
++ |
14529 |
++#ifdef CONFIG_VSERVER_HARDCPU |
14530 |
++ |
14531 |
++/* |
14532 |
++ * effective_prio - return the priority that is based on the static |
14533 |
++ * priority but is modified by bonuses/penalties. |
14534 |
++ * |
14535 |
++ * We scale the actual sleep average [0 .... MAX_SLEEP_AVG] |
14536 |
++ * into a -4 ... 0 ... +4 bonus/penalty range. |
14537 |
++ * |
14538 |
++ * Additionally, we scale another amount based on the number of |
14539 |
++ * CPU tokens currently held by the context, if the process is |
14540 |
++ * part of a context (and the appropriate SCHED flag is set). |
14541 |
++ * This ranges from -5 ... 0 ... +15, quadratically. |
14542 |
++ * |
14543 |
++ * So, the total bonus is -9 .. 0 .. +19 |
14544 |
++ * We use ~50% of the full 0...39 priority range so that: |
14545 |
++ * |
14546 |
++ * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs. |
14547 |
++ * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks. |
14548 |
++ * unless that context is far exceeding its CPU allocation. |
14549 |
++ * |
14550 |
++ * Both properties are important to certain workloads. |
14551 |
++ */ |
14552 |
++static inline |
14553 |
++int vx_effective_vavavoom(struct _vx_sched_pc *sched_pc, int max_prio) |
14554 |
++{ |
14555 |
++ int vavavoom, max; |
14556 |
++ |
14557 |
++ /* lots of tokens = lots of vavavoom |
14558 |
++ * no tokens = no vavavoom */ |
14559 |
++ if ((vavavoom = sched_pc->tokens) >= 0) { |
14560 |
++ max = sched_pc->tokens_max; |
14561 |
++ vavavoom = max - vavavoom; |
14562 |
++ max = max * max; |
14563 |
++ vavavoom = max_prio * VAVAVOOM_RATIO / 100 |
14564 |
++ * (vavavoom*vavavoom - (max >> 2)) / max; |
14565 |
++ return vavavoom; |
14566 |
++ } |
14567 |
++ return 0; |
14568 |
++} |
14569 |
++ |
14570 |
++ |
14571 |
++static inline |
14572 |
++int vx_adjust_prio(struct task_struct *p, int prio, int max_user) |
14573 |
++{ |
14574 |
++ struct vx_info *vxi = p->vx_info; |
14575 |
++ struct _vx_sched_pc *sched_pc; |
14576 |
++ |
14577 |
++ if (!vxi) |
14578 |
++ return prio; |
14579 |
++ |
14580 |
++ sched_pc = &vx_cpu(vxi, sched_pc); |
14581 |
++ if (vx_info_flags(vxi, VXF_SCHED_PRIO, 0)) { |
14582 |
++ int vavavoom = vx_effective_vavavoom(sched_pc, max_user); |
14583 |
++ |
14584 |
++ sched_pc->vavavoom = vavavoom; |
14585 |
++ prio += vavavoom; |
14586 |
++ } |
14587 |
++ prio += sched_pc->prio_bias; |
14588 |
++ return prio; |
14589 |
++} |
14590 |
++ |
14591 |
++#else /* !CONFIG_VSERVER_HARDCPU */ |
14592 |
++ |
14593 |
++static inline |
14594 |
++int vx_adjust_prio(struct task_struct *p, int prio, int max_user) |
14595 |
++{ |
14596 |
++ struct vx_info *vxi = p->vx_info; |
14597 |
++ |
14598 |
++ if (vxi) |
14599 |
++ prio += vx_cpu(vxi, sched_pc).prio_bias; |
14600 |
++ return prio; |
14601 |
++} |
14602 |
++ |
14603 |
++#endif /* CONFIG_VSERVER_HARDCPU */ |
14604 |
++ |
14605 |
++ |
14606 |
++static inline void vx_account_user(struct vx_info *vxi, |
14607 |
++ cputime_t cputime, int nice) |
14608 |
++{ |
14609 |
++ if (!vxi) |
14610 |
++ return; |
14611 |
++ vx_cpu(vxi, sched_pc).user_ticks += cputime; |
14612 |
++} |
14613 |
++ |
14614 |
++static inline void vx_account_system(struct vx_info *vxi, |
14615 |
++ cputime_t cputime, int idle) |
14616 |
++{ |
14617 |
++ if (!vxi) |
14618 |
++ return; |
14619 |
++ vx_cpu(vxi, sched_pc).sys_ticks += cputime; |
14620 |
++} |
14621 |
++ |
14622 |
++#else |
14623 |
++#warning duplicate inclusion |
14624 |
++#endif |
14625 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_socket.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_socket.h |
14626 |
+--- linux-2.6.29.4/include/linux/vs_socket.h 1970-01-01 01:00:00.000000000 +0100 |
14627 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_socket.h 2009-02-22 22:54:26.000000000 +0100 |
14628 |
+@@ -0,0 +1,67 @@ |
14629 |
++#ifndef _VS_SOCKET_H |
14630 |
++#define _VS_SOCKET_H |
14631 |
++ |
14632 |
++#include "vserver/debug.h" |
14633 |
++#include "vserver/base.h" |
14634 |
++#include "vserver/cacct.h" |
14635 |
++#include "vserver/context.h" |
14636 |
++#include "vserver/tag.h" |
14637 |
++ |
14638 |
++ |
14639 |
++/* socket accounting */ |
14640 |
++ |
14641 |
++#include <linux/socket.h> |
14642 |
++ |
14643 |
++static inline int vx_sock_type(int family) |
14644 |
++{ |
14645 |
++ switch (family) { |
14646 |
++ case PF_UNSPEC: |
14647 |
++ return VXA_SOCK_UNSPEC; |
14648 |
++ case PF_UNIX: |
14649 |
++ return VXA_SOCK_UNIX; |
14650 |
++ case PF_INET: |
14651 |
++ return VXA_SOCK_INET; |
14652 |
++ case PF_INET6: |
14653 |
++ return VXA_SOCK_INET6; |
14654 |
++ case PF_PACKET: |
14655 |
++ return VXA_SOCK_PACKET; |
14656 |
++ default: |
14657 |
++ return VXA_SOCK_OTHER; |
14658 |
++ } |
14659 |
++} |
14660 |
++ |
14661 |
++#define vx_acc_sock(v, f, p, s) \ |
14662 |
++ __vx_acc_sock(v, f, p, s, __FILE__, __LINE__) |
14663 |
++ |
14664 |
++static inline void __vx_acc_sock(struct vx_info *vxi, |
14665 |
++ int family, int pos, int size, char *file, int line) |
14666 |
++{ |
14667 |
++ if (vxi) { |
14668 |
++ int type = vx_sock_type(family); |
14669 |
++ |
14670 |
++ atomic_long_inc(&vxi->cacct.sock[type][pos].count); |
14671 |
++ atomic_long_add(size, &vxi->cacct.sock[type][pos].total); |
14672 |
++ } |
14673 |
++} |
14674 |
++ |
14675 |
++#define vx_sock_recv(sk, s) \ |
14676 |
++ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, s) |
14677 |
++#define vx_sock_send(sk, s) \ |
14678 |
++ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, s) |
14679 |
++#define vx_sock_fail(sk, s) \ |
14680 |
++ vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, s) |
14681 |
++ |
14682 |
++ |
14683 |
++#define sock_vx_init(s) do { \ |
14684 |
++ (s)->sk_xid = 0; \ |
14685 |
++ (s)->sk_vx_info = NULL; \ |
14686 |
++ } while (0) |
14687 |
++ |
14688 |
++#define sock_nx_init(s) do { \ |
14689 |
++ (s)->sk_nid = 0; \ |
14690 |
++ (s)->sk_nx_info = NULL; \ |
14691 |
++ } while (0) |
14692 |
++ |
14693 |
++#else |
14694 |
++#warning duplicate inclusion |
14695 |
++#endif |
14696 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_tag.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_tag.h |
14697 |
+--- linux-2.6.29.4/include/linux/vs_tag.h 1970-01-01 01:00:00.000000000 +0100 |
14698 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_tag.h 2009-02-22 22:54:26.000000000 +0100 |
14699 |
+@@ -0,0 +1,47 @@ |
14700 |
++#ifndef _VS_TAG_H |
14701 |
++#define _VS_TAG_H |
14702 |
++ |
14703 |
++#include <linux/vserver/tag.h> |
14704 |
++ |
14705 |
++/* check conditions */ |
14706 |
++ |
14707 |
++#define DX_ADMIN 0x0001 |
14708 |
++#define DX_WATCH 0x0002 |
14709 |
++#define DX_HOSTID 0x0008 |
14710 |
++ |
14711 |
++#define DX_IDENT 0x0010 |
14712 |
++ |
14713 |
++#define DX_ARG_MASK 0x0010 |
14714 |
++ |
14715 |
++ |
14716 |
++#define dx_task_tag(t) ((t)->tag) |
14717 |
++ |
14718 |
++#define dx_current_tag() dx_task_tag(current) |
14719 |
++ |
14720 |
++#define dx_check(c, m) __dx_check(dx_current_tag(), c, m) |
14721 |
++ |
14722 |
++#define dx_weak_check(c, m) ((m) ? dx_check(c, m) : 1) |
14723 |
++ |
14724 |
++ |
14725 |
++/* |
14726 |
++ * check current context for ADMIN/WATCH and |
14727 |
++ * optionally against supplied argument |
14728 |
++ */ |
14729 |
++static inline int __dx_check(tag_t cid, tag_t id, unsigned int mode) |
14730 |
++{ |
14731 |
++ if (mode & DX_ARG_MASK) { |
14732 |
++ if ((mode & DX_IDENT) && (id == cid)) |
14733 |
++ return 1; |
14734 |
++ } |
14735 |
++ return (((mode & DX_ADMIN) && (cid == 0)) || |
14736 |
++ ((mode & DX_WATCH) && (cid == 1)) || |
14737 |
++ ((mode & DX_HOSTID) && (id == 0))); |
14738 |
++} |
14739 |
++ |
14740 |
++struct inode; |
14741 |
++int dx_permission(struct inode *inode, int mask); |
14742 |
++ |
14743 |
++ |
14744 |
++#else |
14745 |
++#warning duplicate inclusion |
14746 |
++#endif |
14747 |
+diff -NurpP --minimal linux-2.6.29.4/include/linux/vs_time.h linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_time.h |
14748 |
+--- linux-2.6.29.4/include/linux/vs_time.h 1970-01-01 01:00:00.000000000 +0100 |
14749 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/linux/vs_time.h 2009-02-22 22:54:26.000000000 +0100 |
14750 |
+@@ -0,0 +1,19 @@ |
14751 |
++#ifndef _VS_TIME_H |
14752 |
++#define _VS_TIME_H |
14753 |
++ |
14754 |
++ |
14755 |
++/* time faking stuff */ |
14756 |
++ |
14757 |
++#ifdef CONFIG_VSERVER_VTIME |
14758 |
++ |
14759 |
++extern void vx_gettimeofday(struct timeval *tv); |
14760 |
++extern int vx_settimeofday(struct timespec *ts); |
14761 |
++ |
14762 |
++#else |
14763 |
++#define vx_gettimeofday(t) do_gettimeofday(t) |
14764 |
++#define vx_settimeofday(t) do_settimeofday(t) |
14765 |
++#endif |
14766 |
++ |
14767 |
++#else |
14768 |
++#warning duplicate inclusion |
14769 |
++#endif |
14770 |
+diff -NurpP --minimal linux-2.6.29.4/include/net/addrconf.h linux-2.6.29.4-vs2.3.0.36.14/include/net/addrconf.h |
14771 |
+--- linux-2.6.29.4/include/net/addrconf.h 2008-12-25 00:26:37.000000000 +0100 |
14772 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/net/addrconf.h 2009-02-22 22:54:26.000000000 +0100 |
14773 |
+@@ -84,7 +84,8 @@ extern int ipv6_dev_get_saddr(struct n |
14774 |
+ struct net_device *dev, |
14775 |
+ const struct in6_addr *daddr, |
14776 |
+ unsigned int srcprefs, |
14777 |
+- struct in6_addr *saddr); |
14778 |
++ struct in6_addr *saddr, |
14779 |
++ struct nx_info *nxi); |
14780 |
+ extern int ipv6_get_lladdr(struct net_device *dev, |
14781 |
+ struct in6_addr *addr, |
14782 |
+ unsigned char banned_flags); |
14783 |
+diff -NurpP --minimal linux-2.6.29.4/include/net/af_unix.h linux-2.6.29.4-vs2.3.0.36.14/include/net/af_unix.h |
14784 |
+--- linux-2.6.29.4/include/net/af_unix.h 2008-12-25 00:26:37.000000000 +0100 |
14785 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/net/af_unix.h 2009-02-22 22:54:26.000000000 +0100 |
14786 |
+@@ -4,6 +4,7 @@ |
14787 |
+ #include <linux/socket.h> |
14788 |
+ #include <linux/un.h> |
14789 |
+ #include <linux/mutex.h> |
14790 |
++#include <linux/vs_base.h> |
14791 |
+ #include <net/sock.h> |
14792 |
+ |
14793 |
+ extern void unix_inflight(struct file *fp); |
14794 |
+diff -NurpP --minimal linux-2.6.29.4/include/net/inet_timewait_sock.h linux-2.6.29.4-vs2.3.0.36.14/include/net/inet_timewait_sock.h |
14795 |
+--- linux-2.6.29.4/include/net/inet_timewait_sock.h 2009-03-24 14:22:44.000000000 +0100 |
14796 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/net/inet_timewait_sock.h 2009-03-24 14:48:36.000000000 +0100 |
14797 |
+@@ -15,15 +15,14 @@ |
14798 |
+ #ifndef _INET_TIMEWAIT_SOCK_ |
14799 |
+ #define _INET_TIMEWAIT_SOCK_ |
14800 |
+ |
14801 |
++// #include <net/inet_sock.h> |
14802 |
++#include <net/sock.h> |
14803 |
+ |
14804 |
+ #include <linux/list.h> |
14805 |
+ #include <linux/module.h> |
14806 |
+ #include <linux/timer.h> |
14807 |
+ #include <linux/types.h> |
14808 |
+ #include <linux/workqueue.h> |
14809 |
+- |
14810 |
+-#include <net/inet_sock.h> |
14811 |
+-#include <net/sock.h> |
14812 |
+ #include <net/tcp_states.h> |
14813 |
+ #include <net/timewait_sock.h> |
14814 |
+ |
14815 |
+@@ -116,6 +115,10 @@ struct inet_timewait_sock { |
14816 |
+ #define tw_hash __tw_common.skc_hash |
14817 |
+ #define tw_prot __tw_common.skc_prot |
14818 |
+ #define tw_net __tw_common.skc_net |
14819 |
++#define tw_xid __tw_common.skc_xid |
14820 |
++#define tw_vx_info __tw_common.skc_vx_info |
14821 |
++#define tw_nid __tw_common.skc_nid |
14822 |
++#define tw_nx_info __tw_common.skc_nx_info |
14823 |
+ int tw_timeout; |
14824 |
+ volatile unsigned char tw_substate; |
14825 |
+ /* 3 bits hole, try to pack */ |
14826 |
+diff -NurpP --minimal linux-2.6.29.4/include/net/route.h linux-2.6.29.4-vs2.3.0.36.14/include/net/route.h |
14827 |
+--- linux-2.6.29.4/include/net/route.h 2008-12-25 00:26:37.000000000 +0100 |
14828 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/net/route.h 2009-02-22 22:54:26.000000000 +0100 |
14829 |
+@@ -135,6 +135,9 @@ static inline void ip_rt_put(struct rtab |
14830 |
+ dst_release(&rt->u.dst); |
14831 |
+ } |
14832 |
+ |
14833 |
++#include <linux/vs_base.h> |
14834 |
++#include <linux/vs_inet.h> |
14835 |
++ |
14836 |
+ #define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3) |
14837 |
+ |
14838 |
+ extern const __u8 ip_tos2prio[16]; |
14839 |
+@@ -144,6 +147,9 @@ static inline char rt_tos2priority(u8 to |
14840 |
+ return ip_tos2prio[IPTOS_TOS(tos)>>1]; |
14841 |
+ } |
14842 |
+ |
14843 |
++extern int ip_v4_find_src(struct net *net, struct nx_info *, |
14844 |
++ struct rtable **, struct flowi *); |
14845 |
++ |
14846 |
+ static inline int ip_route_connect(struct rtable **rp, __be32 dst, |
14847 |
+ __be32 src, u32 tos, int oif, u8 protocol, |
14848 |
+ __be16 sport, __be16 dport, struct sock *sk, |
14849 |
+@@ -161,11 +167,24 @@ static inline int ip_route_connect(struc |
14850 |
+ |
14851 |
+ int err; |
14852 |
+ struct net *net = sock_net(sk); |
14853 |
++ struct nx_info *nx_info = current->nx_info; |
14854 |
+ |
14855 |
+ if (inet_sk(sk)->transparent) |
14856 |
+ fl.flags |= FLOWI_FLAG_ANYSRC; |
14857 |
+ |
14858 |
+- if (!dst || !src) { |
14859 |
++ if (sk) |
14860 |
++ nx_info = sk->sk_nx_info; |
14861 |
++ |
14862 |
++ vxdprintk(VXD_CBIT(net, 4), |
14863 |
++ "ip_route_connect(%p) %p,%p;%lx", |
14864 |
++ sk, nx_info, sk->sk_socket, |
14865 |
++ (sk->sk_socket?sk->sk_socket->flags:0)); |
14866 |
++ |
14867 |
++ err = ip_v4_find_src(net, nx_info, rp, &fl); |
14868 |
++ if (err) |
14869 |
++ return err; |
14870 |
++ |
14871 |
++ if (!fl.fl4_dst || !fl.fl4_src) { |
14872 |
+ err = __ip_route_output_key(net, rp, &fl); |
14873 |
+ if (err) |
14874 |
+ return err; |
14875 |
+diff -NurpP --minimal linux-2.6.29.4/include/net/sock.h linux-2.6.29.4-vs2.3.0.36.14/include/net/sock.h |
14876 |
+--- linux-2.6.29.4/include/net/sock.h 2009-03-24 14:22:44.000000000 +0100 |
14877 |
++++ linux-2.6.29.4-vs2.3.0.36.14/include/net/sock.h 2009-03-24 14:48:36.000000000 +0100 |
14878 |
+@@ -134,6 +134,10 @@ struct sock_common { |
14879 |
+ #ifdef CONFIG_NET_NS |
14880 |
+ struct net *skc_net; |
14881 |
+ #endif |
14882 |
++ xid_t skc_xid; |
14883 |
++ struct vx_info *skc_vx_info; |
14884 |
++ nid_t skc_nid; |
14885 |
++ struct nx_info *skc_nx_info; |
14886 |
+ }; |
14887 |
+ |
14888 |
+ /** |
14889 |
+@@ -218,6 +222,10 @@ struct sock { |
14890 |
+ #define sk_hash __sk_common.skc_hash |
14891 |
+ #define sk_prot __sk_common.skc_prot |
14892 |
+ #define sk_net __sk_common.skc_net |
14893 |
++#define sk_xid __sk_common.skc_xid |
14894 |
++#define sk_vx_info __sk_common.skc_vx_info |
14895 |
++#define sk_nid __sk_common.skc_nid |
14896 |
++#define sk_nx_info __sk_common.skc_nx_info |
14897 |
+ unsigned char sk_shutdown : 2, |
14898 |
+ sk_no_check : 2, |
14899 |
+ sk_userlocks : 4; |
14900 |
+diff -NurpP --minimal linux-2.6.29.4/init/main.c linux-2.6.29.4-vs2.3.0.36.14/init/main.c |
14901 |
+--- linux-2.6.29.4/init/main.c 2009-03-24 14:22:44.000000000 +0100 |
14902 |
++++ linux-2.6.29.4-vs2.3.0.36.14/init/main.c 2009-03-24 17:22:37.000000000 +0100 |
14903 |
+@@ -64,6 +64,7 @@ |
14904 |
+ #include <linux/ftrace.h> |
14905 |
+ #include <linux/async.h> |
14906 |
+ #include <trace/boot.h> |
14907 |
++#include <linux/vserver/percpu.h> |
14908 |
+ |
14909 |
+ #include <asm/io.h> |
14910 |
+ #include <asm/bugs.h> |
14911 |
+@@ -381,12 +382,14 @@ EXPORT_SYMBOL(__per_cpu_offset); |
14912 |
+ |
14913 |
+ static void __init setup_per_cpu_areas(void) |
14914 |
+ { |
14915 |
+- unsigned long size, i; |
14916 |
++ unsigned long size, vspc, i; |
14917 |
+ char *ptr; |
14918 |
+ unsigned long nr_possible_cpus = num_possible_cpus(); |
14919 |
+ |
14920 |
++ vspc = PERCPU_PERCTX * CONFIG_VSERVER_CONTEXTS; |
14921 |
++ |
14922 |
+ /* Copy section for each CPU (we discard the original) */ |
14923 |
+- size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE); |
14924 |
++ size = ALIGN(PERCPU_ENOUGH_ROOM + vspc, PAGE_SIZE); |
14925 |
+ ptr = alloc_bootmem_pages(size * nr_possible_cpus); |
14926 |
+ |
14927 |
+ for_each_possible_cpu(i) { |
14928 |
+diff -NurpP --minimal linux-2.6.29.4/ipc/mqueue.c linux-2.6.29.4-vs2.3.0.36.14/ipc/mqueue.c |
14929 |
+--- linux-2.6.29.4/ipc/mqueue.c 2009-03-24 14:22:44.000000000 +0100 |
14930 |
++++ linux-2.6.29.4-vs2.3.0.36.14/ipc/mqueue.c 2009-03-24 17:24:19.000000000 +0100 |
14931 |
+@@ -31,6 +31,8 @@ |
14932 |
+ #include <linux/mutex.h> |
14933 |
+ #include <linux/nsproxy.h> |
14934 |
+ #include <linux/pid.h> |
14935 |
++#include <linux/vs_context.h> |
14936 |
++#include <linux/vs_limit.h> |
14937 |
+ |
14938 |
+ #include <net/sock.h> |
14939 |
+ #include "util.h" |
14940 |
+@@ -79,6 +81,7 @@ struct mqueue_inode_info { |
14941 |
+ struct sigevent notify; |
14942 |
+ struct pid* notify_owner; |
14943 |
+ struct user_struct *user; /* user who created, for accounting */ |
14944 |
++ struct vx_info *vxi; |
14945 |
+ struct sock *notify_sock; |
14946 |
+ struct sk_buff *notify_cookie; |
14947 |
+ |
14948 |
+@@ -126,6 +129,7 @@ static struct inode *mqueue_get_inode(st |
14949 |
+ if (S_ISREG(mode)) { |
14950 |
+ struct mqueue_inode_info *info; |
14951 |
+ struct task_struct *p = current; |
14952 |
++ struct vx_info *vxi = p->vx_info; |
14953 |
+ unsigned long mq_bytes, mq_msg_tblsz; |
14954 |
+ |
14955 |
+ inode->i_fop = &mqueue_file_operations; |
14956 |
+@@ -140,6 +144,7 @@ static struct inode *mqueue_get_inode(st |
14957 |
+ info->notify_owner = NULL; |
14958 |
+ info->qsize = 0; |
14959 |
+ info->user = NULL; /* set when all is ok */ |
14960 |
++ info->vxi = NULL; |
14961 |
+ memset(&info->attr, 0, sizeof(info->attr)); |
14962 |
+ info->attr.mq_maxmsg = msg_max; |
14963 |
+ info->attr.mq_msgsize = msgsize_max; |
14964 |
+@@ -154,22 +159,26 @@ static struct inode *mqueue_get_inode(st |
14965 |
+ spin_lock(&mq_lock); |
14966 |
+ if (u->mq_bytes + mq_bytes < u->mq_bytes || |
14967 |
+ u->mq_bytes + mq_bytes > |
14968 |
+- p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) { |
14969 |
++ p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur || |
14970 |
++ !vx_ipcmsg_avail(vxi, mq_bytes)) { |
14971 |
+ spin_unlock(&mq_lock); |
14972 |
+ goto out_inode; |
14973 |
+ } |
14974 |
+ u->mq_bytes += mq_bytes; |
14975 |
++ vx_ipcmsg_add(vxi, u, mq_bytes); |
14976 |
+ spin_unlock(&mq_lock); |
14977 |
+ |
14978 |
+ info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL); |
14979 |
+ if (!info->messages) { |
14980 |
+ spin_lock(&mq_lock); |
14981 |
+ u->mq_bytes -= mq_bytes; |
14982 |
++ vx_ipcmsg_sub(vxi, u, mq_bytes); |
14983 |
+ spin_unlock(&mq_lock); |
14984 |
+ goto out_inode; |
14985 |
+ } |
14986 |
+ /* all is ok */ |
14987 |
+ info->user = get_uid(u); |
14988 |
++ info->vxi = get_vx_info(vxi); |
14989 |
+ } else if (S_ISDIR(mode)) { |
14990 |
+ inc_nlink(inode); |
14991 |
+ /* Some things misbehave if size == 0 on a directory */ |
14992 |
+@@ -260,10 +269,14 @@ static void mqueue_delete_inode(struct i |
14993 |
+ (info->attr.mq_maxmsg * info->attr.mq_msgsize)); |
14994 |
+ user = info->user; |
14995 |
+ if (user) { |
14996 |
++ struct vx_info *vxi = info->vxi; |
14997 |
++ |
14998 |
+ spin_lock(&mq_lock); |
14999 |
+ user->mq_bytes -= mq_bytes; |
15000 |
++ vx_ipcmsg_sub(vxi, user, mq_bytes); |
15001 |
+ queues_count--; |
15002 |
+ spin_unlock(&mq_lock); |
15003 |
++ put_vx_info(vxi); |
15004 |
+ free_uid(user); |
15005 |
+ } |
15006 |
+ } |
15007 |
+diff -NurpP --minimal linux-2.6.29.4/ipc/msg.c linux-2.6.29.4-vs2.3.0.36.14/ipc/msg.c |
15008 |
+--- linux-2.6.29.4/ipc/msg.c 2009-03-24 14:22:44.000000000 +0100 |
15009 |
++++ linux-2.6.29.4-vs2.3.0.36.14/ipc/msg.c 2009-02-22 22:54:26.000000000 +0100 |
15010 |
+@@ -38,6 +38,7 @@ |
15011 |
+ #include <linux/rwsem.h> |
15012 |
+ #include <linux/nsproxy.h> |
15013 |
+ #include <linux/ipc_namespace.h> |
15014 |
++#include <linux/vs_base.h> |
15015 |
+ |
15016 |
+ #include <asm/current.h> |
15017 |
+ #include <asm/uaccess.h> |
15018 |
+@@ -190,6 +191,7 @@ static int newque(struct ipc_namespace * |
15019 |
+ |
15020 |
+ msq->q_perm.mode = msgflg & S_IRWXUGO; |
15021 |
+ msq->q_perm.key = key; |
15022 |
++ msq->q_perm.xid = vx_current_xid(); |
15023 |
+ |
15024 |
+ msq->q_perm.security = NULL; |
15025 |
+ retval = security_msg_queue_alloc(msq); |
15026 |
+diff -NurpP --minimal linux-2.6.29.4/ipc/namespace.c linux-2.6.29.4-vs2.3.0.36.14/ipc/namespace.c |
15027 |
+--- linux-2.6.29.4/ipc/namespace.c 2008-12-25 00:26:37.000000000 +0100 |
15028 |
++++ linux-2.6.29.4-vs2.3.0.36.14/ipc/namespace.c 2009-02-22 22:54:26.000000000 +0100 |
15029 |
+@@ -9,6 +9,8 @@ |
15030 |
+ #include <linux/rcupdate.h> |
15031 |
+ #include <linux/nsproxy.h> |
15032 |
+ #include <linux/slab.h> |
15033 |
++#include <linux/vs_base.h> |
15034 |
++#include <linux/vserver/global.h> |
15035 |
+ |
15036 |
+ #include "util.h" |
15037 |
+ |
15038 |
+@@ -35,6 +37,7 @@ static struct ipc_namespace *clone_ipc_n |
15039 |
+ register_ipcns_notifier(ns); |
15040 |
+ |
15041 |
+ kref_init(&ns->kref); |
15042 |
++ atomic_inc(&vs_global_ipc_ns); |
15043 |
+ return ns; |
15044 |
+ } |
15045 |
+ |
15046 |
+@@ -101,6 +104,7 @@ void free_ipc_ns(struct kref *kref) |
15047 |
+ sem_exit_ns(ns); |
15048 |
+ msg_exit_ns(ns); |
15049 |
+ shm_exit_ns(ns); |
15050 |
++ atomic_dec(&vs_global_ipc_ns); |
15051 |
+ kfree(ns); |
15052 |
+ atomic_dec(&nr_ipc_ns); |
15053 |
+ |
15054 |
+diff -NurpP --minimal linux-2.6.29.4/ipc/sem.c linux-2.6.29.4-vs2.3.0.36.14/ipc/sem.c |
15055 |
+--- linux-2.6.29.4/ipc/sem.c 2009-03-24 14:22:44.000000000 +0100 |
15056 |
++++ linux-2.6.29.4-vs2.3.0.36.14/ipc/sem.c 2009-03-31 23:31:33.000000000 +0200 |
15057 |
+@@ -83,6 +83,8 @@ |
15058 |
+ #include <linux/rwsem.h> |
15059 |
+ #include <linux/nsproxy.h> |
15060 |
+ #include <linux/ipc_namespace.h> |
15061 |
++#include <linux/vs_base.h> |
15062 |
++#include <linux/vs_limit.h> |
15063 |
+ |
15064 |
+ #include <asm/uaccess.h> |
15065 |
+ #include "util.h" |
15066 |
+@@ -255,6 +257,7 @@ static int newary(struct ipc_namespace * |
15067 |
+ |
15068 |
+ sma->sem_perm.mode = (semflg & S_IRWXUGO); |
15069 |
+ sma->sem_perm.key = key; |
15070 |
++ sma->sem_perm.xid = vx_current_xid(); |
15071 |
+ |
15072 |
+ sma->sem_perm.security = NULL; |
15073 |
+ retval = security_sem_alloc(sma); |
15074 |
+@@ -270,6 +273,9 @@ static int newary(struct ipc_namespace * |
15075 |
+ return id; |
15076 |
+ } |
15077 |
+ ns->used_sems += nsems; |
15078 |
++ /* FIXME: obsoleted? */ |
15079 |
++ vx_semary_inc(sma); |
15080 |
++ vx_nsems_add(sma, nsems); |
15081 |
+ |
15082 |
+ sma->sem_base = (struct sem *) &sma[1]; |
15083 |
+ INIT_LIST_HEAD(&sma->sem_pending); |
15084 |
+@@ -546,6 +552,9 @@ static void freeary(struct ipc_namespace |
15085 |
+ sem_unlock(sma); |
15086 |
+ |
15087 |
+ ns->used_sems -= sma->sem_nsems; |
15088 |
++ /* FIXME: obsoleted? */ |
15089 |
++ vx_nsems_sub(sma, sma->sem_nsems); |
15090 |
++ vx_semary_dec(sma); |
15091 |
+ security_sem_free(sma); |
15092 |
+ ipc_rcu_putref(sma); |
15093 |
+ } |
15094 |
+diff -NurpP --minimal linux-2.6.29.4/ipc/shm.c linux-2.6.29.4-vs2.3.0.36.14/ipc/shm.c |
15095 |
+--- linux-2.6.29.4/ipc/shm.c 2009-03-24 14:22:44.000000000 +0100 |
15096 |
++++ linux-2.6.29.4-vs2.3.0.36.14/ipc/shm.c 2009-03-24 14:48:36.000000000 +0100 |
15097 |
+@@ -39,6 +39,8 @@ |
15098 |
+ #include <linux/nsproxy.h> |
15099 |
+ #include <linux/mount.h> |
15100 |
+ #include <linux/ipc_namespace.h> |
15101 |
++#include <linux/vs_context.h> |
15102 |
++#include <linux/vs_limit.h> |
15103 |
+ |
15104 |
+ #include <asm/uaccess.h> |
15105 |
+ |
15106 |
+@@ -168,7 +170,12 @@ static void shm_open(struct vm_area_stru |
15107 |
+ */ |
15108 |
+ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) |
15109 |
+ { |
15110 |
+- ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT; |
15111 |
++ struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid); |
15112 |
++ int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT; |
15113 |
++ |
15114 |
++ vx_ipcshm_sub(vxi, shp, numpages); |
15115 |
++ ns->shm_tot -= numpages; |
15116 |
++ |
15117 |
+ shm_rmid(ns, shp); |
15118 |
+ shm_unlock(shp); |
15119 |
+ if (!is_file_hugepages(shp->shm_file)) |
15120 |
+@@ -178,6 +185,7 @@ static void shm_destroy(struct ipc_names |
15121 |
+ shp->mlock_user); |
15122 |
+ fput (shp->shm_file); |
15123 |
+ security_shm_free(shp); |
15124 |
++ put_vx_info(vxi); |
15125 |
+ ipc_rcu_putref(shp); |
15126 |
+ } |
15127 |
+ |
15128 |
+@@ -348,11 +356,15 @@ static int newseg(struct ipc_namespace * |
15129 |
+ if (ns->shm_tot + numpages > ns->shm_ctlall) |
15130 |
+ return -ENOSPC; |
15131 |
+ |
15132 |
++ if (!vx_ipcshm_avail(current->vx_info, numpages)) |
15133 |
++ return -ENOSPC; |
15134 |
++ |
15135 |
+ shp = ipc_rcu_alloc(sizeof(*shp)); |
15136 |
+ if (!shp) |
15137 |
+ return -ENOMEM; |
15138 |
+ |
15139 |
+ shp->shm_perm.key = key; |
15140 |
++ shp->shm_perm.xid = vx_current_xid(); |
15141 |
+ shp->shm_perm.mode = (shmflg & S_IRWXUGO); |
15142 |
+ shp->mlock_user = NULL; |
15143 |
+ |
15144 |
+@@ -406,6 +418,7 @@ static int newseg(struct ipc_namespace * |
15145 |
+ ns->shm_tot += numpages; |
15146 |
+ error = shp->shm_perm.id; |
15147 |
+ shm_unlock(shp); |
15148 |
++ vx_ipcshm_add(current->vx_info, key, numpages); |
15149 |
+ return error; |
15150 |
+ |
15151 |
+ no_id: |
15152 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/capability.c linux-2.6.29.4-vs2.3.0.36.14/kernel/capability.c |
15153 |
+--- linux-2.6.29.4/kernel/capability.c 2009-03-24 14:22:44.000000000 +0100 |
15154 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/capability.c 2009-03-24 17:27:28.000000000 +0100 |
15155 |
+@@ -14,6 +14,7 @@ |
15156 |
+ #include <linux/security.h> |
15157 |
+ #include <linux/syscalls.h> |
15158 |
+ #include <linux/pid_namespace.h> |
15159 |
++#include <linux/vs_context.h> |
15160 |
+ #include <asm/uaccess.h> |
15161 |
+ #include "cred-internals.h" |
15162 |
+ |
15163 |
+@@ -122,6 +123,7 @@ static int cap_validate_magic(cap_user_h |
15164 |
+ return 0; |
15165 |
+ } |
15166 |
+ |
15167 |
++ |
15168 |
+ /* |
15169 |
+ * The only thing that can change the capabilities of the current |
15170 |
+ * process is the current process. As such, we can't be in this code |
15171 |
+@@ -289,6 +291,8 @@ error: |
15172 |
+ return ret; |
15173 |
+ } |
15174 |
+ |
15175 |
++#include <linux/vserver/base.h> |
15176 |
++ |
15177 |
+ /** |
15178 |
+ * capable - Determine if the current task has a superior capability in effect |
15179 |
+ * @cap: The capability to be tested for |
15180 |
+@@ -301,6 +305,9 @@ error: |
15181 |
+ */ |
15182 |
+ int capable(int cap) |
15183 |
+ { |
15184 |
++ /* here for now so we don't require task locking */ |
15185 |
++ if (vs_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap)) |
15186 |
++ return 0; |
15187 |
+ if (unlikely(!cap_valid(cap))) { |
15188 |
+ printk(KERN_CRIT "capable() called with invalid cap=%u\n", cap); |
15189 |
+ BUG(); |
15190 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/compat.c linux-2.6.29.4-vs2.3.0.36.14/kernel/compat.c |
15191 |
+--- linux-2.6.29.4/kernel/compat.c 2009-03-24 14:22:44.000000000 +0100 |
15192 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/compat.c 2009-03-24 14:48:36.000000000 +0100 |
15193 |
+@@ -891,7 +891,7 @@ asmlinkage long compat_sys_time(compat_t |
15194 |
+ compat_time_t i; |
15195 |
+ struct timeval tv; |
15196 |
+ |
15197 |
+- do_gettimeofday(&tv); |
15198 |
++ vx_gettimeofday(&tv); |
15199 |
+ i = tv.tv_sec; |
15200 |
+ |
15201 |
+ if (tloc) { |
15202 |
+@@ -916,7 +916,7 @@ asmlinkage long compat_sys_stime(compat_ |
15203 |
+ if (err) |
15204 |
+ return err; |
15205 |
+ |
15206 |
+- do_settimeofday(&tv); |
15207 |
++ vx_settimeofday(&tv); |
15208 |
+ return 0; |
15209 |
+ } |
15210 |
+ |
15211 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/exit.c linux-2.6.29.4-vs2.3.0.36.14/kernel/exit.c |
15212 |
+--- linux-2.6.29.4/kernel/exit.c 2009-05-23 23:16:53.000000000 +0200 |
15213 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/exit.c 2009-05-10 23:58:02.000000000 +0200 |
15214 |
+@@ -47,6 +47,10 @@ |
15215 |
+ #include <linux/task_io_accounting_ops.h> |
15216 |
+ #include <linux/tracehook.h> |
15217 |
+ #include <linux/init_task.h> |
15218 |
++#include <linux/vs_limit.h> |
15219 |
++#include <linux/vs_context.h> |
15220 |
++#include <linux/vs_network.h> |
15221 |
++#include <linux/vs_pid.h> |
15222 |
+ #include <trace/sched.h> |
15223 |
+ |
15224 |
+ #include <asm/uaccess.h> |
15225 |
+@@ -497,9 +501,11 @@ static void close_files(struct files_str |
15226 |
+ filp_close(file, files); |
15227 |
+ cond_resched(); |
15228 |
+ } |
15229 |
++ vx_openfd_dec(i); |
15230 |
+ } |
15231 |
+ i++; |
15232 |
+ set >>= 1; |
15233 |
++ cond_resched(); |
15234 |
+ } |
15235 |
+ } |
15236 |
+ } |
15237 |
+@@ -1092,10 +1098,15 @@ NORET_TYPE void do_exit(long code) |
15238 |
+ if (tsk->splice_pipe) |
15239 |
+ __free_pipe_info(tsk->splice_pipe); |
15240 |
+ |
15241 |
++ /* needs to stay after exit_notify() */ |
15242 |
++ exit_vx_info(tsk, code); |
15243 |
++ exit_nx_info(tsk); |
15244 |
++ |
15245 |
+ preempt_disable(); |
15246 |
+ /* causes final put_task_struct in finish_task_switch(). */ |
15247 |
+ tsk->state = TASK_DEAD; |
15248 |
+ schedule(); |
15249 |
++ printk("bad task: %p [%lx]\n", current, current->state); |
15250 |
+ BUG(); |
15251 |
+ /* Avoid "noreturn function does return". */ |
15252 |
+ for (;;) |
15253 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/fork.c linux-2.6.29.4-vs2.3.0.36.14/kernel/fork.c |
15254 |
+--- linux-2.6.29.4/kernel/fork.c 2009-05-23 23:16:53.000000000 +0200 |
15255 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/fork.c 2009-05-10 23:58:22.000000000 +0200 |
15256 |
+@@ -60,6 +60,10 @@ |
15257 |
+ #include <linux/tty.h> |
15258 |
+ #include <linux/proc_fs.h> |
15259 |
+ #include <linux/blkdev.h> |
15260 |
++#include <linux/vs_context.h> |
15261 |
++#include <linux/vs_network.h> |
15262 |
++#include <linux/vs_limit.h> |
15263 |
++#include <linux/vs_memory.h> |
15264 |
+ #include <trace/sched.h> |
15265 |
+ |
15266 |
+ #include <asm/pgtable.h> |
15267 |
+@@ -140,6 +144,8 @@ void free_task(struct task_struct *tsk) |
15268 |
+ prop_local_destroy_single(&tsk->dirties); |
15269 |
+ free_thread_info(tsk->stack); |
15270 |
+ rt_mutex_debug_task_free(tsk); |
15271 |
++ clr_vx_info(&tsk->vx_info); |
15272 |
++ clr_nx_info(&tsk->nx_info); |
15273 |
+ ftrace_graph_exit_task(tsk); |
15274 |
+ free_task_struct(tsk); |
15275 |
+ } |
15276 |
+@@ -279,6 +285,8 @@ static int dup_mmap(struct mm_struct *mm |
15277 |
+ mm->free_area_cache = oldmm->mmap_base; |
15278 |
+ mm->cached_hole_size = ~0UL; |
15279 |
+ mm->map_count = 0; |
15280 |
++ __set_mm_counter(mm, file_rss, 0); |
15281 |
++ __set_mm_counter(mm, anon_rss, 0); |
15282 |
+ cpus_clear(mm->cpu_vm_mask); |
15283 |
+ mm->mm_rb = RB_ROOT; |
15284 |
+ rb_link = &mm->mm_rb.rb_node; |
15285 |
+@@ -290,7 +298,7 @@ static int dup_mmap(struct mm_struct *mm |
15286 |
+ |
15287 |
+ if (mpnt->vm_flags & VM_DONTCOPY) { |
15288 |
+ long pages = vma_pages(mpnt); |
15289 |
+- mm->total_vm -= pages; |
15290 |
++ vx_vmpages_sub(mm, pages); |
15291 |
+ vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file, |
15292 |
+ -pages); |
15293 |
+ continue; |
15294 |
+@@ -423,8 +431,8 @@ static struct mm_struct * mm_init(struct |
15295 |
+ mm->flags = (current->mm) ? current->mm->flags : default_dump_filter; |
15296 |
+ mm->core_state = NULL; |
15297 |
+ mm->nr_ptes = 0; |
15298 |
+- set_mm_counter(mm, file_rss, 0); |
15299 |
+- set_mm_counter(mm, anon_rss, 0); |
15300 |
++ __set_mm_counter(mm, file_rss, 0); |
15301 |
++ __set_mm_counter(mm, anon_rss, 0); |
15302 |
+ spin_lock_init(&mm->page_table_lock); |
15303 |
+ spin_lock_init(&mm->ioctx_lock); |
15304 |
+ INIT_HLIST_HEAD(&mm->ioctx_list); |
15305 |
+@@ -435,6 +443,7 @@ static struct mm_struct * mm_init(struct |
15306 |
+ if (likely(!mm_alloc_pgd(mm))) { |
15307 |
+ mm->def_flags = 0; |
15308 |
+ mmu_notifier_mm_init(mm); |
15309 |
++ set_vx_info(&mm->mm_vx_info, p->vx_info); |
15310 |
+ return mm; |
15311 |
+ } |
15312 |
+ |
15313 |
+@@ -468,6 +477,7 @@ void __mmdrop(struct mm_struct *mm) |
15314 |
+ mm_free_pgd(mm); |
15315 |
+ destroy_context(mm); |
15316 |
+ mmu_notifier_mm_destroy(mm); |
15317 |
++ clr_vx_info(&mm->mm_vx_info); |
15318 |
+ free_mm(mm); |
15319 |
+ } |
15320 |
+ EXPORT_SYMBOL_GPL(__mmdrop); |
15321 |
+@@ -594,6 +604,7 @@ struct mm_struct *dup_mm(struct task_str |
15322 |
+ goto fail_nomem; |
15323 |
+ |
15324 |
+ memcpy(mm, oldmm, sizeof(*mm)); |
15325 |
++ mm->mm_vx_info = NULL; |
15326 |
+ |
15327 |
+ /* Initializing for Swap token stuff */ |
15328 |
+ mm->token_priority = 0; |
15329 |
+@@ -627,6 +638,7 @@ fail_nocontext: |
15330 |
+ * If init_new_context() failed, we cannot use mmput() to free the mm |
15331 |
+ * because it calls destroy_context() |
15332 |
+ */ |
15333 |
++ clr_vx_info(&mm->mm_vx_info); |
15334 |
+ mm_free_pgd(mm); |
15335 |
+ free_mm(mm); |
15336 |
+ return NULL; |
15337 |
+@@ -943,6 +955,8 @@ static struct task_struct *copy_process( |
15338 |
+ int retval; |
15339 |
+ struct task_struct *p; |
15340 |
+ int cgroup_callbacks_done = 0; |
15341 |
++ struct vx_info *vxi; |
15342 |
++ struct nx_info *nxi; |
15343 |
+ |
15344 |
+ if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) |
15345 |
+ return ERR_PTR(-EINVAL); |
15346 |
+@@ -977,12 +991,28 @@ static struct task_struct *copy_process( |
15347 |
+ DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled); |
15348 |
+ DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); |
15349 |
+ #endif |
15350 |
++ init_vx_info(&p->vx_info, current->vx_info); |
15351 |
++ init_nx_info(&p->nx_info, current->nx_info); |
15352 |
++ |
15353 |
++ /* check vserver memory */ |
15354 |
++ if (p->mm && !(clone_flags & CLONE_VM)) { |
15355 |
++ if (vx_vmpages_avail(p->mm, p->mm->total_vm)) |
15356 |
++ vx_pages_add(p->vx_info, RLIMIT_AS, p->mm->total_vm); |
15357 |
++ else |
15358 |
++ goto bad_fork_free; |
15359 |
++ } |
15360 |
++ if (p->mm && vx_flags(VXF_FORK_RSS, 0)) { |
15361 |
++ if (!vx_rss_avail(p->mm, get_mm_counter(p->mm, file_rss))) |
15362 |
++ goto bad_fork_cleanup_vm; |
15363 |
++ } |
15364 |
+ retval = -EAGAIN; |
15365 |
++ if (!vx_nproc_avail(1)) |
15366 |
++ goto bad_fork_cleanup_vm; |
15367 |
+ if (atomic_read(&p->real_cred->user->processes) >= |
15368 |
+ p->signal->rlim[RLIMIT_NPROC].rlim_cur) { |
15369 |
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && |
15370 |
+ p->real_cred->user != INIT_USER) |
15371 |
+- goto bad_fork_free; |
15372 |
++ goto bad_fork_cleanup_vm; |
15373 |
+ } |
15374 |
+ |
15375 |
+ retval = copy_creds(p, clone_flags); |
15376 |
+@@ -1259,6 +1289,18 @@ static struct task_struct *copy_process( |
15377 |
+ |
15378 |
+ total_forks++; |
15379 |
+ spin_unlock(¤t->sighand->siglock); |
15380 |
++ |
15381 |
++ /* p is copy of current */ |
15382 |
++ vxi = p->vx_info; |
15383 |
++ if (vxi) { |
15384 |
++ claim_vx_info(vxi, p); |
15385 |
++ atomic_inc(&vxi->cvirt.nr_threads); |
15386 |
++ atomic_inc(&vxi->cvirt.total_forks); |
15387 |
++ vx_nproc_inc(p); |
15388 |
++ } |
15389 |
++ nxi = p->nx_info; |
15390 |
++ if (nxi) |
15391 |
++ claim_nx_info(nxi, p); |
15392 |
+ write_unlock_irq(&tasklist_lock); |
15393 |
+ proc_fork_connector(p); |
15394 |
+ cgroup_post_fork(p); |
15395 |
+@@ -1303,6 +1345,9 @@ bad_fork_cleanup_count: |
15396 |
+ atomic_dec(&p->cred->user->processes); |
15397 |
+ put_cred(p->real_cred); |
15398 |
+ put_cred(p->cred); |
15399 |
++bad_fork_cleanup_vm: |
15400 |
++ if (p->mm && !(clone_flags & CLONE_VM)) |
15401 |
++ vx_pages_sub(p->vx_info, RLIMIT_AS, p->mm->total_vm); |
15402 |
+ bad_fork_free: |
15403 |
+ free_task(p); |
15404 |
+ fork_out: |
15405 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/kthread.c linux-2.6.29.4-vs2.3.0.36.14/kernel/kthread.c |
15406 |
+--- linux-2.6.29.4/kernel/kthread.c 2009-03-24 14:22:44.000000000 +0100 |
15407 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/kthread.c 2009-03-24 14:48:36.000000000 +0100 |
15408 |
+@@ -13,6 +13,7 @@ |
15409 |
+ #include <linux/file.h> |
15410 |
+ #include <linux/module.h> |
15411 |
+ #include <linux/mutex.h> |
15412 |
++#include <linux/vs_pid.h> |
15413 |
+ #include <trace/sched.h> |
15414 |
+ |
15415 |
+ #define KTHREAD_NICE_LEVEL (-5) |
15416 |
+@@ -102,7 +103,7 @@ static void create_kthread(struct kthrea |
15417 |
+ struct sched_param param = { .sched_priority = 0 }; |
15418 |
+ wait_for_completion(&create->started); |
15419 |
+ read_lock(&tasklist_lock); |
15420 |
+- create->result = find_task_by_pid_ns(pid, &init_pid_ns); |
15421 |
++ create->result = find_task_by_real_pid(pid); |
15422 |
+ read_unlock(&tasklist_lock); |
15423 |
+ /* |
15424 |
+ * root may have changed our (kthreadd's) priority or CPU mask. |
15425 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/Makefile linux-2.6.29.4-vs2.3.0.36.14/kernel/Makefile |
15426 |
+--- linux-2.6.29.4/kernel/Makefile 2009-03-24 14:22:44.000000000 +0100 |
15427 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/Makefile 2009-03-24 14:48:36.000000000 +0100 |
15428 |
+@@ -22,6 +22,7 @@ CFLAGS_REMOVE_cgroup-debug.o = -pg |
15429 |
+ CFLAGS_REMOVE_sched_clock.o = -pg |
15430 |
+ endif |
15431 |
+ |
15432 |
++obj-y += vserver/ |
15433 |
+ obj-$(CONFIG_FREEZER) += freezer.o |
15434 |
+ obj-$(CONFIG_PROFILING) += profile.o |
15435 |
+ obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o |
15436 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/nsproxy.c linux-2.6.29.4-vs2.3.0.36.14/kernel/nsproxy.c |
15437 |
+--- linux-2.6.29.4/kernel/nsproxy.c 2009-03-24 14:22:44.000000000 +0100 |
15438 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/nsproxy.c 2009-03-25 00:39:02.000000000 +0100 |
15439 |
+@@ -19,6 +19,8 @@ |
15440 |
+ #include <linux/mnt_namespace.h> |
15441 |
+ #include <linux/utsname.h> |
15442 |
+ #include <linux/pid_namespace.h> |
15443 |
++#include <linux/vserver/global.h> |
15444 |
++#include <linux/vserver/debug.h> |
15445 |
+ #include <net/net_namespace.h> |
15446 |
+ #include <linux/ipc_namespace.h> |
15447 |
+ |
15448 |
+@@ -37,6 +39,9 @@ static inline struct nsproxy *clone_nspr |
15449 |
+ if (ns) { |
15450 |
+ memcpy(ns, orig, sizeof(struct nsproxy)); |
15451 |
+ atomic_set(&ns->count, 1); |
15452 |
++ vxdprintk(VXD_CBIT(space, 2), "clone_nsproxy(%p[%u] = %p[1]", |
15453 |
++ orig, atomic_read(&orig->count), ns); |
15454 |
++ atomic_inc(&vs_global_nsproxy); |
15455 |
+ } |
15456 |
+ return ns; |
15457 |
+ } |
15458 |
+@@ -46,41 +51,52 @@ static inline struct nsproxy *clone_nspr |
15459 |
+ * Return the newly created nsproxy. Do not attach this to the task, |
15460 |
+ * leave it to the caller to do proper locking and attach it to task. |
15461 |
+ */ |
15462 |
+-static struct nsproxy *create_new_namespaces(unsigned long flags, |
15463 |
+- struct task_struct *tsk, struct fs_struct *new_fs) |
15464 |
++static struct nsproxy *unshare_namespaces(unsigned long flags, |
15465 |
++ struct nsproxy *orig, struct fs_struct *new_fs) |
15466 |
+ { |
15467 |
+ struct nsproxy *new_nsp; |
15468 |
+ int err; |
15469 |
+ |
15470 |
+- new_nsp = clone_nsproxy(tsk->nsproxy); |
15471 |
++ vxdprintk(VXD_CBIT(space, 4), |
15472 |
++ "unshare_namespaces(0x%08lx,%p,%p)", |
15473 |
++ flags, orig, new_fs); |
15474 |
++ |
15475 |
++ new_nsp = clone_nsproxy(orig); |
15476 |
+ if (!new_nsp) |
15477 |
+ return ERR_PTR(-ENOMEM); |
15478 |
+ |
15479 |
+- new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, new_fs); |
15480 |
++ new_nsp->mnt_ns = copy_mnt_ns(flags, orig->mnt_ns, new_fs); |
15481 |
+ if (IS_ERR(new_nsp->mnt_ns)) { |
15482 |
+ err = PTR_ERR(new_nsp->mnt_ns); |
15483 |
+ goto out_ns; |
15484 |
+ } |
15485 |
+ |
15486 |
+- new_nsp->uts_ns = copy_utsname(flags, tsk->nsproxy->uts_ns); |
15487 |
++ new_nsp->uts_ns = copy_utsname(flags, orig->uts_ns); |
15488 |
+ if (IS_ERR(new_nsp->uts_ns)) { |
15489 |
+ err = PTR_ERR(new_nsp->uts_ns); |
15490 |
+ goto out_uts; |
15491 |
+ } |
15492 |
+ |
15493 |
+- new_nsp->ipc_ns = copy_ipcs(flags, tsk->nsproxy->ipc_ns); |
15494 |
++ new_nsp->ipc_ns = copy_ipcs(flags, orig->ipc_ns); |
15495 |
+ if (IS_ERR(new_nsp->ipc_ns)) { |
15496 |
+ err = PTR_ERR(new_nsp->ipc_ns); |
15497 |
+ goto out_ipc; |
15498 |
+ } |
15499 |
+ |
15500 |
+- new_nsp->pid_ns = copy_pid_ns(flags, task_active_pid_ns(tsk)); |
15501 |
++ new_nsp->pid_ns = copy_pid_ns(flags, orig->pid_ns); |
15502 |
+ if (IS_ERR(new_nsp->pid_ns)) { |
15503 |
+ err = PTR_ERR(new_nsp->pid_ns); |
15504 |
+ goto out_pid; |
15505 |
+ } |
15506 |
+ |
15507 |
+- new_nsp->net_ns = copy_net_ns(flags, tsk->nsproxy->net_ns); |
15508 |
++ /* disabled now? |
15509 |
++ new_nsp->user_ns = copy_user_ns(flags, orig->user_ns); |
15510 |
++ if (IS_ERR(new_nsp->user_ns)) { |
15511 |
++ err = PTR_ERR(new_nsp->user_ns); |
15512 |
++ goto out_user; |
15513 |
++ } */ |
15514 |
++ |
15515 |
++ new_nsp->net_ns = copy_net_ns(flags, orig->net_ns); |
15516 |
+ if (IS_ERR(new_nsp->net_ns)) { |
15517 |
+ err = PTR_ERR(new_nsp->net_ns); |
15518 |
+ goto out_net; |
15519 |
+@@ -105,6 +121,35 @@ out_ns: |
15520 |
+ return ERR_PTR(err); |
15521 |
+ } |
15522 |
+ |
15523 |
++static struct nsproxy *create_new_namespaces(int flags, struct task_struct *tsk, |
15524 |
++ struct fs_struct *new_fs) |
15525 |
++{ |
15526 |
++ return unshare_namespaces(flags, tsk->nsproxy, new_fs); |
15527 |
++} |
15528 |
++ |
15529 |
++/* |
15530 |
++ * copies the nsproxy, setting refcount to 1, and grabbing a |
15531 |
++ * reference to all contained namespaces. |
15532 |
++ */ |
15533 |
++struct nsproxy *copy_nsproxy(struct nsproxy *orig) |
15534 |
++{ |
15535 |
++ struct nsproxy *ns = clone_nsproxy(orig); |
15536 |
++ |
15537 |
++ if (ns) { |
15538 |
++ if (ns->mnt_ns) |
15539 |
++ get_mnt_ns(ns->mnt_ns); |
15540 |
++ if (ns->uts_ns) |
15541 |
++ get_uts_ns(ns->uts_ns); |
15542 |
++ if (ns->ipc_ns) |
15543 |
++ get_ipc_ns(ns->ipc_ns); |
15544 |
++ if (ns->pid_ns) |
15545 |
++ get_pid_ns(ns->pid_ns); |
15546 |
++ if (ns->net_ns) |
15547 |
++ get_net(ns->net_ns); |
15548 |
++ } |
15549 |
++ return ns; |
15550 |
++} |
15551 |
++ |
15552 |
+ /* |
15553 |
+ * called from clone. This now handles copy for nsproxy and all |
15554 |
+ * namespaces therein. |
15555 |
+@@ -112,9 +157,12 @@ out_ns: |
15556 |
+ int copy_namespaces(unsigned long flags, struct task_struct *tsk) |
15557 |
+ { |
15558 |
+ struct nsproxy *old_ns = tsk->nsproxy; |
15559 |
+- struct nsproxy *new_ns; |
15560 |
++ struct nsproxy *new_ns = NULL; |
15561 |
+ int err = 0; |
15562 |
+ |
15563 |
++ vxdprintk(VXD_CBIT(space, 7), "copy_namespaces(0x%08lx,%p[%p])", |
15564 |
++ flags, tsk, old_ns); |
15565 |
++ |
15566 |
+ if (!old_ns) |
15567 |
+ return 0; |
15568 |
+ |
15569 |
+@@ -151,6 +199,9 @@ int copy_namespaces(unsigned long flags, |
15570 |
+ |
15571 |
+ out: |
15572 |
+ put_nsproxy(old_ns); |
15573 |
++ vxdprintk(VXD_CBIT(space, 3), |
15574 |
++ "copy_namespaces(0x%08lx,%p[%p]) = %d [%p]", |
15575 |
++ flags, tsk, old_ns, err, new_ns); |
15576 |
+ return err; |
15577 |
+ } |
15578 |
+ |
15579 |
+@@ -164,7 +215,9 @@ void free_nsproxy(struct nsproxy *ns) |
15580 |
+ put_ipc_ns(ns->ipc_ns); |
15581 |
+ if (ns->pid_ns) |
15582 |
+ put_pid_ns(ns->pid_ns); |
15583 |
+- put_net(ns->net_ns); |
15584 |
++ if (ns->net_ns) |
15585 |
++ put_net(ns->net_ns); |
15586 |
++ atomic_dec(&vs_global_nsproxy); |
15587 |
+ kmem_cache_free(nsproxy_cachep, ns); |
15588 |
+ } |
15589 |
+ |
15590 |
+@@ -177,6 +230,10 @@ int unshare_nsproxy_namespaces(unsigned |
15591 |
+ { |
15592 |
+ int err = 0; |
15593 |
+ |
15594 |
++ vxdprintk(VXD_CBIT(space, 4), |
15595 |
++ "unshare_nsproxy_namespaces(0x%08lx,[%p])", |
15596 |
++ unshare_flags, current->nsproxy); |
15597 |
++ |
15598 |
+ if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | |
15599 |
+ CLONE_NEWNET))) |
15600 |
+ return 0; |
15601 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/pid.c linux-2.6.29.4-vs2.3.0.36.14/kernel/pid.c |
15602 |
+--- linux-2.6.29.4/kernel/pid.c 2009-03-24 14:22:44.000000000 +0100 |
15603 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/pid.c 2009-05-10 23:59:04.000000000 +0200 |
15604 |
+@@ -36,6 +36,7 @@ |
15605 |
+ #include <linux/pid_namespace.h> |
15606 |
+ #include <linux/init_task.h> |
15607 |
+ #include <linux/syscalls.h> |
15608 |
++#include <linux/vs_pid.h> |
15609 |
+ |
15610 |
+ #define pid_hashfn(nr, ns) \ |
15611 |
+ hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift) |
15612 |
+@@ -305,7 +306,7 @@ EXPORT_SYMBOL_GPL(find_pid_ns); |
15613 |
+ |
15614 |
+ struct pid *find_vpid(int nr) |
15615 |
+ { |
15616 |
+- return find_pid_ns(nr, current->nsproxy->pid_ns); |
15617 |
++ return find_pid_ns(vx_rmap_pid(nr), current->nsproxy->pid_ns); |
15618 |
+ } |
15619 |
+ EXPORT_SYMBOL_GPL(find_vpid); |
15620 |
+ |
15621 |
+@@ -365,6 +366,9 @@ void transfer_pid(struct task_struct *ol |
15622 |
+ struct task_struct *pid_task(struct pid *pid, enum pid_type type) |
15623 |
+ { |
15624 |
+ struct task_struct *result = NULL; |
15625 |
++ |
15626 |
++ if (type == PIDTYPE_REALPID) |
15627 |
++ type = PIDTYPE_PID; |
15628 |
+ if (pid) { |
15629 |
+ struct hlist_node *first; |
15630 |
+ first = rcu_dereference(pid->tasks[type].first); |
15631 |
+@@ -388,14 +392,14 @@ EXPORT_SYMBOL(find_task_by_pid_type_ns); |
15632 |
+ |
15633 |
+ struct task_struct *find_task_by_vpid(pid_t vnr) |
15634 |
+ { |
15635 |
+- return find_task_by_pid_type_ns(PIDTYPE_PID, vnr, |
15636 |
++ return find_task_by_pid_type_ns(PIDTYPE_PID, vx_rmap_pid(vnr), |
15637 |
+ current->nsproxy->pid_ns); |
15638 |
+ } |
15639 |
+ EXPORT_SYMBOL(find_task_by_vpid); |
15640 |
+ |
15641 |
+ struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns) |
15642 |
+ { |
15643 |
+- return find_task_by_pid_type_ns(PIDTYPE_PID, nr, ns); |
15644 |
++ return find_task_by_pid_type_ns(PIDTYPE_PID, vx_rmap_pid(nr), ns); |
15645 |
+ } |
15646 |
+ EXPORT_SYMBOL(find_task_by_pid_ns); |
15647 |
+ |
15648 |
+@@ -431,7 +435,7 @@ struct pid *find_get_pid(pid_t nr) |
15649 |
+ } |
15650 |
+ EXPORT_SYMBOL_GPL(find_get_pid); |
15651 |
+ |
15652 |
+-pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) |
15653 |
++pid_t pid_unmapped_nr_ns(struct pid *pid, struct pid_namespace *ns) |
15654 |
+ { |
15655 |
+ struct upid *upid; |
15656 |
+ pid_t nr = 0; |
15657 |
+@@ -444,6 +448,11 @@ pid_t pid_nr_ns(struct pid *pid, struct |
15658 |
+ return nr; |
15659 |
+ } |
15660 |
+ |
15661 |
++pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) |
15662 |
++{ |
15663 |
++ return vx_map_pid(pid_unmapped_nr_ns(pid, ns)); |
15664 |
++} |
15665 |
++ |
15666 |
+ pid_t pid_vnr(struct pid *pid) |
15667 |
+ { |
15668 |
+ return pid_nr_ns(pid, current->nsproxy->pid_ns); |
15669 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/pid_namespace.c linux-2.6.29.4-vs2.3.0.36.14/kernel/pid_namespace.c |
15670 |
+--- linux-2.6.29.4/kernel/pid_namespace.c 2008-12-25 00:26:37.000000000 +0100 |
15671 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/pid_namespace.c 2009-02-22 22:54:26.000000000 +0100 |
15672 |
+@@ -13,6 +13,7 @@ |
15673 |
+ #include <linux/syscalls.h> |
15674 |
+ #include <linux/err.h> |
15675 |
+ #include <linux/acct.h> |
15676 |
++#include <linux/vserver/global.h> |
15677 |
+ |
15678 |
+ #define BITS_PER_PAGE (PAGE_SIZE*8) |
15679 |
+ |
15680 |
+@@ -85,6 +86,7 @@ static struct pid_namespace *create_pid_ |
15681 |
+ goto out_free_map; |
15682 |
+ |
15683 |
+ kref_init(&ns->kref); |
15684 |
++ atomic_inc(&vs_global_pid_ns); |
15685 |
+ ns->level = level; |
15686 |
+ |
15687 |
+ set_bit(0, ns->pidmap[0].page); |
15688 |
+@@ -109,6 +111,7 @@ static void destroy_pid_namespace(struct |
15689 |
+ |
15690 |
+ for (i = 0; i < PIDMAP_ENTRIES; i++) |
15691 |
+ kfree(ns->pidmap[i].page); |
15692 |
++ atomic_dec(&vs_global_pid_ns); |
15693 |
+ kmem_cache_free(pid_ns_cachep, ns); |
15694 |
+ } |
15695 |
+ |
15696 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/posix-timers.c linux-2.6.29.4-vs2.3.0.36.14/kernel/posix-timers.c |
15697 |
+--- linux-2.6.29.4/kernel/posix-timers.c 2009-03-24 14:22:44.000000000 +0100 |
15698 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/posix-timers.c 2009-05-06 21:28:16.000000000 +0200 |
15699 |
+@@ -46,6 +46,7 @@ |
15700 |
+ #include <linux/wait.h> |
15701 |
+ #include <linux/workqueue.h> |
15702 |
+ #include <linux/module.h> |
15703 |
++#include <linux/vs_context.h> |
15704 |
+ |
15705 |
+ /* |
15706 |
+ * Management arrays for POSIX timers. Timers are kept in slab memory |
15707 |
+@@ -321,6 +322,7 @@ int posix_timer_event(struct k_itimer *t |
15708 |
+ { |
15709 |
+ struct task_struct *task; |
15710 |
+ int shared, ret = -1; |
15711 |
++ |
15712 |
+ /* |
15713 |
+ * FIXME: if ->sigq is queued we can race with |
15714 |
+ * dequeue_signal()->do_schedule_next_timer(). |
15715 |
+@@ -337,10 +339,18 @@ int posix_timer_event(struct k_itimer *t |
15716 |
+ rcu_read_lock(); |
15717 |
+ task = pid_task(timr->it_pid, PIDTYPE_PID); |
15718 |
+ if (task) { |
15719 |
++ struct vx_info_save vxis; |
15720 |
++ struct vx_info *vxi; |
15721 |
++ |
15722 |
++ vxi = task_get_vx_info(task); |
15723 |
++ enter_vx_info(vxi, &vxis); |
15724 |
+ shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID); |
15725 |
+ ret = send_sigqueue(timr->sigq, task, shared); |
15726 |
++ leave_vx_info(&vxis); |
15727 |
++ put_vx_info(vxi); |
15728 |
+ } |
15729 |
+ rcu_read_unlock(); |
15730 |
++ |
15731 |
+ /* If we failed to send the signal the timer stops. */ |
15732 |
+ return ret > 0; |
15733 |
+ } |
15734 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/printk.c linux-2.6.29.4-vs2.3.0.36.14/kernel/printk.c |
15735 |
+--- linux-2.6.29.4/kernel/printk.c 2009-03-24 14:22:44.000000000 +0100 |
15736 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/printk.c 2009-03-24 14:48:36.000000000 +0100 |
15737 |
+@@ -32,6 +32,7 @@ |
15738 |
+ #include <linux/security.h> |
15739 |
+ #include <linux/bootmem.h> |
15740 |
+ #include <linux/syscalls.h> |
15741 |
++#include <linux/vs_cvirt.h> |
15742 |
+ |
15743 |
+ #include <asm/uaccess.h> |
15744 |
+ |
15745 |
+@@ -251,18 +252,13 @@ int do_syslog(int type, char __user *buf |
15746 |
+ unsigned i, j, limit, count; |
15747 |
+ int do_clear = 0; |
15748 |
+ char c; |
15749 |
+- int error = 0; |
15750 |
++ int error; |
15751 |
+ |
15752 |
+ error = security_syslog(type); |
15753 |
+ if (error) |
15754 |
+ return error; |
15755 |
+ |
15756 |
+- switch (type) { |
15757 |
+- case 0: /* Close log */ |
15758 |
+- break; |
15759 |
+- case 1: /* Open log */ |
15760 |
+- break; |
15761 |
+- case 2: /* Read from log */ |
15762 |
++ if ((type >= 2) && (type <= 4)) { |
15763 |
+ error = -EINVAL; |
15764 |
+ if (!buf || len < 0) |
15765 |
+ goto out; |
15766 |
+@@ -273,6 +269,16 @@ int do_syslog(int type, char __user *buf |
15767 |
+ error = -EFAULT; |
15768 |
+ goto out; |
15769 |
+ } |
15770 |
++ } |
15771 |
++ if (!vx_check(0, VS_ADMIN|VS_WATCH)) |
15772 |
++ return vx_do_syslog(type, buf, len); |
15773 |
++ |
15774 |
++ switch (type) { |
15775 |
++ case 0: /* Close log */ |
15776 |
++ break; |
15777 |
++ case 1: /* Open log */ |
15778 |
++ break; |
15779 |
++ case 2: /* Read from log */ |
15780 |
+ error = wait_event_interruptible(log_wait, |
15781 |
+ (log_start - log_end)); |
15782 |
+ if (error) |
15783 |
+@@ -297,16 +303,6 @@ int do_syslog(int type, char __user *buf |
15784 |
+ do_clear = 1; |
15785 |
+ /* FALL THRU */ |
15786 |
+ case 3: /* Read last kernel messages */ |
15787 |
+- error = -EINVAL; |
15788 |
+- if (!buf || len < 0) |
15789 |
+- goto out; |
15790 |
+- error = 0; |
15791 |
+- if (!len) |
15792 |
+- goto out; |
15793 |
+- if (!access_ok(VERIFY_WRITE, buf, len)) { |
15794 |
+- error = -EFAULT; |
15795 |
+- goto out; |
15796 |
+- } |
15797 |
+ count = len; |
15798 |
+ if (count > log_buf_len) |
15799 |
+ count = log_buf_len; |
15800 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/ptrace.c linux-2.6.29.4-vs2.3.0.36.14/kernel/ptrace.c |
15801 |
+--- linux-2.6.29.4/kernel/ptrace.c 2009-05-23 23:16:53.000000000 +0200 |
15802 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/ptrace.c 2009-05-10 23:42:01.000000000 +0200 |
15803 |
+@@ -21,6 +21,7 @@ |
15804 |
+ #include <linux/audit.h> |
15805 |
+ #include <linux/pid_namespace.h> |
15806 |
+ #include <linux/syscalls.h> |
15807 |
++#include <linux/vs_context.h> |
15808 |
+ |
15809 |
+ #include <asm/pgtable.h> |
15810 |
+ #include <asm/uaccess.h> |
15811 |
+@@ -159,6 +160,11 @@ int __ptrace_may_access(struct task_stru |
15812 |
+ dumpable = get_dumpable(task->mm); |
15813 |
+ if (!dumpable && !capable(CAP_SYS_PTRACE)) |
15814 |
+ return -EPERM; |
15815 |
++ if (!vx_check(task->xid, VS_ADMIN_P|VS_IDENT)) |
15816 |
++ return -EPERM; |
15817 |
++ if (!vx_check(task->xid, VS_IDENT) && |
15818 |
++ !task_vx_flags(task, VXF_STATE_ADMIN, 0)) |
15819 |
++ return -EACCES; |
15820 |
+ |
15821 |
+ return security_ptrace_may_access(task, mode); |
15822 |
+ } |
15823 |
+@@ -596,6 +602,10 @@ SYSCALL_DEFINE4(ptrace, long, request, l |
15824 |
+ goto out; |
15825 |
+ } |
15826 |
+ |
15827 |
++ ret = -EPERM; |
15828 |
++ if (!vx_check(vx_task_xid(child), VS_WATCH_P | VS_IDENT)) |
15829 |
++ goto out_put_task_struct; |
15830 |
++ |
15831 |
+ if (request == PTRACE_ATTACH) { |
15832 |
+ ret = ptrace_attach(child); |
15833 |
+ /* |
15834 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/sched.c linux-2.6.29.4-vs2.3.0.36.14/kernel/sched.c |
15835 |
+--- linux-2.6.29.4/kernel/sched.c 2009-05-23 23:16:53.000000000 +0200 |
15836 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/sched.c 2009-05-10 23:42:01.000000000 +0200 |
15837 |
+@@ -72,6 +72,8 @@ |
15838 |
+ #include <linux/debugfs.h> |
15839 |
+ #include <linux/ctype.h> |
15840 |
+ #include <linux/ftrace.h> |
15841 |
++#include <linux/vs_sched.h> |
15842 |
++#include <linux/vs_cvirt.h> |
15843 |
+ #include <trace/sched.h> |
15844 |
+ |
15845 |
+ #include <asm/tlb.h> |
15846 |
+@@ -617,6 +619,16 @@ struct rq { |
15847 |
+ #endif |
15848 |
+ struct hrtimer hrtick_timer; |
15849 |
+ #endif |
15850 |
++ unsigned long norm_time; |
15851 |
++ unsigned long idle_time; |
15852 |
++#ifdef CONFIG_VSERVER_IDLETIME |
15853 |
++ int idle_skip; |
15854 |
++#endif |
15855 |
++#ifdef CONFIG_VSERVER_HARDCPU |
15856 |
++ struct list_head hold_queue; |
15857 |
++ unsigned long nr_onhold; |
15858 |
++ int idle_tokens; |
15859 |
++#endif |
15860 |
+ |
15861 |
+ #ifdef CONFIG_SCHEDSTATS |
15862 |
+ /* latency stats */ |
15863 |
+@@ -1713,6 +1725,7 @@ static void update_avg(u64 *avg, u64 sam |
15864 |
+ |
15865 |
+ static void enqueue_task(struct rq *rq, struct task_struct *p, int wakeup) |
15866 |
+ { |
15867 |
++ // BUG_ON(p->state & TASK_ONHOLD); |
15868 |
+ sched_info_queued(p); |
15869 |
+ p->sched_class->enqueue_task(rq, p, wakeup); |
15870 |
+ p->se.on_rq = 1; |
15871 |
+@@ -1836,6 +1849,8 @@ static inline void check_class_changed(s |
15872 |
+ p->sched_class->prio_changed(rq, p, oldprio, running); |
15873 |
+ } |
15874 |
+ |
15875 |
++#include "sched_mon.h" |
15876 |
++ |
15877 |
+ #ifdef CONFIG_SMP |
15878 |
+ |
15879 |
+ /* Used instead of source_load when we know the type == 0 */ |
15880 |
+@@ -1923,6 +1938,7 @@ migrate_task(struct task_struct *p, int |
15881 |
+ { |
15882 |
+ struct rq *rq = task_rq(p); |
15883 |
+ |
15884 |
++ vxm_migrate_task(p, rq, dest_cpu); |
15885 |
+ /* |
15886 |
+ * If the task is not on a runqueue (and not running), then |
15887 |
+ * it is sufficient to simply update the task's cpu field. |
15888 |
+@@ -2250,6 +2266,8 @@ static int sched_balance_self(int cpu, i |
15889 |
+ |
15890 |
+ #endif /* CONFIG_SMP */ |
15891 |
+ |
15892 |
++#include "sched_hard.h" |
15893 |
++ |
15894 |
+ /*** |
15895 |
+ * try_to_wake_up - wake up a thread |
15896 |
+ * @p: the to-be-woken-up thread |
15897 |
+@@ -2294,6 +2312,13 @@ static int try_to_wake_up(struct task_st |
15898 |
+ rq = task_rq_lock(p, &flags); |
15899 |
+ update_rq_clock(rq); |
15900 |
+ old_state = p->state; |
15901 |
++ |
15902 |
++ /* we need to unhold suspended tasks */ |
15903 |
++ if (old_state & TASK_ONHOLD) { |
15904 |
++ vx_unhold_task(p, rq); |
15905 |
++ old_state = p->state; |
15906 |
++ } |
15907 |
++ |
15908 |
+ if (!(old_state & state)) |
15909 |
+ goto out; |
15910 |
+ |
15911 |
+@@ -2315,6 +2340,12 @@ static int try_to_wake_up(struct task_st |
15912 |
+ /* might preempt at this point */ |
15913 |
+ rq = task_rq_lock(p, &flags); |
15914 |
+ old_state = p->state; |
15915 |
++ |
15916 |
++ /* we need to unhold suspended tasks |
15917 |
++ if (old_state & TASK_ONHOLD) { |
15918 |
++ vx_unhold_task(p, rq); |
15919 |
++ old_state = p->state; |
15920 |
++ } */ |
15921 |
+ if (!(old_state & state)) |
15922 |
+ goto out; |
15923 |
+ if (p->se.on_rq) |
15924 |
+@@ -4226,16 +4257,19 @@ void account_user_time(struct task_struc |
15925 |
+ cputime_t cputime_scaled) |
15926 |
+ { |
15927 |
+ struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; |
15928 |
++ struct vx_info *vxi = p->vx_info; /* p is _always_ current */ |
15929 |
+ cputime64_t tmp; |
15930 |
++ int nice = (TASK_NICE(p) > 0); |
15931 |
+ |
15932 |
+ /* Add user time to process. */ |
15933 |
+ p->utime = cputime_add(p->utime, cputime); |
15934 |
+ p->utimescaled = cputime_add(p->utimescaled, cputime_scaled); |
15935 |
++ vx_account_user(vxi, cputime, nice); |
15936 |
+ account_group_user_time(p, cputime); |
15937 |
+ |
15938 |
+ /* Add user time to cpustat. */ |
15939 |
+ tmp = cputime_to_cputime64(cputime); |
15940 |
+- if (TASK_NICE(p) > 0) |
15941 |
++ if (nice) |
15942 |
+ cpustat->nice = cputime64_add(cpustat->nice, tmp); |
15943 |
+ else |
15944 |
+ cpustat->user = cputime64_add(cpustat->user, tmp); |
15945 |
+@@ -4279,6 +4313,7 @@ void account_system_time(struct task_str |
15946 |
+ cputime_t cputime, cputime_t cputime_scaled) |
15947 |
+ { |
15948 |
+ struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; |
15949 |
++ struct vx_info *vxi = p->vx_info; /* p is _always_ current */ |
15950 |
+ cputime64_t tmp; |
15951 |
+ |
15952 |
+ if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) { |
15953 |
+@@ -4289,6 +4324,7 @@ void account_system_time(struct task_str |
15954 |
+ /* Add system time to process. */ |
15955 |
+ p->stime = cputime_add(p->stime, cputime); |
15956 |
+ p->stimescaled = cputime_add(p->stimescaled, cputime_scaled); |
15957 |
++ vx_account_system(vxi, cputime, 0 /* do we have idle time? */); |
15958 |
+ account_group_system_time(p, cputime); |
15959 |
+ |
15960 |
+ /* Add system time to cpustat. */ |
15961 |
+@@ -4644,6 +4680,11 @@ need_resched_nonpreemptible: |
15962 |
+ idle_balance(cpu, rq); |
15963 |
+ |
15964 |
+ prev->sched_class->put_prev_task(rq, prev); |
15965 |
++ |
15966 |
++ vx_set_rq_time(rq, jiffies); /* update time */ |
15967 |
++ vx_schedule(prev, rq, cpu); /* hold if over limit */ |
15968 |
++ vx_try_unhold(rq, cpu); /* unhold if refilled */ |
15969 |
++ |
15970 |
+ next = pick_next_task(rq, prev); |
15971 |
+ |
15972 |
+ if (likely(prev != next)) { |
15973 |
+@@ -5209,7 +5250,7 @@ SYSCALL_DEFINE1(nice, int, increment) |
15974 |
+ nice = 19; |
15975 |
+ |
15976 |
+ if (increment < 0 && !can_nice(current, nice)) |
15977 |
+- return -EPERM; |
15978 |
++ return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM; |
15979 |
+ |
15980 |
+ retval = security_task_setnice(current, nice); |
15981 |
+ if (retval) |
15982 |
+@@ -8485,7 +8526,10 @@ void __init sched_init(void) |
15983 |
+ |
15984 |
+ #endif |
15985 |
+ #endif /* CONFIG_FAIR_GROUP_SCHED */ |
15986 |
+- |
15987 |
++#ifdef CONFIG_VSERVER_HARDCPU |
15988 |
++ INIT_LIST_HEAD(&rq->hold_queue); |
15989 |
++ rq->nr_onhold = 0; |
15990 |
++#endif |
15991 |
+ rq->rt.rt_runtime = def_rt_bandwidth.rt_runtime; |
15992 |
+ #ifdef CONFIG_RT_GROUP_SCHED |
15993 |
+ INIT_LIST_HEAD(&rq->leaf_rt_rq_list); |
15994 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/sched_fair.c linux-2.6.29.4-vs2.3.0.36.14/kernel/sched_fair.c |
15995 |
+--- linux-2.6.29.4/kernel/sched_fair.c 2009-03-24 14:22:45.000000000 +0100 |
15996 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/sched_fair.c 2009-03-24 14:48:36.000000000 +0100 |
15997 |
+@@ -717,6 +717,9 @@ enqueue_entity(struct cfs_rq *cfs_rq, st |
15998 |
+ check_spread(cfs_rq, se); |
15999 |
+ if (se != cfs_rq->curr) |
16000 |
+ __enqueue_entity(cfs_rq, se); |
16001 |
++ |
16002 |
++ if (entity_is_task(se)) |
16003 |
++ vx_activate_task(task_of(se)); |
16004 |
+ } |
16005 |
+ |
16006 |
+ static void __clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se) |
16007 |
+@@ -760,6 +763,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, st |
16008 |
+ |
16009 |
+ if (se != cfs_rq->curr) |
16010 |
+ __dequeue_entity(cfs_rq, se); |
16011 |
++ if (entity_is_task(se)) |
16012 |
++ vx_deactivate_task(task_of(se)); |
16013 |
+ account_entity_dequeue(cfs_rq, se); |
16014 |
+ update_min_vruntime(cfs_rq); |
16015 |
+ } |
16016 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/sched_hard.h linux-2.6.29.4-vs2.3.0.36.14/kernel/sched_hard.h |
16017 |
+--- linux-2.6.29.4/kernel/sched_hard.h 1970-01-01 01:00:00.000000000 +0100 |
16018 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/sched_hard.h 2009-02-22 22:54:26.000000000 +0100 |
16019 |
+@@ -0,0 +1,353 @@ |
16020 |
++ |
16021 |
++#ifdef CONFIG_VSERVER_IDLELIMIT |
16022 |
++ |
16023 |
++/* |
16024 |
++ * vx_idle_resched - reschedule after maxidle |
16025 |
++ */ |
16026 |
++static inline |
16027 |
++void vx_idle_resched(struct rq *rq) |
16028 |
++{ |
16029 |
++ /* maybe have a better criterion for paused */ |
16030 |
++ if (!--rq->idle_tokens && !list_empty(&rq->hold_queue)) |
16031 |
++ set_need_resched(); |
16032 |
++} |
16033 |
++ |
16034 |
++#else /* !CONFIG_VSERVER_IDLELIMIT */ |
16035 |
++ |
16036 |
++#define vx_idle_resched(rq) |
16037 |
++ |
16038 |
++#endif /* CONFIG_VSERVER_IDLELIMIT */ |
16039 |
++ |
16040 |
++ |
16041 |
++ |
16042 |
++#ifdef CONFIG_VSERVER_IDLETIME |
16043 |
++ |
16044 |
++#define vx_set_rq_min_skip(rq, min) \ |
16045 |
++ (rq)->idle_skip = (min) |
16046 |
++ |
16047 |
++#define vx_save_min_skip(ret, min, val) \ |
16048 |
++ __vx_save_min_skip(ret, min, val) |
16049 |
++ |
16050 |
++static inline |
16051 |
++void __vx_save_min_skip(int ret, int *min, int val) |
16052 |
++{ |
16053 |
++ if (ret > -2) |
16054 |
++ return; |
16055 |
++ if ((*min > val) || !*min) |
16056 |
++ *min = val; |
16057 |
++} |
16058 |
++ |
16059 |
++static inline |
16060 |
++int vx_try_skip(struct rq *rq, int cpu) |
16061 |
++{ |
16062 |
++ /* artificially advance time */ |
16063 |
++ if (rq->idle_skip > 0) { |
16064 |
++ vxdprintk(list_empty(&rq->hold_queue), |
16065 |
++ "hold queue empty on cpu %d", cpu); |
16066 |
++ rq->idle_time += rq->idle_skip; |
16067 |
++ vxm_idle_skip(rq, cpu); |
16068 |
++ return 1; |
16069 |
++ } |
16070 |
++ return 0; |
16071 |
++} |
16072 |
++ |
16073 |
++#else /* !CONFIG_VSERVER_IDLETIME */ |
16074 |
++ |
16075 |
++#define vx_set_rq_min_skip(rq, min) \ |
16076 |
++ ({ int dummy = (min); dummy; }) |
16077 |
++ |
16078 |
++#define vx_save_min_skip(ret, min, val) |
16079 |
++ |
16080 |
++static inline |
16081 |
++int vx_try_skip(struct rq *rq, int cpu) |
16082 |
++{ |
16083 |
++ return 0; |
16084 |
++} |
16085 |
++ |
16086 |
++#endif /* CONFIG_VSERVER_IDLETIME */ |
16087 |
++ |
16088 |
++ |
16089 |
++ |
16090 |
++#ifdef CONFIG_VSERVER_HARDCPU |
16091 |
++ |
16092 |
++#define vx_set_rq_max_idle(rq, max) \ |
16093 |
++ (rq)->idle_tokens = (max) |
16094 |
++ |
16095 |
++#define vx_save_max_idle(ret, min, val) \ |
16096 |
++ __vx_save_max_idle(ret, min, val) |
16097 |
++ |
16098 |
++static inline |
16099 |
++void __vx_save_max_idle(int ret, int *min, int val) |
16100 |
++{ |
16101 |
++ if (*min > val) |
16102 |
++ *min = val; |
16103 |
++} |
16104 |
++ |
16105 |
++ |
16106 |
++/* |
16107 |
++ * vx_hold_task - put a task on the hold queue |
16108 |
++ */ |
16109 |
++static inline |
16110 |
++void vx_hold_task(struct task_struct *p, struct rq *rq) |
16111 |
++{ |
16112 |
++ // printk("@ hold_task(%p[%lx])\n", p, p->state); |
16113 |
++ |
16114 |
++ /* ignore dead/killed tasks */ |
16115 |
++ if (unlikely(p->state & (TASK_DEAD | TASK_WAKEKILL))) |
16116 |
++ return; |
16117 |
++ |
16118 |
++ /* ignore sleeping tasks */ |
16119 |
++ if (unlikely(p->state & TASK_NORMAL)) |
16120 |
++ return; |
16121 |
++ |
16122 |
++ /* remove task from runqueue */ |
16123 |
++ if (likely(p->se.on_rq)) |
16124 |
++ dequeue_task(rq, p, 0); |
16125 |
++ else |
16126 |
++ printk("@ woops, task %p not on runqueue?\n", p); |
16127 |
++ |
16128 |
++ p->state |= TASK_ONHOLD; |
16129 |
++ /* a new one on hold */ |
16130 |
++ rq->nr_onhold++; |
16131 |
++ vxm_hold_task(p, rq); |
16132 |
++ list_add_tail(&p->hq, &rq->hold_queue); |
16133 |
++ // list_add_tail(&p->run_list, &rq->hold_queue); |
16134 |
++} |
16135 |
++ |
16136 |
++/* |
16137 |
++ * vx_unhold_task - put a task back to the runqueue |
16138 |
++ */ |
16139 |
++static inline |
16140 |
++void vx_unhold_task(struct task_struct *p, struct rq *rq) |
16141 |
++{ |
16142 |
++ // printk("@ unhold_task(%p[%lx])\n", p, p->state); |
16143 |
++ list_del_init(&p->hq); |
16144 |
++ // list_del(&p->run_list); |
16145 |
++ /* one less waiting */ |
16146 |
++ rq->nr_onhold--; |
16147 |
++ p->state &= ~TASK_ONHOLD; |
16148 |
++ enqueue_task(rq, p, 0); |
16149 |
++ // ? inc_nr_running(p, rq); |
16150 |
++ vxm_unhold_task(p, rq); |
16151 |
++} |
16152 |
++ |
16153 |
++/* |
16154 |
++ * vx_remove_hold - remove a task from the hold queue |
16155 |
++ */ |
16156 |
++static inline |
16157 |
++void vx_remove_hold(struct task_struct *p, struct rq *rq) |
16158 |
++{ |
16159 |
++ printk("@ remove_hold(%p[%lx])\n", p, p->state); |
16160 |
++ list_del_init(&p->hq); |
16161 |
++ // list_del(&p->run_list); |
16162 |
++ /* one less waiting */ |
16163 |
++ rq->nr_onhold--; |
16164 |
++ p->state &= ~TASK_ONHOLD; |
16165 |
++} |
16166 |
++ |
16167 |
++unsigned long nr_onhold(void) |
16168 |
++{ |
16169 |
++ unsigned long i, sum = 0; |
16170 |
++ |
16171 |
++ for_each_online_cpu(i) |
16172 |
++ sum += cpu_rq(i)->nr_onhold; |
16173 |
++ |
16174 |
++ return sum; |
16175 |
++} |
16176 |
++ |
16177 |
++ |
16178 |
++ |
16179 |
++static inline |
16180 |
++int __vx_tokens_avail(struct _vx_sched_pc *sched_pc) |
16181 |
++{ |
16182 |
++ return sched_pc->tokens; |
16183 |
++} |
16184 |
++ |
16185 |
++static inline |
16186 |
++void __vx_consume_token(struct _vx_sched_pc *sched_pc) |
16187 |
++{ |
16188 |
++ sched_pc->tokens--; |
16189 |
++} |
16190 |
++ |
16191 |
++static inline |
16192 |
++int vx_need_resched(struct task_struct *p, int slice, int cpu) |
16193 |
++{ |
16194 |
++ struct vx_info *vxi = p->vx_info; |
16195 |
++ |
16196 |
++ if (vx_info_flags(vxi, VXF_SCHED_HARD|VXF_SCHED_PRIO, 0)) { |
16197 |
++ struct _vx_sched_pc *sched_pc = |
16198 |
++ &vx_per_cpu(vxi, sched_pc, cpu); |
16199 |
++ int tokens; |
16200 |
++ |
16201 |
++ /* maybe we can simplify that to decrement |
16202 |
++ the token counter unconditional? */ |
16203 |
++ |
16204 |
++ if ((tokens = __vx_tokens_avail(sched_pc)) > 0) |
16205 |
++ __vx_consume_token(sched_pc); |
16206 |
++ |
16207 |
++ /* for tokens > 0, one token was consumed */ |
16208 |
++ if (tokens < 2) |
16209 |
++ slice = 0; |
16210 |
++ } |
16211 |
++ vxm_need_resched(p, slice, cpu); |
16212 |
++ return (slice == 0); |
16213 |
++} |
16214 |
++ |
16215 |
++ |
16216 |
++#define vx_set_rq_time(rq, time) do { \ |
16217 |
++ rq->norm_time = time; \ |
16218 |
++} while (0) |
16219 |
++ |
16220 |
++ |
16221 |
++static inline |
16222 |
++void vx_try_unhold(struct rq *rq, int cpu) |
16223 |
++{ |
16224 |
++ struct vx_info *vxi = NULL; |
16225 |
++ struct list_head *l, *n; |
16226 |
++ int maxidle = HZ; |
16227 |
++ int minskip = 0; |
16228 |
++ |
16229 |
++ /* nothing to do? what about pause? */ |
16230 |
++ if (list_empty(&rq->hold_queue)) |
16231 |
++ return; |
16232 |
++ |
16233 |
++ list_for_each_safe(l, n, &rq->hold_queue) { |
16234 |
++ int ret, delta_min[2]; |
16235 |
++ struct _vx_sched_pc *sched_pc; |
16236 |
++ struct task_struct *p; |
16237 |
++ |
16238 |
++ p = list_entry(l, struct task_struct, hq); |
16239 |
++ /* don't bother with same context */ |
16240 |
++ if (vxi == p->vx_info) |
16241 |
++ continue; |
16242 |
++ |
16243 |
++ vxi = p->vx_info; |
16244 |
++ /* ignore paused contexts */ |
16245 |
++ if (vx_info_flags(vxi, VXF_SCHED_PAUSE, 0)) |
16246 |
++ continue; |
16247 |
++ |
16248 |
++ sched_pc = &vx_per_cpu(vxi, sched_pc, cpu); |
16249 |
++ |
16250 |
++ /* recalc tokens */ |
16251 |
++ vxm_sched_info(sched_pc, vxi, cpu); |
16252 |
++ ret = vx_tokens_recalc(sched_pc, |
16253 |
++ &rq->norm_time, &rq->idle_time, delta_min); |
16254 |
++ vxm_tokens_recalc(sched_pc, rq, vxi, cpu); |
16255 |
++ |
16256 |
++ if (ret > 0) { |
16257 |
++ /* we found a runable context */ |
16258 |
++ vx_unhold_task(p, rq); |
16259 |
++ break; |
16260 |
++ } |
16261 |
++ vx_save_max_idle(ret, &maxidle, delta_min[0]); |
16262 |
++ vx_save_min_skip(ret, &minskip, delta_min[1]); |
16263 |
++ } |
16264 |
++ vx_set_rq_max_idle(rq, maxidle); |
16265 |
++ vx_set_rq_min_skip(rq, minskip); |
16266 |
++ vxm_rq_max_min(rq, cpu); |
16267 |
++} |
16268 |
++ |
16269 |
++ |
16270 |
++static inline |
16271 |
++int vx_schedule(struct task_struct *next, struct rq *rq, int cpu) |
16272 |
++{ |
16273 |
++ struct vx_info *vxi = next->vx_info; |
16274 |
++ struct _vx_sched_pc *sched_pc; |
16275 |
++ int delta_min[2]; |
16276 |
++ int flags, ret; |
16277 |
++ |
16278 |
++ if (!vxi) |
16279 |
++ return 1; |
16280 |
++ |
16281 |
++ flags = vxi->vx_flags; |
16282 |
++ |
16283 |
++ if (unlikely(vs_check_flags(flags, VXF_SCHED_PAUSE, 0))) |
16284 |
++ goto put_on_hold; |
16285 |
++ if (!vs_check_flags(flags, VXF_SCHED_HARD | VXF_SCHED_PRIO, 0)) |
16286 |
++ return 1; |
16287 |
++ |
16288 |
++ sched_pc = &vx_per_cpu(vxi, sched_pc, cpu); |
16289 |
++#ifdef CONFIG_SMP |
16290 |
++ /* update scheduler params */ |
16291 |
++ if (cpu_isset(cpu, vxi->sched.update)) { |
16292 |
++ vx_update_sched_param(&vxi->sched, sched_pc); |
16293 |
++ vxm_update_sched(sched_pc, vxi, cpu); |
16294 |
++ cpu_clear(cpu, vxi->sched.update); |
16295 |
++ } |
16296 |
++#endif |
16297 |
++ vxm_sched_info(sched_pc, vxi, cpu); |
16298 |
++ ret = vx_tokens_recalc(sched_pc, |
16299 |
++ &rq->norm_time, &rq->idle_time, delta_min); |
16300 |
++ vxm_tokens_recalc(sched_pc, rq, vxi, cpu); |
16301 |
++ |
16302 |
++ if (!vs_check_flags(flags, VXF_SCHED_HARD, 0)) |
16303 |
++ return 1; |
16304 |
++ |
16305 |
++ if (unlikely(ret < 0)) { |
16306 |
++ vx_save_max_idle(ret, &rq->idle_tokens, delta_min[0]); |
16307 |
++ vx_save_min_skip(ret, &rq->idle_skip, delta_min[1]); |
16308 |
++ vxm_rq_max_min(rq, cpu); |
16309 |
++ put_on_hold: |
16310 |
++ vx_hold_task(next, rq); |
16311 |
++ return 0; |
16312 |
++ } |
16313 |
++ return 1; |
16314 |
++} |
16315 |
++ |
16316 |
++ |
16317 |
++#else /* CONFIG_VSERVER_HARDCPU */ |
16318 |
++ |
16319 |
++static inline |
16320 |
++void vx_hold_task(struct task_struct *p, struct rq *rq) |
16321 |
++{ |
16322 |
++ return; |
16323 |
++} |
16324 |
++ |
16325 |
++static inline |
16326 |
++void vx_unhold_task(struct task_struct *p, struct rq *rq) |
16327 |
++{ |
16328 |
++ return; |
16329 |
++} |
16330 |
++ |
16331 |
++unsigned long nr_onhold(void) |
16332 |
++{ |
16333 |
++ return 0; |
16334 |
++} |
16335 |
++ |
16336 |
++ |
16337 |
++static inline |
16338 |
++int vx_need_resched(struct task_struct *p, int slice, int cpu) |
16339 |
++{ |
16340 |
++ return (slice == 0); |
16341 |
++} |
16342 |
++ |
16343 |
++ |
16344 |
++#define vx_set_rq_time(rq, time) |
16345 |
++ |
16346 |
++static inline |
16347 |
++void vx_try_unhold(struct rq *rq, int cpu) |
16348 |
++{ |
16349 |
++ return; |
16350 |
++} |
16351 |
++ |
16352 |
++static inline |
16353 |
++int vx_schedule(struct task_struct *next, struct rq *rq, int cpu) |
16354 |
++{ |
16355 |
++ struct vx_info *vxi = next->vx_info; |
16356 |
++ struct _vx_sched_pc *sched_pc; |
16357 |
++ int delta_min[2]; |
16358 |
++ int ret; |
16359 |
++ |
16360 |
++ if (!vx_info_flags(vxi, VXF_SCHED_PRIO, 0)) |
16361 |
++ return 1; |
16362 |
++ |
16363 |
++ sched_pc = &vx_per_cpu(vxi, sched_pc, cpu); |
16364 |
++ vxm_sched_info(sched_pc, vxi, cpu); |
16365 |
++ ret = vx_tokens_recalc(sched_pc, |
16366 |
++ &rq->norm_time, &rq->idle_time, delta_min); |
16367 |
++ vxm_tokens_recalc(sched_pc, rq, vxi, cpu); |
16368 |
++ return 1; |
16369 |
++} |
16370 |
++ |
16371 |
++#endif /* CONFIG_VSERVER_HARDCPU */ |
16372 |
++ |
16373 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/sched_mon.h linux-2.6.29.4-vs2.3.0.36.14/kernel/sched_mon.h |
16374 |
+--- linux-2.6.29.4/kernel/sched_mon.h 1970-01-01 01:00:00.000000000 +0100 |
16375 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/sched_mon.h 2009-02-22 22:54:26.000000000 +0100 |
16376 |
+@@ -0,0 +1,200 @@ |
16377 |
++ |
16378 |
++#include <linux/vserver/monitor.h> |
16379 |
++ |
16380 |
++#ifdef CONFIG_VSERVER_MONITOR |
16381 |
++ |
16382 |
++#ifdef CONFIG_VSERVER_HARDCPU |
16383 |
++#define HARDCPU(x) (x) |
16384 |
++#else |
16385 |
++#define HARDCPU(x) (0) |
16386 |
++#endif |
16387 |
++ |
16388 |
++#ifdef CONFIG_VSERVER_IDLETIME |
16389 |
++#define IDLETIME(x) (x) |
16390 |
++#else |
16391 |
++#define IDLETIME(x) (0) |
16392 |
++#endif |
16393 |
++ |
16394 |
++struct _vx_mon_entry *vxm_advance(int cpu); |
16395 |
++ |
16396 |
++ |
16397 |
++static inline |
16398 |
++void __vxm_basic(struct _vx_mon_entry *entry, xid_t xid, int type) |
16399 |
++{ |
16400 |
++ entry->type = type; |
16401 |
++ entry->xid = xid; |
16402 |
++} |
16403 |
++ |
16404 |
++static inline |
16405 |
++void __vxm_sync(int cpu) |
16406 |
++{ |
16407 |
++ struct _vx_mon_entry *entry = vxm_advance(cpu); |
16408 |
++ |
16409 |
++ __vxm_basic(entry, 0, VXM_SYNC); |
16410 |
++ entry->ev.sec = xtime.tv_sec; |
16411 |
++ entry->ev.nsec = xtime.tv_nsec; |
16412 |
++} |
16413 |
++ |
16414 |
++static inline |
16415 |
++void __vxm_task(struct task_struct *p, int type) |
16416 |
++{ |
16417 |
++ struct _vx_mon_entry *entry = vxm_advance(task_cpu(p)); |
16418 |
++ |
16419 |
++ __vxm_basic(entry, p->xid, type); |
16420 |
++ entry->ev.tsk.pid = p->pid; |
16421 |
++ entry->ev.tsk.state = p->state; |
16422 |
++} |
16423 |
++ |
16424 |
++static inline |
16425 |
++void __vxm_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu) |
16426 |
++{ |
16427 |
++ struct _vx_mon_entry *entry = vxm_advance(cpu); |
16428 |
++ |
16429 |
++ __vxm_basic(entry, vxi->vx_id, (VXM_SCHED | s->flags)); |
16430 |
++ entry->sd.tokens = s->tokens; |
16431 |
++ entry->sd.norm_time = s->norm_time; |
16432 |
++ entry->sd.idle_time = s->idle_time; |
16433 |
++} |
16434 |
++ |
16435 |
++static inline |
16436 |
++void __vxm_rqinfo1(struct rq *q, int cpu) |
16437 |
++{ |
16438 |
++ struct _vx_mon_entry *entry = vxm_advance(cpu); |
16439 |
++ |
16440 |
++ entry->type = VXM_RQINFO_1; |
16441 |
++ entry->xid = ((unsigned long)q >> 16) & 0xffff; |
16442 |
++ entry->q1.running = q->nr_running; |
16443 |
++ entry->q1.onhold = HARDCPU(q->nr_onhold); |
16444 |
++ entry->q1.iowait = atomic_read(&q->nr_iowait); |
16445 |
++ entry->q1.uintr = q->nr_uninterruptible; |
16446 |
++ entry->q1.idle_tokens = IDLETIME(q->idle_tokens); |
16447 |
++} |
16448 |
++ |
16449 |
++static inline |
16450 |
++void __vxm_rqinfo2(struct rq *q, int cpu) |
16451 |
++{ |
16452 |
++ struct _vx_mon_entry *entry = vxm_advance(cpu); |
16453 |
++ |
16454 |
++ entry->type = VXM_RQINFO_2; |
16455 |
++ entry->xid = (unsigned long)q & 0xffff; |
16456 |
++ entry->q2.norm_time = q->norm_time; |
16457 |
++ entry->q2.idle_time = q->idle_time; |
16458 |
++ entry->q2.idle_skip = IDLETIME(q->idle_skip); |
16459 |
++} |
16460 |
++ |
16461 |
++static inline |
16462 |
++void __vxm_update(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu) |
16463 |
++{ |
16464 |
++ struct _vx_mon_entry *entry = vxm_advance(cpu); |
16465 |
++ |
16466 |
++ __vxm_basic(entry, vxi->vx_id, VXM_UPDATE); |
16467 |
++ entry->ev.tokens = s->tokens; |
16468 |
++} |
16469 |
++ |
16470 |
++static inline |
16471 |
++void __vxm_update1(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu) |
16472 |
++{ |
16473 |
++ struct _vx_mon_entry *entry = vxm_advance(cpu); |
16474 |
++ |
16475 |
++ __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_1); |
16476 |
++ entry->u1.tokens_max = s->tokens_max; |
16477 |
++ entry->u1.fill_rate = s->fill_rate[0]; |
16478 |
++ entry->u1.interval = s->interval[0]; |
16479 |
++} |
16480 |
++ |
16481 |
++static inline |
16482 |
++void __vxm_update2(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu) |
16483 |
++{ |
16484 |
++ struct _vx_mon_entry *entry = vxm_advance(cpu); |
16485 |
++ |
16486 |
++ __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_2); |
16487 |
++ entry->u2.tokens_min = s->tokens_min; |
16488 |
++ entry->u2.fill_rate = s->fill_rate[1]; |
16489 |
++ entry->u2.interval = s->interval[1]; |
16490 |
++} |
16491 |
++ |
16492 |
++ |
16493 |
++#define vxm_activate_task(p,q) __vxm_task(p, VXM_ACTIVATE) |
16494 |
++#define vxm_activate_idle(p,q) __vxm_task(p, VXM_IDLE) |
16495 |
++#define vxm_deactivate_task(p,q) __vxm_task(p, VXM_DEACTIVATE) |
16496 |
++#define vxm_hold_task(p,q) __vxm_task(p, VXM_HOLD) |
16497 |
++#define vxm_unhold_task(p,q) __vxm_task(p, VXM_UNHOLD) |
16498 |
++ |
16499 |
++static inline |
16500 |
++void vxm_migrate_task(struct task_struct *p, struct rq *rq, int dest) |
16501 |
++{ |
16502 |
++ __vxm_task(p, VXM_MIGRATE); |
16503 |
++ __vxm_rqinfo1(rq, task_cpu(p)); |
16504 |
++ __vxm_rqinfo2(rq, task_cpu(p)); |
16505 |
++} |
16506 |
++ |
16507 |
++static inline |
16508 |
++void vxm_idle_skip(struct rq *rq, int cpu) |
16509 |
++{ |
16510 |
++ __vxm_rqinfo1(rq, cpu); |
16511 |
++ __vxm_rqinfo2(rq, cpu); |
16512 |
++} |
16513 |
++ |
16514 |
++static inline |
16515 |
++void vxm_need_resched(struct task_struct *p, int slice, int cpu) |
16516 |
++{ |
16517 |
++ if (slice) |
16518 |
++ return; |
16519 |
++ |
16520 |
++ __vxm_task(p, VXM_RESCHED); |
16521 |
++} |
16522 |
++ |
16523 |
++static inline |
16524 |
++void vxm_sync(unsigned long now, int cpu) |
16525 |
++{ |
16526 |
++ if (!CONFIG_VSERVER_MONITOR_SYNC || |
16527 |
++ (now % CONFIG_VSERVER_MONITOR_SYNC)) |
16528 |
++ return; |
16529 |
++ |
16530 |
++ __vxm_sync(cpu); |
16531 |
++} |
16532 |
++ |
16533 |
++#define vxm_sched_info(s,v,c) __vxm_sched(s,v,c) |
16534 |
++ |
16535 |
++static inline |
16536 |
++void vxm_tokens_recalc(struct _vx_sched_pc *s, struct rq *rq, |
16537 |
++ struct vx_info *vxi, int cpu) |
16538 |
++{ |
16539 |
++ __vxm_sched(s, vxi, cpu); |
16540 |
++ __vxm_rqinfo2(rq, cpu); |
16541 |
++} |
16542 |
++ |
16543 |
++static inline |
16544 |
++void vxm_update_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu) |
16545 |
++{ |
16546 |
++ __vxm_sched(s, vxi, cpu); |
16547 |
++ __vxm_update(s, vxi, cpu); |
16548 |
++ __vxm_update1(s, vxi, cpu); |
16549 |
++ __vxm_update2(s, vxi, cpu); |
16550 |
++} |
16551 |
++ |
16552 |
++static inline |
16553 |
++void vxm_rq_max_min(struct rq *rq, int cpu) |
16554 |
++{ |
16555 |
++ __vxm_rqinfo1(rq, cpu); |
16556 |
++ __vxm_rqinfo2(rq, cpu); |
16557 |
++} |
16558 |
++ |
16559 |
++#else /* CONFIG_VSERVER_MONITOR */ |
16560 |
++ |
16561 |
++#define vxm_activate_task(t,q) do { } while (0) |
16562 |
++#define vxm_activate_idle(t,q) do { } while (0) |
16563 |
++#define vxm_deactivate_task(t,q) do { } while (0) |
16564 |
++#define vxm_hold_task(t,q) do { } while (0) |
16565 |
++#define vxm_unhold_task(t,q) do { } while (0) |
16566 |
++#define vxm_migrate_task(t,q,d) do { } while (0) |
16567 |
++#define vxm_idle_skip(q,c) do { } while (0) |
16568 |
++#define vxm_need_resched(t,s,c) do { } while (0) |
16569 |
++#define vxm_sync(s,c) do { } while (0) |
16570 |
++#define vxm_sched_info(s,v,c) do { } while (0) |
16571 |
++#define vxm_tokens_recalc(s,q,v,c) do { } while (0) |
16572 |
++#define vxm_update_sched(s,v,c) do { } while (0) |
16573 |
++#define vxm_rq_max_min(q,c) do { } while (0) |
16574 |
++ |
16575 |
++#endif /* CONFIG_VSERVER_MONITOR */ |
16576 |
++ |
16577 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/signal.c linux-2.6.29.4-vs2.3.0.36.14/kernel/signal.c |
16578 |
+--- linux-2.6.29.4/kernel/signal.c 2009-03-24 14:22:45.000000000 +0100 |
16579 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/signal.c 2009-04-20 23:37:12.000000000 +0200 |
16580 |
+@@ -27,6 +27,8 @@ |
16581 |
+ #include <linux/freezer.h> |
16582 |
+ #include <linux/pid_namespace.h> |
16583 |
+ #include <linux/nsproxy.h> |
16584 |
++#include <linux/vs_context.h> |
16585 |
++#include <linux/vs_pid.h> |
16586 |
+ #include <trace/sched.h> |
16587 |
+ |
16588 |
+ #include <asm/param.h> |
16589 |
+@@ -584,6 +586,14 @@ static int check_kill_permission(int sig |
16590 |
+ if (!valid_signal(sig)) |
16591 |
+ return -EINVAL; |
16592 |
+ |
16593 |
++ if ((info != SEND_SIG_NOINFO) && |
16594 |
++ (is_si_special(info) || !SI_FROMUSER(info))) |
16595 |
++ goto skip; |
16596 |
++ |
16597 |
++ vxdprintk(VXD_CBIT(misc, 7), |
16598 |
++ "check_kill_permission(%d,%p,%p[#%u,%u])", |
16599 |
++ sig, info, t, vx_task_xid(t), t->pid); |
16600 |
++ |
16601 |
+ if (info != SEND_SIG_NOINFO && (is_si_special(info) || SI_FROMKERNEL(info))) |
16602 |
+ return 0; |
16603 |
+ |
16604 |
+@@ -611,6 +621,20 @@ static int check_kill_permission(int sig |
16605 |
+ } |
16606 |
+ } |
16607 |
+ |
16608 |
++ error = -EPERM; |
16609 |
++ if (t->pid == 1 && current->xid) |
16610 |
++ return error; |
16611 |
++ |
16612 |
++ error = -ESRCH; |
16613 |
++ /* FIXME: we shouldn't return ESRCH ever, to avoid |
16614 |
++ loops, maybe ENOENT or EACCES? */ |
16615 |
++ if (!vx_check(vx_task_xid(t), VS_WATCH_P | VS_IDENT)) { |
16616 |
++ vxdprintk(current->xid || VXD_CBIT(misc, 7), |
16617 |
++ "signal %d[%p] xid mismatch %p[#%u,%u] xid=#%u", |
16618 |
++ sig, info, t, vx_task_xid(t), t->pid, current->xid); |
16619 |
++ return error; |
16620 |
++ } |
16621 |
++skip: |
16622 |
+ return security_task_kill(t, info, sig, 0); |
16623 |
+ } |
16624 |
+ |
16625 |
+@@ -1076,7 +1100,7 @@ int kill_pid_info(int sig, struct siginf |
16626 |
+ rcu_read_lock(); |
16627 |
+ retry: |
16628 |
+ p = pid_task(pid, PIDTYPE_PID); |
16629 |
+- if (p) { |
16630 |
++ if (p && vx_check(vx_task_xid(p), VS_IDENT)) { |
16631 |
+ error = group_send_sig_info(sig, info, p); |
16632 |
+ if (unlikely(error == -ESRCH)) |
16633 |
+ /* |
16634 |
+@@ -1115,7 +1139,7 @@ int kill_pid_info_as_uid(int sig, struct |
16635 |
+ |
16636 |
+ read_lock(&tasklist_lock); |
16637 |
+ p = pid_task(pid, PIDTYPE_PID); |
16638 |
+- if (!p) { |
16639 |
++ if (!p || !vx_check(vx_task_xid(p), VS_IDENT)) { |
16640 |
+ ret = -ESRCH; |
16641 |
+ goto out_unlock; |
16642 |
+ } |
16643 |
+@@ -1169,8 +1193,10 @@ static int kill_something_info(int sig, |
16644 |
+ struct task_struct * p; |
16645 |
+ |
16646 |
+ for_each_process(p) { |
16647 |
+- if (task_pid_vnr(p) > 1 && |
16648 |
+- !same_thread_group(p, current)) { |
16649 |
++ if (vx_check(vx_task_xid(p), VS_ADMIN|VS_IDENT) && |
16650 |
++ task_pid_vnr(p) > 1 && |
16651 |
++ !same_thread_group(p, current) && |
16652 |
++ !vx_current_initpid(p->pid)) { |
16653 |
+ int err = group_send_sig_info(sig, info, p); |
16654 |
+ ++count; |
16655 |
+ if (err != -EPERM) |
16656 |
+@@ -1849,6 +1875,11 @@ relock: |
16657 |
+ !signal_group_exit(signal)) |
16658 |
+ continue; |
16659 |
+ |
16660 |
++ /* virtual init is protected against user signals */ |
16661 |
++ if ((info->si_code == SI_USER) && |
16662 |
++ vx_current_initpid(current->pid)) |
16663 |
++ continue; |
16664 |
++ |
16665 |
+ if (sig_kernel_stop(signr)) { |
16666 |
+ /* |
16667 |
+ * The default action is to stop all threads in |
16668 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/softirq.c linux-2.6.29.4-vs2.3.0.36.14/kernel/softirq.c |
16669 |
+--- linux-2.6.29.4/kernel/softirq.c 2009-05-23 23:16:53.000000000 +0200 |
16670 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/softirq.c 2009-04-30 12:14:53.000000000 +0200 |
16671 |
+@@ -23,6 +23,7 @@ |
16672 |
+ #include <linux/rcupdate.h> |
16673 |
+ #include <linux/smp.h> |
16674 |
+ #include <linux/tick.h> |
16675 |
++#include <linux/vs_context.h> |
16676 |
+ |
16677 |
+ #include <asm/irq.h> |
16678 |
+ /* |
16679 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/sys.c linux-2.6.29.4-vs2.3.0.36.14/kernel/sys.c |
16680 |
+--- linux-2.6.29.4/kernel/sys.c 2009-03-24 14:22:45.000000000 +0100 |
16681 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/sys.c 2009-03-24 14:48:36.000000000 +0100 |
16682 |
+@@ -39,6 +39,7 @@ |
16683 |
+ #include <linux/syscalls.h> |
16684 |
+ #include <linux/kprobes.h> |
16685 |
+ #include <linux/user_namespace.h> |
16686 |
++#include <linux/vs_pid.h> |
16687 |
+ |
16688 |
+ #include <asm/uaccess.h> |
16689 |
+ #include <asm/io.h> |
16690 |
+@@ -128,7 +129,10 @@ static int set_one_prio(struct task_stru |
16691 |
+ goto out; |
16692 |
+ } |
16693 |
+ if (niceval < task_nice(p) && !can_nice(p, niceval)) { |
16694 |
+- error = -EACCES; |
16695 |
++ if (vx_flags(VXF_IGNEG_NICE, 0)) |
16696 |
++ error = 0; |
16697 |
++ else |
16698 |
++ error = -EACCES; |
16699 |
+ goto out; |
16700 |
+ } |
16701 |
+ no_nice = security_task_setnice(p, niceval); |
16702 |
+@@ -177,6 +181,8 @@ SYSCALL_DEFINE3(setpriority, int, which, |
16703 |
+ else |
16704 |
+ pgrp = task_pgrp(current); |
16705 |
+ do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { |
16706 |
++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT)) |
16707 |
++ continue; |
16708 |
+ error = set_one_prio(p, niceval, error); |
16709 |
+ } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); |
16710 |
+ break; |
16711 |
+@@ -238,6 +244,8 @@ SYSCALL_DEFINE2(getpriority, int, which, |
16712 |
+ else |
16713 |
+ pgrp = task_pgrp(current); |
16714 |
+ do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { |
16715 |
++ if (!vx_check(p->xid, VS_ADMIN_P | VS_IDENT)) |
16716 |
++ continue; |
16717 |
+ niceval = 20 - task_nice(p); |
16718 |
+ if (niceval > retval) |
16719 |
+ retval = niceval; |
16720 |
+@@ -347,6 +355,9 @@ void kernel_power_off(void) |
16721 |
+ machine_power_off(); |
16722 |
+ } |
16723 |
+ EXPORT_SYMBOL_GPL(kernel_power_off); |
16724 |
++ |
16725 |
++long vs_reboot(unsigned int, void __user *); |
16726 |
++ |
16727 |
+ /* |
16728 |
+ * Reboot system call: for obvious reasons only root may call it, |
16729 |
+ * and even root needs to set up some magic numbers in the registers |
16730 |
+@@ -378,6 +389,9 @@ SYSCALL_DEFINE4(reboot, int, magic1, int |
16731 |
+ if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off) |
16732 |
+ cmd = LINUX_REBOOT_CMD_HALT; |
16733 |
+ |
16734 |
++ if (!vx_check(0, VS_ADMIN|VS_WATCH)) |
16735 |
++ return vs_reboot(cmd, arg); |
16736 |
++ |
16737 |
+ lock_kernel(); |
16738 |
+ switch (cmd) { |
16739 |
+ case LINUX_REBOOT_CMD_RESTART: |
16740 |
+@@ -1420,7 +1434,7 @@ SYSCALL_DEFINE2(sethostname, char __user |
16741 |
+ int errno; |
16742 |
+ char tmp[__NEW_UTS_LEN]; |
16743 |
+ |
16744 |
+- if (!capable(CAP_SYS_ADMIN)) |
16745 |
++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME)) |
16746 |
+ return -EPERM; |
16747 |
+ if (len < 0 || len > __NEW_UTS_LEN) |
16748 |
+ return -EINVAL; |
16749 |
+@@ -1469,7 +1483,7 @@ SYSCALL_DEFINE2(setdomainname, char __us |
16750 |
+ int errno; |
16751 |
+ char tmp[__NEW_UTS_LEN]; |
16752 |
+ |
16753 |
+- if (!capable(CAP_SYS_ADMIN)) |
16754 |
++ if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME)) |
16755 |
+ return -EPERM; |
16756 |
+ if (len < 0 || len > __NEW_UTS_LEN) |
16757 |
+ return -EINVAL; |
16758 |
+@@ -1538,7 +1552,7 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, |
16759 |
+ return -EINVAL; |
16760 |
+ old_rlim = current->signal->rlim + resource; |
16761 |
+ if ((new_rlim.rlim_max > old_rlim->rlim_max) && |
16762 |
+- !capable(CAP_SYS_RESOURCE)) |
16763 |
++ !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT)) |
16764 |
+ return -EPERM; |
16765 |
+ if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) |
16766 |
+ return -EPERM; |
16767 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/sysctl.c linux-2.6.29.4-vs2.3.0.36.14/kernel/sysctl.c |
16768 |
+--- linux-2.6.29.4/kernel/sysctl.c 2009-05-23 23:16:53.000000000 +0200 |
16769 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/sysctl.c 2009-04-30 12:14:53.000000000 +0200 |
16770 |
+@@ -111,6 +111,7 @@ static int ngroups_max = NGROUPS_MAX; |
16771 |
+ #ifdef CONFIG_MODULES |
16772 |
+ extern char modprobe_path[]; |
16773 |
+ #endif |
16774 |
++extern char vshelper_path[]; |
16775 |
+ #ifdef CONFIG_CHR_DEV_SG |
16776 |
+ extern int sg_big_buff; |
16777 |
+ #endif |
16778 |
+@@ -542,6 +543,15 @@ static struct ctl_table kern_table[] = { |
16779 |
+ .strategy = &sysctl_string, |
16780 |
+ }, |
16781 |
+ #endif |
16782 |
++ { |
16783 |
++ .ctl_name = KERN_VSHELPER, |
16784 |
++ .procname = "vshelper", |
16785 |
++ .data = &vshelper_path, |
16786 |
++ .maxlen = 256, |
16787 |
++ .mode = 0644, |
16788 |
++ .proc_handler = &proc_dostring, |
16789 |
++ .strategy = &sysctl_string, |
16790 |
++ }, |
16791 |
+ #ifdef CONFIG_CHR_DEV_SG |
16792 |
+ { |
16793 |
+ .ctl_name = KERN_SG_BIG_BUFF, |
16794 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/sysctl_check.c linux-2.6.29.4-vs2.3.0.36.14/kernel/sysctl_check.c |
16795 |
+--- linux-2.6.29.4/kernel/sysctl_check.c 2009-03-24 14:22:45.000000000 +0100 |
16796 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/sysctl_check.c 2009-03-24 14:48:36.000000000 +0100 |
16797 |
+@@ -39,6 +39,7 @@ static const struct trans_ctl_table tran |
16798 |
+ |
16799 |
+ { KERN_PANIC, "panic" }, |
16800 |
+ { KERN_REALROOTDEV, "real-root-dev" }, |
16801 |
++ { KERN_VSHELPER, "vshelper", }, |
16802 |
+ |
16803 |
+ { KERN_SPARC_REBOOT, "reboot-cmd" }, |
16804 |
+ { KERN_CTLALTDEL, "ctrl-alt-del" }, |
16805 |
+@@ -1216,6 +1217,22 @@ static const struct trans_ctl_table tran |
16806 |
+ {} |
16807 |
+ }; |
16808 |
+ |
16809 |
++static struct trans_ctl_table trans_vserver_table[] = { |
16810 |
++ { 1, "debug_switch" }, |
16811 |
++ { 2, "debug_xid" }, |
16812 |
++ { 3, "debug_nid" }, |
16813 |
++ { 4, "debug_tag" }, |
16814 |
++ { 5, "debug_net" }, |
16815 |
++ { 6, "debug_limit" }, |
16816 |
++ { 7, "debug_cres" }, |
16817 |
++ { 8, "debug_dlim" }, |
16818 |
++ { 9, "debug_quota" }, |
16819 |
++ { 10, "debug_cvirt" }, |
16820 |
++ { 11, "debug_space" }, |
16821 |
++ { 12, "debug_misc" }, |
16822 |
++ {} |
16823 |
++}; |
16824 |
++ |
16825 |
+ static const struct trans_ctl_table trans_root_table[] = { |
16826 |
+ { CTL_KERN, "kernel", trans_kern_table }, |
16827 |
+ { CTL_VM, "vm", trans_vm_table }, |
16828 |
+@@ -1232,6 +1249,7 @@ static const struct trans_ctl_table tran |
16829 |
+ { CTL_SUNRPC, "sunrpc", trans_sunrpc_table }, |
16830 |
+ { CTL_PM, "pm", trans_pm_table }, |
16831 |
+ { CTL_FRV, "frv", trans_frv_table }, |
16832 |
++ { CTL_VSERVER, "vserver", trans_vserver_table }, |
16833 |
+ {} |
16834 |
+ }; |
16835 |
+ |
16836 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/time.c linux-2.6.29.4-vs2.3.0.36.14/kernel/time.c |
16837 |
+--- linux-2.6.29.4/kernel/time.c 2009-03-24 14:22:45.000000000 +0100 |
16838 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/time.c 2009-03-24 14:48:36.000000000 +0100 |
16839 |
+@@ -63,6 +63,7 @@ EXPORT_SYMBOL(sys_tz); |
16840 |
+ SYSCALL_DEFINE1(time, time_t __user *, tloc) |
16841 |
+ { |
16842 |
+ time_t i = get_seconds(); |
16843 |
++/* FIXME: do_gettimeofday(&tv) -> vx_gettimeofday(&tv) */ |
16844 |
+ |
16845 |
+ if (tloc) { |
16846 |
+ if (put_user(i,tloc)) |
16847 |
+@@ -93,7 +94,7 @@ SYSCALL_DEFINE1(stime, time_t __user *, |
16848 |
+ if (err) |
16849 |
+ return err; |
16850 |
+ |
16851 |
+- do_settimeofday(&tv); |
16852 |
++ vx_settimeofday(&tv); |
16853 |
+ return 0; |
16854 |
+ } |
16855 |
+ |
16856 |
+@@ -104,7 +105,7 @@ SYSCALL_DEFINE2(gettimeofday, struct tim |
16857 |
+ { |
16858 |
+ if (likely(tv != NULL)) { |
16859 |
+ struct timeval ktv; |
16860 |
+- do_gettimeofday(&ktv); |
16861 |
++ vx_gettimeofday(&ktv); |
16862 |
+ if (copy_to_user(tv, &ktv, sizeof(ktv))) |
16863 |
+ return -EFAULT; |
16864 |
+ } |
16865 |
+@@ -179,7 +180,7 @@ int do_sys_settimeofday(struct timespec |
16866 |
+ /* SMP safe, again the code in arch/foo/time.c should |
16867 |
+ * globally block out interrupts when it runs. |
16868 |
+ */ |
16869 |
+- return do_settimeofday(tv); |
16870 |
++ return vx_settimeofday(tv); |
16871 |
+ } |
16872 |
+ return 0; |
16873 |
+ } |
16874 |
+@@ -311,7 +312,7 @@ void getnstimeofday(struct timespec *tv) |
16875 |
+ { |
16876 |
+ struct timeval x; |
16877 |
+ |
16878 |
+- do_gettimeofday(&x); |
16879 |
++ vx_gettimeofday(&x); |
16880 |
+ tv->tv_sec = x.tv_sec; |
16881 |
+ tv->tv_nsec = x.tv_usec * NSEC_PER_USEC; |
16882 |
+ } |
16883 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/timer.c linux-2.6.29.4-vs2.3.0.36.14/kernel/timer.c |
16884 |
+--- linux-2.6.29.4/kernel/timer.c 2009-03-24 14:22:45.000000000 +0100 |
16885 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/timer.c 2009-03-24 17:41:02.000000000 +0100 |
16886 |
+@@ -37,6 +37,10 @@ |
16887 |
+ #include <linux/delay.h> |
16888 |
+ #include <linux/tick.h> |
16889 |
+ #include <linux/kallsyms.h> |
16890 |
++#include <linux/vs_base.h> |
16891 |
++#include <linux/vs_cvirt.h> |
16892 |
++#include <linux/vs_pid.h> |
16893 |
++#include <linux/vserver/sched.h> |
16894 |
+ |
16895 |
+ #include <asm/uaccess.h> |
16896 |
+ #include <asm/unistd.h> |
16897 |
+@@ -1018,6 +1022,25 @@ unsigned long get_next_timer_interrupt(u |
16898 |
+ } |
16899 |
+ #endif |
16900 |
+ |
16901 |
++static inline |
16902 |
++void __vx_consume_token(struct _vx_sched_pc *sched_pc) |
16903 |
++{ |
16904 |
++ sched_pc->tokens--; |
16905 |
++} |
16906 |
++ |
16907 |
++static inline |
16908 |
++void vx_hard_tick(struct task_struct *p, int cpu) |
16909 |
++{ |
16910 |
++ struct vx_info *vxi = p->vx_info; |
16911 |
++ |
16912 |
++ if (vx_info_flags(vxi, VXF_SCHED_HARD|VXF_SCHED_PRIO, 0)) { |
16913 |
++ struct _vx_sched_pc *sched_pc = |
16914 |
++ &vx_per_cpu(vxi, sched_pc, cpu); |
16915 |
++ |
16916 |
++ __vx_consume_token(sched_pc); |
16917 |
++ } |
16918 |
++} |
16919 |
++ |
16920 |
+ /* |
16921 |
+ * Called from the timer interrupt handler to charge one tick to the current |
16922 |
+ * process. user_tick is 1 if the tick is user time, 0 for system. |
16923 |
+@@ -1034,6 +1057,7 @@ void update_process_times(int user_tick) |
16924 |
+ rcu_check_callbacks(cpu, user_tick); |
16925 |
+ printk_tick(); |
16926 |
+ scheduler_tick(); |
16927 |
++ vx_hard_tick(p, cpu); |
16928 |
+ run_posix_cpu_timers(p); |
16929 |
+ } |
16930 |
+ |
16931 |
+@@ -1136,12 +1160,6 @@ SYSCALL_DEFINE1(alarm, unsigned int, sec |
16932 |
+ |
16933 |
+ #endif |
16934 |
+ |
16935 |
+-#ifndef __alpha__ |
16936 |
+- |
16937 |
+-/* |
16938 |
+- * The Alpha uses getxpid, getxuid, and getxgid instead. Maybe this |
16939 |
+- * should be moved into arch/i386 instead? |
16940 |
+- */ |
16941 |
+ |
16942 |
+ /** |
16943 |
+ * sys_getpid - return the thread group id of the current process |
16944 |
+@@ -1170,10 +1188,23 @@ SYSCALL_DEFINE0(getppid) |
16945 |
+ rcu_read_lock(); |
16946 |
+ pid = task_tgid_vnr(current->real_parent); |
16947 |
+ rcu_read_unlock(); |
16948 |
++ return vx_map_pid(pid); |
16949 |
++} |
16950 |
+ |
16951 |
+- return pid; |
16952 |
++#ifdef __alpha__ |
16953 |
++ |
16954 |
++/* |
16955 |
++ * The Alpha uses getxpid, getxuid, and getxgid instead. |
16956 |
++ */ |
16957 |
++ |
16958 |
++asmlinkage long do_getxpid(long *ppid) |
16959 |
++{ |
16960 |
++ *ppid = sys_getppid(); |
16961 |
++ return sys_getpid(); |
16962 |
+ } |
16963 |
+ |
16964 |
++#else /* _alpha_ */ |
16965 |
++ |
16966 |
+ SYSCALL_DEFINE0(getuid) |
16967 |
+ { |
16968 |
+ /* Only we change this so SMP safe */ |
16969 |
+@@ -1344,6 +1375,8 @@ int do_sysinfo(struct sysinfo *info) |
16970 |
+ tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC; |
16971 |
+ tp.tv_sec++; |
16972 |
+ } |
16973 |
++ if (vx_flags(VXF_VIRT_UPTIME, 0)) |
16974 |
++ vx_vsi_uptime(&tp, NULL); |
16975 |
+ info->uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0); |
16976 |
+ |
16977 |
+ info->loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); |
16978 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/user.c linux-2.6.29.4-vs2.3.0.36.14/kernel/user.c |
16979 |
+--- linux-2.6.29.4/kernel/user.c 2009-03-24 14:22:45.000000000 +0100 |
16980 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/user.c 2009-03-24 17:47:32.000000000 +0100 |
16981 |
+@@ -249,10 +249,10 @@ static struct kobj_type uids_ktype = { |
16982 |
+ * |
16983 |
+ * See Documentation/scheduler/sched-design-CFS.txt for ramifications. |
16984 |
+ */ |
16985 |
+-static int uids_user_create(struct user_struct *up) |
16986 |
++static int uids_user_create(struct user_namespace *ns, struct user_struct *up) |
16987 |
+ { |
16988 |
+ struct kobject *kobj = &up->kobj; |
16989 |
+- int error; |
16990 |
++ int error = 0; |
16991 |
+ |
16992 |
+ memset(kobj, 0, sizeof(struct kobject)); |
16993 |
+ if (up->user_ns != &init_user_ns) |
16994 |
+@@ -280,7 +280,7 @@ int __init uids_sysfs_init(void) |
16995 |
+ if (!uids_kset) |
16996 |
+ return -ENOMEM; |
16997 |
+ |
16998 |
+- return uids_user_create(&root_user); |
16999 |
++ return uids_user_create(NULL, &root_user); |
17000 |
+ } |
17001 |
+ |
17002 |
+ /* work function to remove sysfs directory for a user and free up |
17003 |
+@@ -342,7 +342,8 @@ static void free_user(struct user_struct |
17004 |
+ #else /* CONFIG_USER_SCHED && CONFIG_SYSFS */ |
17005 |
+ |
17006 |
+ int uids_sysfs_init(void) { return 0; } |
17007 |
+-static inline int uids_user_create(struct user_struct *up) { return 0; } |
17008 |
++static inline int uids_user_create(struct user_namespace *ns, |
17009 |
++ struct user_struct *up) { return 0; } |
17010 |
+ static inline void uids_mutex_lock(void) { } |
17011 |
+ static inline void uids_mutex_unlock(void) { } |
17012 |
+ |
17013 |
+@@ -439,7 +440,7 @@ struct user_struct *alloc_uid(struct use |
17014 |
+ |
17015 |
+ new->user_ns = get_user_ns(ns); |
17016 |
+ |
17017 |
+- if (uids_user_create(new)) |
17018 |
++ if (uids_user_create(ns, new)) |
17019 |
+ goto out_destoy_sched; |
17020 |
+ |
17021 |
+ /* |
17022 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/user_namespace.c linux-2.6.29.4-vs2.3.0.36.14/kernel/user_namespace.c |
17023 |
+--- linux-2.6.29.4/kernel/user_namespace.c 2009-03-24 14:22:45.000000000 +0100 |
17024 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/user_namespace.c 2009-03-24 18:05:19.000000000 +0100 |
17025 |
+@@ -10,6 +10,7 @@ |
17026 |
+ #include <linux/slab.h> |
17027 |
+ #include <linux/user_namespace.h> |
17028 |
+ #include <linux/cred.h> |
17029 |
++#include <linux/vserver/global.h> |
17030 |
+ |
17031 |
+ /* |
17032 |
+ * Create a new user namespace, deriving the creator from the user in the |
17033 |
+@@ -30,6 +31,7 @@ int create_user_ns(struct cred *new) |
17034 |
+ return -ENOMEM; |
17035 |
+ |
17036 |
+ kref_init(&ns->kref); |
17037 |
++ atomic_inc(&vs_global_user_ns); |
17038 |
+ |
17039 |
+ for (n = 0; n < UIDHASH_SZ; ++n) |
17040 |
+ INIT_HLIST_HEAD(ns->uidhash_table + n); |
17041 |
+@@ -78,6 +80,8 @@ void free_user_ns(struct kref *kref) |
17042 |
+ struct user_namespace *ns = |
17043 |
+ container_of(kref, struct user_namespace, kref); |
17044 |
+ |
17045 |
++ /* FIXME: maybe move into destroyer? */ |
17046 |
++ atomic_dec(&vs_global_user_ns); |
17047 |
+ INIT_WORK(&ns->destroyer, free_user_ns_work); |
17048 |
+ schedule_work(&ns->destroyer); |
17049 |
+ } |
17050 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/utsname.c linux-2.6.29.4-vs2.3.0.36.14/kernel/utsname.c |
17051 |
+--- linux-2.6.29.4/kernel/utsname.c 2008-12-25 00:26:37.000000000 +0100 |
17052 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/utsname.c 2009-02-22 22:54:26.000000000 +0100 |
17053 |
+@@ -14,6 +14,7 @@ |
17054 |
+ #include <linux/utsname.h> |
17055 |
+ #include <linux/err.h> |
17056 |
+ #include <linux/slab.h> |
17057 |
++#include <linux/vserver/global.h> |
17058 |
+ |
17059 |
+ /* |
17060 |
+ * Clone a new ns copying an original utsname, setting refcount to 1 |
17061 |
+@@ -32,6 +33,7 @@ static struct uts_namespace *clone_uts_n |
17062 |
+ memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); |
17063 |
+ up_read(&uts_sem); |
17064 |
+ kref_init(&ns->kref); |
17065 |
++ atomic_inc(&vs_global_uts_ns); |
17066 |
+ return ns; |
17067 |
+ } |
17068 |
+ |
17069 |
+@@ -62,5 +64,6 @@ void free_uts_ns(struct kref *kref) |
17070 |
+ struct uts_namespace *ns; |
17071 |
+ |
17072 |
+ ns = container_of(kref, struct uts_namespace, kref); |
17073 |
++ atomic_dec(&vs_global_uts_ns); |
17074 |
+ kfree(ns); |
17075 |
+ } |
17076 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/cacct.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cacct.c |
17077 |
+--- linux-2.6.29.4/kernel/vserver/cacct.c 1970-01-01 01:00:00.000000000 +0100 |
17078 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cacct.c 2009-02-22 22:54:26.000000000 +0100 |
17079 |
+@@ -0,0 +1,42 @@ |
17080 |
++/* |
17081 |
++ * linux/kernel/vserver/cacct.c |
17082 |
++ * |
17083 |
++ * Virtual Server: Context Accounting |
17084 |
++ * |
17085 |
++ * Copyright (C) 2006-2007 Herbert Pötzl |
17086 |
++ * |
17087 |
++ * V0.01 added accounting stats |
17088 |
++ * |
17089 |
++ */ |
17090 |
++ |
17091 |
++#include <linux/types.h> |
17092 |
++#include <linux/vs_context.h> |
17093 |
++#include <linux/vserver/cacct_cmd.h> |
17094 |
++#include <linux/vserver/cacct_int.h> |
17095 |
++ |
17096 |
++#include <asm/errno.h> |
17097 |
++#include <asm/uaccess.h> |
17098 |
++ |
17099 |
++ |
17100 |
++int vc_sock_stat(struct vx_info *vxi, void __user *data) |
17101 |
++{ |
17102 |
++ struct vcmd_sock_stat_v0 vc_data; |
17103 |
++ int j, field; |
17104 |
++ |
17105 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
17106 |
++ return -EFAULT; |
17107 |
++ |
17108 |
++ field = vc_data.field; |
17109 |
++ if ((field < 0) || (field >= VXA_SOCK_SIZE)) |
17110 |
++ return -EINVAL; |
17111 |
++ |
17112 |
++ for (j = 0; j < 3; j++) { |
17113 |
++ vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j); |
17114 |
++ vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j); |
17115 |
++ } |
17116 |
++ |
17117 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
17118 |
++ return -EFAULT; |
17119 |
++ return 0; |
17120 |
++} |
17121 |
++ |
17122 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/cacct_init.h linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cacct_init.h |
17123 |
+--- linux-2.6.29.4/kernel/vserver/cacct_init.h 1970-01-01 01:00:00.000000000 +0100 |
17124 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cacct_init.h 2009-02-22 22:54:26.000000000 +0100 |
17125 |
+@@ -0,0 +1,25 @@ |
17126 |
++ |
17127 |
++ |
17128 |
++static inline void vx_info_init_cacct(struct _vx_cacct *cacct) |
17129 |
++{ |
17130 |
++ int i, j; |
17131 |
++ |
17132 |
++ |
17133 |
++ for (i = 0; i < VXA_SOCK_SIZE; i++) { |
17134 |
++ for (j = 0; j < 3; j++) { |
17135 |
++ atomic_set(&cacct->sock[i][j].count, 0); |
17136 |
++ atomic_set(&cacct->sock[i][j].total, 0); |
17137 |
++ } |
17138 |
++ } |
17139 |
++ for (i = 0; i < 8; i++) |
17140 |
++ atomic_set(&cacct->slab[i], 0); |
17141 |
++ for (i = 0; i < 5; i++) |
17142 |
++ for (j = 0; j < 4; j++) |
17143 |
++ atomic_set(&cacct->page[i][j], 0); |
17144 |
++} |
17145 |
++ |
17146 |
++static inline void vx_info_exit_cacct(struct _vx_cacct *cacct) |
17147 |
++{ |
17148 |
++ return; |
17149 |
++} |
17150 |
++ |
17151 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/cacct_proc.h linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cacct_proc.h |
17152 |
+--- linux-2.6.29.4/kernel/vserver/cacct_proc.h 1970-01-01 01:00:00.000000000 +0100 |
17153 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cacct_proc.h 2009-02-22 22:54:26.000000000 +0100 |
17154 |
+@@ -0,0 +1,53 @@ |
17155 |
++#ifndef _VX_CACCT_PROC_H |
17156 |
++#define _VX_CACCT_PROC_H |
17157 |
++ |
17158 |
++#include <linux/vserver/cacct_int.h> |
17159 |
++ |
17160 |
++ |
17161 |
++#define VX_SOCKA_TOP \ |
17162 |
++ "Type\t recv #/bytes\t\t send #/bytes\t\t fail #/bytes\n" |
17163 |
++ |
17164 |
++static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer) |
17165 |
++{ |
17166 |
++ int i, j, length = 0; |
17167 |
++ static char *type[VXA_SOCK_SIZE] = { |
17168 |
++ "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER" |
17169 |
++ }; |
17170 |
++ |
17171 |
++ length += sprintf(buffer + length, VX_SOCKA_TOP); |
17172 |
++ for (i = 0; i < VXA_SOCK_SIZE; i++) { |
17173 |
++ length += sprintf(buffer + length, "%s:", type[i]); |
17174 |
++ for (j = 0; j < 3; j++) { |
17175 |
++ length += sprintf(buffer + length, |
17176 |
++ "\t%10lu/%-10lu", |
17177 |
++ vx_sock_count(cacct, i, j), |
17178 |
++ vx_sock_total(cacct, i, j)); |
17179 |
++ } |
17180 |
++ buffer[length++] = '\n'; |
17181 |
++ } |
17182 |
++ |
17183 |
++ length += sprintf(buffer + length, "\n"); |
17184 |
++ length += sprintf(buffer + length, |
17185 |
++ "slab:\t %8u %8u %8u %8u\n", |
17186 |
++ atomic_read(&cacct->slab[1]), |
17187 |
++ atomic_read(&cacct->slab[4]), |
17188 |
++ atomic_read(&cacct->slab[0]), |
17189 |
++ atomic_read(&cacct->slab[2])); |
17190 |
++ |
17191 |
++ length += sprintf(buffer + length, "\n"); |
17192 |
++ for (i = 0; i < 5; i++) { |
17193 |
++ length += sprintf(buffer + length, |
17194 |
++ "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n", i, |
17195 |
++ atomic_read(&cacct->page[i][0]), |
17196 |
++ atomic_read(&cacct->page[i][1]), |
17197 |
++ atomic_read(&cacct->page[i][2]), |
17198 |
++ atomic_read(&cacct->page[i][3]), |
17199 |
++ atomic_read(&cacct->page[i][4]), |
17200 |
++ atomic_read(&cacct->page[i][5]), |
17201 |
++ atomic_read(&cacct->page[i][6]), |
17202 |
++ atomic_read(&cacct->page[i][7])); |
17203 |
++ } |
17204 |
++ return length; |
17205 |
++} |
17206 |
++ |
17207 |
++#endif /* _VX_CACCT_PROC_H */ |
17208 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/context.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/context.c |
17209 |
+--- linux-2.6.29.4/kernel/vserver/context.c 1970-01-01 01:00:00.000000000 +0100 |
17210 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/context.c 2009-05-23 22:56:58.000000000 +0200 |
17211 |
+@@ -0,0 +1,1030 @@ |
17212 |
++/* |
17213 |
++ * linux/kernel/vserver/context.c |
17214 |
++ * |
17215 |
++ * Virtual Server: Context Support |
17216 |
++ * |
17217 |
++ * Copyright (C) 2003-2007 Herbert Pötzl |
17218 |
++ * |
17219 |
++ * V0.01 context helper |
17220 |
++ * V0.02 vx_ctx_kill syscall command |
17221 |
++ * V0.03 replaced context_info calls |
17222 |
++ * V0.04 redesign of struct (de)alloc |
17223 |
++ * V0.05 rlimit basic implementation |
17224 |
++ * V0.06 task_xid and info commands |
17225 |
++ * V0.07 context flags and caps |
17226 |
++ * V0.08 switch to RCU based hash |
17227 |
++ * V0.09 revert to non RCU for now |
17228 |
++ * V0.10 and back to working RCU hash |
17229 |
++ * V0.11 and back to locking again |
17230 |
++ * V0.12 referenced context store |
17231 |
++ * V0.13 separate per cpu data |
17232 |
++ * V0.14 changed vcmds to vxi arg |
17233 |
++ * V0.15 added context stat |
17234 |
++ * V0.16 have __create claim() the vxi |
17235 |
++ * V0.17 removed older and legacy stuff |
17236 |
++ * |
17237 |
++ */ |
17238 |
++ |
17239 |
++#include <linux/slab.h> |
17240 |
++#include <linux/types.h> |
17241 |
++#include <linux/security.h> |
17242 |
++#include <linux/pid_namespace.h> |
17243 |
++ |
17244 |
++#include <linux/vserver/context.h> |
17245 |
++#include <linux/vserver/network.h> |
17246 |
++#include <linux/vserver/debug.h> |
17247 |
++#include <linux/vserver/limit.h> |
17248 |
++#include <linux/vserver/limit_int.h> |
17249 |
++#include <linux/vserver/space.h> |
17250 |
++#include <linux/init_task.h> |
17251 |
++ |
17252 |
++#include <linux/vs_context.h> |
17253 |
++#include <linux/vs_limit.h> |
17254 |
++#include <linux/vs_pid.h> |
17255 |
++#include <linux/vserver/context_cmd.h> |
17256 |
++ |
17257 |
++#include "cvirt_init.h" |
17258 |
++#include "cacct_init.h" |
17259 |
++#include "limit_init.h" |
17260 |
++#include "sched_init.h" |
17261 |
++ |
17262 |
++ |
17263 |
++atomic_t vx_global_ctotal = ATOMIC_INIT(0); |
17264 |
++atomic_t vx_global_cactive = ATOMIC_INIT(0); |
17265 |
++ |
17266 |
++ |
17267 |
++/* now inactive context structures */ |
17268 |
++ |
17269 |
++static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT; |
17270 |
++ |
17271 |
++static spinlock_t vx_info_inactive_lock = SPIN_LOCK_UNLOCKED; |
17272 |
++ |
17273 |
++ |
17274 |
++/* __alloc_vx_info() |
17275 |
++ |
17276 |
++ * allocate an initialized vx_info struct |
17277 |
++ * doesn't make it visible (hash) */ |
17278 |
++ |
17279 |
++static struct vx_info *__alloc_vx_info(xid_t xid) |
17280 |
++{ |
17281 |
++ struct vx_info *new = NULL; |
17282 |
++ int cpu, index; |
17283 |
++ |
17284 |
++ vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid); |
17285 |
++ |
17286 |
++ /* would this benefit from a slab cache? */ |
17287 |
++ new = kmalloc(sizeof(struct vx_info), GFP_KERNEL); |
17288 |
++ if (!new) |
17289 |
++ return 0; |
17290 |
++ |
17291 |
++ memset(new, 0, sizeof(struct vx_info)); |
17292 |
++#ifdef CONFIG_SMP |
17293 |
++ new->ptr_pc = alloc_percpu(struct _vx_info_pc); |
17294 |
++ if (!new->ptr_pc) |
17295 |
++ goto error; |
17296 |
++#endif |
17297 |
++ new->vx_id = xid; |
17298 |
++ INIT_HLIST_NODE(&new->vx_hlist); |
17299 |
++ atomic_set(&new->vx_usecnt, 0); |
17300 |
++ atomic_set(&new->vx_tasks, 0); |
17301 |
++ new->vx_parent = NULL; |
17302 |
++ new->vx_state = 0; |
17303 |
++ init_waitqueue_head(&new->vx_wait); |
17304 |
++ |
17305 |
++ /* prepare reaper */ |
17306 |
++ get_task_struct(init_pid_ns.child_reaper); |
17307 |
++ new->vx_reaper = init_pid_ns.child_reaper; |
17308 |
++ new->vx_badness_bias = 0; |
17309 |
++ |
17310 |
++ /* rest of init goes here */ |
17311 |
++ vx_info_init_limit(&new->limit); |
17312 |
++ vx_info_init_sched(&new->sched); |
17313 |
++ vx_info_init_cvirt(&new->cvirt); |
17314 |
++ vx_info_init_cacct(&new->cacct); |
17315 |
++ |
17316 |
++ /* per cpu data structures */ |
17317 |
++ for_each_possible_cpu(cpu) { |
17318 |
++ vx_info_init_sched_pc( |
17319 |
++ &vx_per_cpu(new, sched_pc, cpu), cpu); |
17320 |
++ vx_info_init_cvirt_pc( |
17321 |
++ &vx_per_cpu(new, cvirt_pc, cpu), cpu); |
17322 |
++ } |
17323 |
++ |
17324 |
++ new->vx_flags = VXF_INIT_SET; |
17325 |
++ cap_set_init_eff(new->vx_bcaps); |
17326 |
++ new->vx_ccaps = 0; |
17327 |
++ // new->vx_cap_bset = current->cap_bset; |
17328 |
++ |
17329 |
++ new->reboot_cmd = 0; |
17330 |
++ new->exit_code = 0; |
17331 |
++ |
17332 |
++ // preconfig fs entries |
17333 |
++ for (index = 0; index < VX_SPACES; index++) { |
17334 |
++ write_lock(&init_fs.lock); |
17335 |
++ init_fs.users++; |
17336 |
++ write_unlock(&init_fs.lock); |
17337 |
++ new->vx_fs[index] = &init_fs; |
17338 |
++ } |
17339 |
++ |
17340 |
++ vxdprintk(VXD_CBIT(xid, 0), |
17341 |
++ "alloc_vx_info(%d) = %p", xid, new); |
17342 |
++ vxh_alloc_vx_info(new); |
17343 |
++ atomic_inc(&vx_global_ctotal); |
17344 |
++ return new; |
17345 |
++#ifdef CONFIG_SMP |
17346 |
++error: |
17347 |
++ kfree(new); |
17348 |
++ return 0; |
17349 |
++#endif |
17350 |
++} |
17351 |
++ |
17352 |
++/* __dealloc_vx_info() |
17353 |
++ |
17354 |
++ * final disposal of vx_info */ |
17355 |
++ |
17356 |
++static void __dealloc_vx_info(struct vx_info *vxi) |
17357 |
++{ |
17358 |
++ struct vx_info_save vxis; |
17359 |
++ int cpu; |
17360 |
++ |
17361 |
++ vxdprintk(VXD_CBIT(xid, 0), |
17362 |
++ "dealloc_vx_info(%p)", vxi); |
17363 |
++ vxh_dealloc_vx_info(vxi); |
17364 |
++ |
17365 |
++#ifdef CONFIG_VSERVER_WARN |
17366 |
++ enter_vx_info(vxi, &vxis); |
17367 |
++ vx_info_exit_limit(&vxi->limit); |
17368 |
++ vx_info_exit_sched(&vxi->sched); |
17369 |
++ vx_info_exit_cvirt(&vxi->cvirt); |
17370 |
++ vx_info_exit_cacct(&vxi->cacct); |
17371 |
++ |
17372 |
++ for_each_possible_cpu(cpu) { |
17373 |
++ vx_info_exit_sched_pc( |
17374 |
++ &vx_per_cpu(vxi, sched_pc, cpu), cpu); |
17375 |
++ vx_info_exit_cvirt_pc( |
17376 |
++ &vx_per_cpu(vxi, cvirt_pc, cpu), cpu); |
17377 |
++ } |
17378 |
++ leave_vx_info(&vxis); |
17379 |
++#endif |
17380 |
++ |
17381 |
++ vxi->vx_id = -1; |
17382 |
++ vxi->vx_state |= VXS_RELEASED; |
17383 |
++ |
17384 |
++#ifdef CONFIG_SMP |
17385 |
++ free_percpu(vxi->ptr_pc); |
17386 |
++#endif |
17387 |
++ kfree(vxi); |
17388 |
++ atomic_dec(&vx_global_ctotal); |
17389 |
++} |
17390 |
++ |
17391 |
++static void __shutdown_vx_info(struct vx_info *vxi) |
17392 |
++{ |
17393 |
++ struct nsproxy *nsproxy; |
17394 |
++ struct fs_struct *fs; |
17395 |
++ int index, kill; |
17396 |
++ |
17397 |
++ might_sleep(); |
17398 |
++ |
17399 |
++ vxi->vx_state |= VXS_SHUTDOWN; |
17400 |
++ vs_state_change(vxi, VSC_SHUTDOWN); |
17401 |
++ |
17402 |
++ for (index = 0; index < VX_SPACES; index++) { |
17403 |
++ nsproxy = xchg(&vxi->vx_nsproxy[index], NULL); |
17404 |
++ if (nsproxy) |
17405 |
++ put_nsproxy(nsproxy); |
17406 |
++ |
17407 |
++ fs = xchg(&vxi->vx_fs[index], NULL); |
17408 |
++ write_lock(&fs->lock); |
17409 |
++ kill = !--fs->users; |
17410 |
++ write_unlock(&fs->lock); |
17411 |
++ if (kill) |
17412 |
++ free_fs_struct(fs); |
17413 |
++ } |
17414 |
++} |
17415 |
++ |
17416 |
++/* exported stuff */ |
17417 |
++ |
17418 |
++void free_vx_info(struct vx_info *vxi) |
17419 |
++{ |
17420 |
++ unsigned long flags; |
17421 |
++ unsigned index; |
17422 |
++ |
17423 |
++ /* check for reference counts first */ |
17424 |
++ BUG_ON(atomic_read(&vxi->vx_usecnt)); |
17425 |
++ BUG_ON(atomic_read(&vxi->vx_tasks)); |
17426 |
++ |
17427 |
++ /* context must not be hashed */ |
17428 |
++ BUG_ON(vx_info_state(vxi, VXS_HASHED)); |
17429 |
++ |
17430 |
++ /* context shutdown is mandatory */ |
17431 |
++ BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN)); |
17432 |
++ |
17433 |
++ /* nsproxy and fs check */ |
17434 |
++ for (index = 0; index < VX_SPACES; index++) { |
17435 |
++ BUG_ON(vxi->vx_nsproxy[index]); |
17436 |
++ BUG_ON(vxi->vx_fs[index]); |
17437 |
++ } |
17438 |
++ |
17439 |
++ spin_lock_irqsave(&vx_info_inactive_lock, flags); |
17440 |
++ hlist_del(&vxi->vx_hlist); |
17441 |
++ spin_unlock_irqrestore(&vx_info_inactive_lock, flags); |
17442 |
++ |
17443 |
++ __dealloc_vx_info(vxi); |
17444 |
++} |
17445 |
++ |
17446 |
++ |
17447 |
++/* hash table for vx_info hash */ |
17448 |
++ |
17449 |
++#define VX_HASH_SIZE 13 |
17450 |
++ |
17451 |
++static struct hlist_head vx_info_hash[VX_HASH_SIZE] = |
17452 |
++ { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT }; |
17453 |
++ |
17454 |
++static spinlock_t vx_info_hash_lock = SPIN_LOCK_UNLOCKED; |
17455 |
++ |
17456 |
++ |
17457 |
++static inline unsigned int __hashval(xid_t xid) |
17458 |
++{ |
17459 |
++ return (xid % VX_HASH_SIZE); |
17460 |
++} |
17461 |
++ |
17462 |
++ |
17463 |
++ |
17464 |
++/* __hash_vx_info() |
17465 |
++ |
17466 |
++ * add the vxi to the global hash table |
17467 |
++ * requires the hash_lock to be held */ |
17468 |
++ |
17469 |
++static inline void __hash_vx_info(struct vx_info *vxi) |
17470 |
++{ |
17471 |
++ struct hlist_head *head; |
17472 |
++ |
17473 |
++ vxd_assert_lock(&vx_info_hash_lock); |
17474 |
++ vxdprintk(VXD_CBIT(xid, 4), |
17475 |
++ "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id); |
17476 |
++ vxh_hash_vx_info(vxi); |
17477 |
++ |
17478 |
++ /* context must not be hashed */ |
17479 |
++ BUG_ON(vx_info_state(vxi, VXS_HASHED)); |
17480 |
++ |
17481 |
++ vxi->vx_state |= VXS_HASHED; |
17482 |
++ head = &vx_info_hash[__hashval(vxi->vx_id)]; |
17483 |
++ hlist_add_head(&vxi->vx_hlist, head); |
17484 |
++ atomic_inc(&vx_global_cactive); |
17485 |
++} |
17486 |
++ |
17487 |
++/* __unhash_vx_info() |
17488 |
++ |
17489 |
++ * remove the vxi from the global hash table |
17490 |
++ * requires the hash_lock to be held */ |
17491 |
++ |
17492 |
++static inline void __unhash_vx_info(struct vx_info *vxi) |
17493 |
++{ |
17494 |
++ unsigned long flags; |
17495 |
++ |
17496 |
++ vxd_assert_lock(&vx_info_hash_lock); |
17497 |
++ vxdprintk(VXD_CBIT(xid, 4), |
17498 |
++ "__unhash_vx_info: %p[#%d.%d.%d]", vxi, vxi->vx_id, |
17499 |
++ atomic_read(&vxi->vx_usecnt), atomic_read(&vxi->vx_tasks)); |
17500 |
++ vxh_unhash_vx_info(vxi); |
17501 |
++ |
17502 |
++ /* context must be hashed */ |
17503 |
++ BUG_ON(!vx_info_state(vxi, VXS_HASHED)); |
17504 |
++ /* but without tasks */ |
17505 |
++ BUG_ON(atomic_read(&vxi->vx_tasks)); |
17506 |
++ |
17507 |
++ vxi->vx_state &= ~VXS_HASHED; |
17508 |
++ hlist_del_init(&vxi->vx_hlist); |
17509 |
++ spin_lock_irqsave(&vx_info_inactive_lock, flags); |
17510 |
++ hlist_add_head(&vxi->vx_hlist, &vx_info_inactive); |
17511 |
++ spin_unlock_irqrestore(&vx_info_inactive_lock, flags); |
17512 |
++ atomic_dec(&vx_global_cactive); |
17513 |
++} |
17514 |
++ |
17515 |
++ |
17516 |
++/* __lookup_vx_info() |
17517 |
++ |
17518 |
++ * requires the hash_lock to be held |
17519 |
++ * doesn't increment the vx_refcnt */ |
17520 |
++ |
17521 |
++static inline struct vx_info *__lookup_vx_info(xid_t xid) |
17522 |
++{ |
17523 |
++ struct hlist_head *head = &vx_info_hash[__hashval(xid)]; |
17524 |
++ struct hlist_node *pos; |
17525 |
++ struct vx_info *vxi; |
17526 |
++ |
17527 |
++ vxd_assert_lock(&vx_info_hash_lock); |
17528 |
++ hlist_for_each(pos, head) { |
17529 |
++ vxi = hlist_entry(pos, struct vx_info, vx_hlist); |
17530 |
++ |
17531 |
++ if (vxi->vx_id == xid) |
17532 |
++ goto found; |
17533 |
++ } |
17534 |
++ vxi = NULL; |
17535 |
++found: |
17536 |
++ vxdprintk(VXD_CBIT(xid, 0), |
17537 |
++ "__lookup_vx_info(#%u): %p[#%u]", |
17538 |
++ xid, vxi, vxi ? vxi->vx_id : 0); |
17539 |
++ vxh_lookup_vx_info(vxi, xid); |
17540 |
++ return vxi; |
17541 |
++} |
17542 |
++ |
17543 |
++ |
17544 |
++/* __create_vx_info() |
17545 |
++ |
17546 |
++ * create the requested context |
17547 |
++ * get(), claim() and hash it */ |
17548 |
++ |
17549 |
++static struct vx_info *__create_vx_info(int id) |
17550 |
++{ |
17551 |
++ struct vx_info *new, *vxi = NULL; |
17552 |
++ |
17553 |
++ vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id); |
17554 |
++ |
17555 |
++ if (!(new = __alloc_vx_info(id))) |
17556 |
++ return ERR_PTR(-ENOMEM); |
17557 |
++ |
17558 |
++ /* required to make dynamic xids unique */ |
17559 |
++ spin_lock(&vx_info_hash_lock); |
17560 |
++ |
17561 |
++ /* static context requested */ |
17562 |
++ if ((vxi = __lookup_vx_info(id))) { |
17563 |
++ vxdprintk(VXD_CBIT(xid, 0), |
17564 |
++ "create_vx_info(%d) = %p (already there)", id, vxi); |
17565 |
++ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0)) |
17566 |
++ vxi = ERR_PTR(-EBUSY); |
17567 |
++ else |
17568 |
++ vxi = ERR_PTR(-EEXIST); |
17569 |
++ goto out_unlock; |
17570 |
++ } |
17571 |
++ /* new context */ |
17572 |
++ vxdprintk(VXD_CBIT(xid, 0), |
17573 |
++ "create_vx_info(%d) = %p (new)", id, new); |
17574 |
++ claim_vx_info(new, NULL); |
17575 |
++ __hash_vx_info(get_vx_info(new)); |
17576 |
++ vxi = new, new = NULL; |
17577 |
++ |
17578 |
++out_unlock: |
17579 |
++ spin_unlock(&vx_info_hash_lock); |
17580 |
++ vxh_create_vx_info(IS_ERR(vxi) ? NULL : vxi, id); |
17581 |
++ if (new) |
17582 |
++ __dealloc_vx_info(new); |
17583 |
++ return vxi; |
17584 |
++} |
17585 |
++ |
17586 |
++ |
17587 |
++/* exported stuff */ |
17588 |
++ |
17589 |
++ |
17590 |
++void unhash_vx_info(struct vx_info *vxi) |
17591 |
++{ |
17592 |
++ __shutdown_vx_info(vxi); |
17593 |
++ spin_lock(&vx_info_hash_lock); |
17594 |
++ __unhash_vx_info(vxi); |
17595 |
++ spin_unlock(&vx_info_hash_lock); |
17596 |
++ __wakeup_vx_info(vxi); |
17597 |
++} |
17598 |
++ |
17599 |
++ |
17600 |
++/* lookup_vx_info() |
17601 |
++ |
17602 |
++ * search for a vx_info and get() it |
17603 |
++ * negative id means current */ |
17604 |
++ |
17605 |
++struct vx_info *lookup_vx_info(int id) |
17606 |
++{ |
17607 |
++ struct vx_info *vxi = NULL; |
17608 |
++ |
17609 |
++ if (id < 0) { |
17610 |
++ vxi = get_vx_info(current->vx_info); |
17611 |
++ } else if (id > 1) { |
17612 |
++ spin_lock(&vx_info_hash_lock); |
17613 |
++ vxi = get_vx_info(__lookup_vx_info(id)); |
17614 |
++ spin_unlock(&vx_info_hash_lock); |
17615 |
++ } |
17616 |
++ return vxi; |
17617 |
++} |
17618 |
++ |
17619 |
++/* xid_is_hashed() |
17620 |
++ |
17621 |
++ * verify that xid is still hashed */ |
17622 |
++ |
17623 |
++int xid_is_hashed(xid_t xid) |
17624 |
++{ |
17625 |
++ int hashed; |
17626 |
++ |
17627 |
++ spin_lock(&vx_info_hash_lock); |
17628 |
++ hashed = (__lookup_vx_info(xid) != NULL); |
17629 |
++ spin_unlock(&vx_info_hash_lock); |
17630 |
++ return hashed; |
17631 |
++} |
17632 |
++ |
17633 |
++#ifdef CONFIG_PROC_FS |
17634 |
++ |
17635 |
++/* get_xid_list() |
17636 |
++ |
17637 |
++ * get a subset of hashed xids for proc |
17638 |
++ * assumes size is at least one */ |
17639 |
++ |
17640 |
++int get_xid_list(int index, unsigned int *xids, int size) |
17641 |
++{ |
17642 |
++ int hindex, nr_xids = 0; |
17643 |
++ |
17644 |
++ /* only show current and children */ |
17645 |
++ if (!vx_check(0, VS_ADMIN | VS_WATCH)) { |
17646 |
++ if (index > 0) |
17647 |
++ return 0; |
17648 |
++ xids[nr_xids] = vx_current_xid(); |
17649 |
++ return 1; |
17650 |
++ } |
17651 |
++ |
17652 |
++ for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) { |
17653 |
++ struct hlist_head *head = &vx_info_hash[hindex]; |
17654 |
++ struct hlist_node *pos; |
17655 |
++ |
17656 |
++ spin_lock(&vx_info_hash_lock); |
17657 |
++ hlist_for_each(pos, head) { |
17658 |
++ struct vx_info *vxi; |
17659 |
++ |
17660 |
++ if (--index > 0) |
17661 |
++ continue; |
17662 |
++ |
17663 |
++ vxi = hlist_entry(pos, struct vx_info, vx_hlist); |
17664 |
++ xids[nr_xids] = vxi->vx_id; |
17665 |
++ if (++nr_xids >= size) { |
17666 |
++ spin_unlock(&vx_info_hash_lock); |
17667 |
++ goto out; |
17668 |
++ } |
17669 |
++ } |
17670 |
++ /* keep the lock time short */ |
17671 |
++ spin_unlock(&vx_info_hash_lock); |
17672 |
++ } |
17673 |
++out: |
17674 |
++ return nr_xids; |
17675 |
++} |
17676 |
++#endif |
17677 |
++ |
17678 |
++#ifdef CONFIG_VSERVER_DEBUG |
17679 |
++ |
17680 |
++void dump_vx_info_inactive(int level) |
17681 |
++{ |
17682 |
++ struct hlist_node *entry, *next; |
17683 |
++ |
17684 |
++ hlist_for_each_safe(entry, next, &vx_info_inactive) { |
17685 |
++ struct vx_info *vxi = |
17686 |
++ list_entry(entry, struct vx_info, vx_hlist); |
17687 |
++ |
17688 |
++ dump_vx_info(vxi, level); |
17689 |
++ } |
17690 |
++} |
17691 |
++ |
17692 |
++#endif |
17693 |
++ |
17694 |
++#if 0 |
17695 |
++int vx_migrate_user(struct task_struct *p, struct vx_info *vxi) |
17696 |
++{ |
17697 |
++ struct user_struct *new_user, *old_user; |
17698 |
++ |
17699 |
++ if (!p || !vxi) |
17700 |
++ BUG(); |
17701 |
++ |
17702 |
++ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0)) |
17703 |
++ return -EACCES; |
17704 |
++ |
17705 |
++ new_user = alloc_uid(vxi->vx_id, p->uid); |
17706 |
++ if (!new_user) |
17707 |
++ return -ENOMEM; |
17708 |
++ |
17709 |
++ old_user = p->user; |
17710 |
++ if (new_user != old_user) { |
17711 |
++ atomic_inc(&new_user->processes); |
17712 |
++ atomic_dec(&old_user->processes); |
17713 |
++ p->user = new_user; |
17714 |
++ } |
17715 |
++ free_uid(old_user); |
17716 |
++ return 0; |
17717 |
++} |
17718 |
++#endif |
17719 |
++ |
17720 |
++#if 0 |
17721 |
++void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p) |
17722 |
++{ |
17723 |
++ // p->cap_effective &= vxi->vx_cap_bset; |
17724 |
++ p->cap_effective = |
17725 |
++ cap_intersect(p->cap_effective, vxi->cap_bset); |
17726 |
++ // p->cap_inheritable &= vxi->vx_cap_bset; |
17727 |
++ p->cap_inheritable = |
17728 |
++ cap_intersect(p->cap_inheritable, vxi->cap_bset); |
17729 |
++ // p->cap_permitted &= vxi->vx_cap_bset; |
17730 |
++ p->cap_permitted = |
17731 |
++ cap_intersect(p->cap_permitted, vxi->cap_bset); |
17732 |
++} |
17733 |
++#endif |
17734 |
++ |
17735 |
++ |
17736 |
++#include <linux/file.h> |
17737 |
++#include <linux/fdtable.h> |
17738 |
++ |
17739 |
++static int vx_openfd_task(struct task_struct *tsk) |
17740 |
++{ |
17741 |
++ struct files_struct *files = tsk->files; |
17742 |
++ struct fdtable *fdt; |
17743 |
++ const unsigned long *bptr; |
17744 |
++ int count, total; |
17745 |
++ |
17746 |
++ /* no rcu_read_lock() because of spin_lock() */ |
17747 |
++ spin_lock(&files->file_lock); |
17748 |
++ fdt = files_fdtable(files); |
17749 |
++ bptr = fdt->open_fds->fds_bits; |
17750 |
++ count = fdt->max_fds / (sizeof(unsigned long) * 8); |
17751 |
++ for (total = 0; count > 0; count--) { |
17752 |
++ if (*bptr) |
17753 |
++ total += hweight_long(*bptr); |
17754 |
++ bptr++; |
17755 |
++ } |
17756 |
++ spin_unlock(&files->file_lock); |
17757 |
++ return total; |
17758 |
++} |
17759 |
++ |
17760 |
++ |
17761 |
++/* for *space compatibility */ |
17762 |
++ |
17763 |
++asmlinkage long sys_unshare(unsigned long); |
17764 |
++ |
17765 |
++/* |
17766 |
++ * migrate task to new context |
17767 |
++ * gets vxi, puts old_vxi on change |
17768 |
++ * optionally unshares namespaces (hack) |
17769 |
++ */ |
17770 |
++ |
17771 |
++int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare) |
17772 |
++{ |
17773 |
++ struct vx_info *old_vxi; |
17774 |
++ int ret = 0; |
17775 |
++ |
17776 |
++ if (!p || !vxi) |
17777 |
++ BUG(); |
17778 |
++ |
17779 |
++ vxdprintk(VXD_CBIT(xid, 5), |
17780 |
++ "vx_migrate_task(%p,%p[#%d.%d])", p, vxi, |
17781 |
++ vxi->vx_id, atomic_read(&vxi->vx_usecnt)); |
17782 |
++ |
17783 |
++ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) && |
17784 |
++ !vx_info_flags(vxi, VXF_STATE_SETUP, 0)) |
17785 |
++ return -EACCES; |
17786 |
++ |
17787 |
++ if (vx_info_state(vxi, VXS_SHUTDOWN)) |
17788 |
++ return -EFAULT; |
17789 |
++ |
17790 |
++ old_vxi = task_get_vx_info(p); |
17791 |
++ if (old_vxi == vxi) |
17792 |
++ goto out; |
17793 |
++ |
17794 |
++// if (!(ret = vx_migrate_user(p, vxi))) { |
17795 |
++ { |
17796 |
++ int openfd; |
17797 |
++ |
17798 |
++ task_lock(p); |
17799 |
++ openfd = vx_openfd_task(p); |
17800 |
++ |
17801 |
++ if (old_vxi) { |
17802 |
++ atomic_dec(&old_vxi->cvirt.nr_threads); |
17803 |
++ atomic_dec(&old_vxi->cvirt.nr_running); |
17804 |
++ __rlim_dec(&old_vxi->limit, RLIMIT_NPROC); |
17805 |
++ /* FIXME: what about the struct files here? */ |
17806 |
++ __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd); |
17807 |
++ /* account for the executable */ |
17808 |
++ __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY); |
17809 |
++ } |
17810 |
++ atomic_inc(&vxi->cvirt.nr_threads); |
17811 |
++ atomic_inc(&vxi->cvirt.nr_running); |
17812 |
++ __rlim_inc(&vxi->limit, RLIMIT_NPROC); |
17813 |
++ /* FIXME: what about the struct files here? */ |
17814 |
++ __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd); |
17815 |
++ /* account for the executable */ |
17816 |
++ __rlim_inc(&vxi->limit, VLIMIT_DENTRY); |
17817 |
++ |
17818 |
++ if (old_vxi) { |
17819 |
++ release_vx_info(old_vxi, p); |
17820 |
++ clr_vx_info(&p->vx_info); |
17821 |
++ } |
17822 |
++ claim_vx_info(vxi, p); |
17823 |
++ set_vx_info(&p->vx_info, vxi); |
17824 |
++ p->xid = vxi->vx_id; |
17825 |
++ |
17826 |
++ vxdprintk(VXD_CBIT(xid, 5), |
17827 |
++ "moved task %p into vxi:%p[#%d]", |
17828 |
++ p, vxi, vxi->vx_id); |
17829 |
++ |
17830 |
++ // vx_mask_cap_bset(vxi, p); |
17831 |
++ task_unlock(p); |
17832 |
++ |
17833 |
++ /* hack for *spaces to provide compatibility */ |
17834 |
++ if (unshare) { |
17835 |
++ struct nsproxy *old_nsp, *new_nsp; |
17836 |
++ |
17837 |
++ ret = unshare_nsproxy_namespaces( |
17838 |
++ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER, |
17839 |
++ &new_nsp, NULL); |
17840 |
++ if (ret) |
17841 |
++ goto out; |
17842 |
++ |
17843 |
++ old_nsp = xchg(&p->nsproxy, new_nsp); |
17844 |
++ vx_set_space(vxi, |
17845 |
++ CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER, 0); |
17846 |
++ put_nsproxy(old_nsp); |
17847 |
++ } |
17848 |
++ } |
17849 |
++out: |
17850 |
++ put_vx_info(old_vxi); |
17851 |
++ return ret; |
17852 |
++} |
17853 |
++ |
17854 |
++int vx_set_reaper(struct vx_info *vxi, struct task_struct *p) |
17855 |
++{ |
17856 |
++ struct task_struct *old_reaper; |
17857 |
++ |
17858 |
++ if (!vxi) |
17859 |
++ return -EINVAL; |
17860 |
++ |
17861 |
++ vxdprintk(VXD_CBIT(xid, 6), |
17862 |
++ "vx_set_reaper(%p[#%d],%p[#%d,%d])", |
17863 |
++ vxi, vxi->vx_id, p, p->xid, p->pid); |
17864 |
++ |
17865 |
++ old_reaper = vxi->vx_reaper; |
17866 |
++ if (old_reaper == p) |
17867 |
++ return 0; |
17868 |
++ |
17869 |
++ /* set new child reaper */ |
17870 |
++ get_task_struct(p); |
17871 |
++ vxi->vx_reaper = p; |
17872 |
++ put_task_struct(old_reaper); |
17873 |
++ return 0; |
17874 |
++} |
17875 |
++ |
17876 |
++int vx_set_init(struct vx_info *vxi, struct task_struct *p) |
17877 |
++{ |
17878 |
++ if (!vxi) |
17879 |
++ return -EINVAL; |
17880 |
++ |
17881 |
++ vxdprintk(VXD_CBIT(xid, 6), |
17882 |
++ "vx_set_init(%p[#%d],%p[#%d,%d,%d])", |
17883 |
++ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid); |
17884 |
++ |
17885 |
++ vxi->vx_flags &= ~VXF_STATE_INIT; |
17886 |
++ vxi->vx_initpid = p->tgid; |
17887 |
++ return 0; |
17888 |
++} |
17889 |
++ |
17890 |
++void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code) |
17891 |
++{ |
17892 |
++ vxdprintk(VXD_CBIT(xid, 6), |
17893 |
++ "vx_exit_init(%p[#%d],%p[#%d,%d,%d])", |
17894 |
++ vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid); |
17895 |
++ |
17896 |
++ vxi->exit_code = code; |
17897 |
++ vxi->vx_initpid = 0; |
17898 |
++} |
17899 |
++ |
17900 |
++ |
17901 |
++void vx_set_persistent(struct vx_info *vxi) |
17902 |
++{ |
17903 |
++ vxdprintk(VXD_CBIT(xid, 6), |
17904 |
++ "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id); |
17905 |
++ |
17906 |
++ get_vx_info(vxi); |
17907 |
++ claim_vx_info(vxi, NULL); |
17908 |
++} |
17909 |
++ |
17910 |
++void vx_clear_persistent(struct vx_info *vxi) |
17911 |
++{ |
17912 |
++ vxdprintk(VXD_CBIT(xid, 6), |
17913 |
++ "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id); |
17914 |
++ |
17915 |
++ release_vx_info(vxi, NULL); |
17916 |
++ put_vx_info(vxi); |
17917 |
++} |
17918 |
++ |
17919 |
++void vx_update_persistent(struct vx_info *vxi) |
17920 |
++{ |
17921 |
++ if (vx_info_flags(vxi, VXF_PERSISTENT, 0)) |
17922 |
++ vx_set_persistent(vxi); |
17923 |
++ else |
17924 |
++ vx_clear_persistent(vxi); |
17925 |
++} |
17926 |
++ |
17927 |
++ |
17928 |
++/* task must be current or locked */ |
17929 |
++ |
17930 |
++void exit_vx_info(struct task_struct *p, int code) |
17931 |
++{ |
17932 |
++ struct vx_info *vxi = p->vx_info; |
17933 |
++ |
17934 |
++ if (vxi) { |
17935 |
++ atomic_dec(&vxi->cvirt.nr_threads); |
17936 |
++ vx_nproc_dec(p); |
17937 |
++ |
17938 |
++ vxi->exit_code = code; |
17939 |
++ release_vx_info(vxi, p); |
17940 |
++ } |
17941 |
++} |
17942 |
++ |
17943 |
++void exit_vx_info_early(struct task_struct *p, int code) |
17944 |
++{ |
17945 |
++ struct vx_info *vxi = p->vx_info; |
17946 |
++ |
17947 |
++ if (vxi) { |
17948 |
++ if (vxi->vx_initpid == p->tgid) |
17949 |
++ vx_exit_init(vxi, p, code); |
17950 |
++ if (vxi->vx_reaper == p) |
17951 |
++ vx_set_reaper(vxi, init_pid_ns.child_reaper); |
17952 |
++ } |
17953 |
++} |
17954 |
++ |
17955 |
++ |
17956 |
++/* vserver syscall commands below here */ |
17957 |
++ |
17958 |
++/* taks xid and vx_info functions */ |
17959 |
++ |
17960 |
++#include <asm/uaccess.h> |
17961 |
++ |
17962 |
++ |
17963 |
++int vc_task_xid(uint32_t id) |
17964 |
++{ |
17965 |
++ xid_t xid; |
17966 |
++ |
17967 |
++ if (id) { |
17968 |
++ struct task_struct *tsk; |
17969 |
++ |
17970 |
++ read_lock(&tasklist_lock); |
17971 |
++ tsk = find_task_by_real_pid(id); |
17972 |
++ xid = (tsk) ? tsk->xid : -ESRCH; |
17973 |
++ read_unlock(&tasklist_lock); |
17974 |
++ } else |
17975 |
++ xid = vx_current_xid(); |
17976 |
++ return xid; |
17977 |
++} |
17978 |
++ |
17979 |
++ |
17980 |
++int vc_vx_info(struct vx_info *vxi, void __user *data) |
17981 |
++{ |
17982 |
++ struct vcmd_vx_info_v0 vc_data; |
17983 |
++ |
17984 |
++ vc_data.xid = vxi->vx_id; |
17985 |
++ vc_data.initpid = vxi->vx_initpid; |
17986 |
++ |
17987 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
17988 |
++ return -EFAULT; |
17989 |
++ return 0; |
17990 |
++} |
17991 |
++ |
17992 |
++ |
17993 |
++int vc_ctx_stat(struct vx_info *vxi, void __user *data) |
17994 |
++{ |
17995 |
++ struct vcmd_ctx_stat_v0 vc_data; |
17996 |
++ |
17997 |
++ vc_data.usecnt = atomic_read(&vxi->vx_usecnt); |
17998 |
++ vc_data.tasks = atomic_read(&vxi->vx_tasks); |
17999 |
++ |
18000 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
18001 |
++ return -EFAULT; |
18002 |
++ return 0; |
18003 |
++} |
18004 |
++ |
18005 |
++ |
18006 |
++/* context functions */ |
18007 |
++ |
18008 |
++int vc_ctx_create(uint32_t xid, void __user *data) |
18009 |
++{ |
18010 |
++ struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET }; |
18011 |
++ struct vx_info *new_vxi; |
18012 |
++ int ret; |
18013 |
++ |
18014 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
18015 |
++ return -EFAULT; |
18016 |
++ |
18017 |
++ if ((xid > MAX_S_CONTEXT) || (xid < 2)) |
18018 |
++ return -EINVAL; |
18019 |
++ |
18020 |
++ new_vxi = __create_vx_info(xid); |
18021 |
++ if (IS_ERR(new_vxi)) |
18022 |
++ return PTR_ERR(new_vxi); |
18023 |
++ |
18024 |
++ /* initial flags */ |
18025 |
++ new_vxi->vx_flags = vc_data.flagword; |
18026 |
++ |
18027 |
++ ret = -ENOEXEC; |
18028 |
++ if (vs_state_change(new_vxi, VSC_STARTUP)) |
18029 |
++ goto out; |
18030 |
++ |
18031 |
++ ret = vx_migrate_task(current, new_vxi, (!data)); |
18032 |
++ if (ret) |
18033 |
++ goto out; |
18034 |
++ |
18035 |
++ /* return context id on success */ |
18036 |
++ ret = new_vxi->vx_id; |
18037 |
++ |
18038 |
++ /* get a reference for persistent contexts */ |
18039 |
++ if ((vc_data.flagword & VXF_PERSISTENT)) |
18040 |
++ vx_set_persistent(new_vxi); |
18041 |
++out: |
18042 |
++ release_vx_info(new_vxi, NULL); |
18043 |
++ put_vx_info(new_vxi); |
18044 |
++ return ret; |
18045 |
++} |
18046 |
++ |
18047 |
++ |
18048 |
++int vc_ctx_migrate(struct vx_info *vxi, void __user *data) |
18049 |
++{ |
18050 |
++ struct vcmd_ctx_migrate vc_data = { .flagword = 0 }; |
18051 |
++ int ret; |
18052 |
++ |
18053 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
18054 |
++ return -EFAULT; |
18055 |
++ |
18056 |
++ ret = vx_migrate_task(current, vxi, 0); |
18057 |
++ if (ret) |
18058 |
++ return ret; |
18059 |
++ if (vc_data.flagword & VXM_SET_INIT) |
18060 |
++ ret = vx_set_init(vxi, current); |
18061 |
++ if (ret) |
18062 |
++ return ret; |
18063 |
++ if (vc_data.flagword & VXM_SET_REAPER) |
18064 |
++ ret = vx_set_reaper(vxi, current); |
18065 |
++ return ret; |
18066 |
++} |
18067 |
++ |
18068 |
++ |
18069 |
++int vc_get_cflags(struct vx_info *vxi, void __user *data) |
18070 |
++{ |
18071 |
++ struct vcmd_ctx_flags_v0 vc_data; |
18072 |
++ |
18073 |
++ vc_data.flagword = vxi->vx_flags; |
18074 |
++ |
18075 |
++ /* special STATE flag handling */ |
18076 |
++ vc_data.mask = vs_mask_flags(~0ULL, vxi->vx_flags, VXF_ONE_TIME); |
18077 |
++ |
18078 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
18079 |
++ return -EFAULT; |
18080 |
++ return 0; |
18081 |
++} |
18082 |
++ |
18083 |
++int vc_set_cflags(struct vx_info *vxi, void __user *data) |
18084 |
++{ |
18085 |
++ struct vcmd_ctx_flags_v0 vc_data; |
18086 |
++ uint64_t mask, trigger; |
18087 |
++ |
18088 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
18089 |
++ return -EFAULT; |
18090 |
++ |
18091 |
++ /* special STATE flag handling */ |
18092 |
++ mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME); |
18093 |
++ trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword); |
18094 |
++ |
18095 |
++ if (vxi == current->vx_info) { |
18096 |
++ /* if (trigger & VXF_STATE_SETUP) |
18097 |
++ vx_mask_cap_bset(vxi, current); */ |
18098 |
++ if (trigger & VXF_STATE_INIT) { |
18099 |
++ int ret; |
18100 |
++ |
18101 |
++ ret = vx_set_init(vxi, current); |
18102 |
++ if (ret) |
18103 |
++ return ret; |
18104 |
++ ret = vx_set_reaper(vxi, current); |
18105 |
++ if (ret) |
18106 |
++ return ret; |
18107 |
++ } |
18108 |
++ } |
18109 |
++ |
18110 |
++ vxi->vx_flags = vs_mask_flags(vxi->vx_flags, |
18111 |
++ vc_data.flagword, mask); |
18112 |
++ if (trigger & VXF_PERSISTENT) |
18113 |
++ vx_update_persistent(vxi); |
18114 |
++ |
18115 |
++ return 0; |
18116 |
++} |
18117 |
++ |
18118 |
++ |
18119 |
++static inline uint64_t caps_from_cap_t(kernel_cap_t c) |
18120 |
++{ |
18121 |
++ uint64_t v = c.cap[0] | ((uint64_t)c.cap[1] << 32); |
18122 |
++ |
18123 |
++ // printk("caps_from_cap_t(%08x:%08x) = %016llx\n", c.cap[1], c.cap[0], v); |
18124 |
++ return v; |
18125 |
++} |
18126 |
++ |
18127 |
++static inline kernel_cap_t cap_t_from_caps(uint64_t v) |
18128 |
++{ |
18129 |
++ kernel_cap_t c = __cap_empty_set; |
18130 |
++ |
18131 |
++ c.cap[0] = v & 0xFFFFFFFF; |
18132 |
++ c.cap[1] = (v >> 32) & 0xFFFFFFFF; |
18133 |
++ |
18134 |
++ // printk("cap_t_from_caps(%016llx) = %08x:%08x\n", v, c.cap[1], c.cap[0]); |
18135 |
++ return c; |
18136 |
++} |
18137 |
++ |
18138 |
++ |
18139 |
++static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps) |
18140 |
++{ |
18141 |
++ if (bcaps) |
18142 |
++ *bcaps = caps_from_cap_t(vxi->vx_bcaps); |
18143 |
++ if (ccaps) |
18144 |
++ *ccaps = vxi->vx_ccaps; |
18145 |
++ |
18146 |
++ return 0; |
18147 |
++} |
18148 |
++ |
18149 |
++int vc_get_ccaps(struct vx_info *vxi, void __user *data) |
18150 |
++{ |
18151 |
++ struct vcmd_ctx_caps_v1 vc_data; |
18152 |
++ int ret; |
18153 |
++ |
18154 |
++ ret = do_get_caps(vxi, NULL, &vc_data.ccaps); |
18155 |
++ if (ret) |
18156 |
++ return ret; |
18157 |
++ vc_data.cmask = ~0ULL; |
18158 |
++ |
18159 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
18160 |
++ return -EFAULT; |
18161 |
++ return 0; |
18162 |
++} |
18163 |
++ |
18164 |
++static int do_set_caps(struct vx_info *vxi, |
18165 |
++ uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask) |
18166 |
++{ |
18167 |
++ uint64_t bcold = caps_from_cap_t(vxi->vx_bcaps); |
18168 |
++ |
18169 |
++#if 0 |
18170 |
++ printk("do_set_caps(%16llx, %16llx, %16llx, %16llx)\n", |
18171 |
++ bcaps, bmask, ccaps, cmask); |
18172 |
++#endif |
18173 |
++ vxi->vx_bcaps = cap_t_from_caps( |
18174 |
++ vs_mask_flags(bcold, bcaps, bmask)); |
18175 |
++ vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask); |
18176 |
++ |
18177 |
++ return 0; |
18178 |
++} |
18179 |
++ |
18180 |
++int vc_set_ccaps(struct vx_info *vxi, void __user *data) |
18181 |
++{ |
18182 |
++ struct vcmd_ctx_caps_v1 vc_data; |
18183 |
++ |
18184 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
18185 |
++ return -EFAULT; |
18186 |
++ |
18187 |
++ return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask); |
18188 |
++} |
18189 |
++ |
18190 |
++int vc_get_bcaps(struct vx_info *vxi, void __user *data) |
18191 |
++{ |
18192 |
++ struct vcmd_bcaps vc_data; |
18193 |
++ int ret; |
18194 |
++ |
18195 |
++ ret = do_get_caps(vxi, &vc_data.bcaps, NULL); |
18196 |
++ if (ret) |
18197 |
++ return ret; |
18198 |
++ vc_data.bmask = ~0ULL; |
18199 |
++ |
18200 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
18201 |
++ return -EFAULT; |
18202 |
++ return 0; |
18203 |
++} |
18204 |
++ |
18205 |
++int vc_set_bcaps(struct vx_info *vxi, void __user *data) |
18206 |
++{ |
18207 |
++ struct vcmd_bcaps vc_data; |
18208 |
++ |
18209 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
18210 |
++ return -EFAULT; |
18211 |
++ |
18212 |
++ return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0); |
18213 |
++} |
18214 |
++ |
18215 |
++ |
18216 |
++int vc_get_badness(struct vx_info *vxi, void __user *data) |
18217 |
++{ |
18218 |
++ struct vcmd_badness_v0 vc_data; |
18219 |
++ |
18220 |
++ vc_data.bias = vxi->vx_badness_bias; |
18221 |
++ |
18222 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
18223 |
++ return -EFAULT; |
18224 |
++ return 0; |
18225 |
++} |
18226 |
++ |
18227 |
++int vc_set_badness(struct vx_info *vxi, void __user *data) |
18228 |
++{ |
18229 |
++ struct vcmd_badness_v0 vc_data; |
18230 |
++ |
18231 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
18232 |
++ return -EFAULT; |
18233 |
++ |
18234 |
++ vxi->vx_badness_bias = vc_data.bias; |
18235 |
++ return 0; |
18236 |
++} |
18237 |
++ |
18238 |
++#include <linux/module.h> |
18239 |
++ |
18240 |
++EXPORT_SYMBOL_GPL(free_vx_info); |
18241 |
++ |
18242 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/cvirt.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cvirt.c |
18243 |
+--- linux-2.6.29.4/kernel/vserver/cvirt.c 1970-01-01 01:00:00.000000000 +0100 |
18244 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cvirt.c 2009-02-22 22:54:26.000000000 +0100 |
18245 |
+@@ -0,0 +1,300 @@ |
18246 |
++/* |
18247 |
++ * linux/kernel/vserver/cvirt.c |
18248 |
++ * |
18249 |
++ * Virtual Server: Context Virtualization |
18250 |
++ * |
18251 |
++ * Copyright (C) 2004-2007 Herbert Pötzl |
18252 |
++ * |
18253 |
++ * V0.01 broken out from limit.c |
18254 |
++ * V0.02 added utsname stuff |
18255 |
++ * V0.03 changed vcmds to vxi arg |
18256 |
++ * |
18257 |
++ */ |
18258 |
++ |
18259 |
++#include <linux/types.h> |
18260 |
++#include <linux/utsname.h> |
18261 |
++#include <linux/vs_cvirt.h> |
18262 |
++#include <linux/vserver/switch.h> |
18263 |
++#include <linux/vserver/cvirt_cmd.h> |
18264 |
++ |
18265 |
++#include <asm/uaccess.h> |
18266 |
++ |
18267 |
++ |
18268 |
++void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle) |
18269 |
++{ |
18270 |
++ struct vx_info *vxi = current->vx_info; |
18271 |
++ |
18272 |
++ set_normalized_timespec(uptime, |
18273 |
++ uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec, |
18274 |
++ uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec); |
18275 |
++ if (!idle) |
18276 |
++ return; |
18277 |
++ set_normalized_timespec(idle, |
18278 |
++ idle->tv_sec - vxi->cvirt.bias_idle.tv_sec, |
18279 |
++ idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec); |
18280 |
++ return; |
18281 |
++} |
18282 |
++ |
18283 |
++uint64_t vx_idle_jiffies(void) |
18284 |
++{ |
18285 |
++ return init_task.utime + init_task.stime; |
18286 |
++} |
18287 |
++ |
18288 |
++ |
18289 |
++ |
18290 |
++static inline uint32_t __update_loadavg(uint32_t load, |
18291 |
++ int wsize, int delta, int n) |
18292 |
++{ |
18293 |
++ unsigned long long calc, prev; |
18294 |
++ |
18295 |
++ /* just set it to n */ |
18296 |
++ if (unlikely(delta >= wsize)) |
18297 |
++ return (n << FSHIFT); |
18298 |
++ |
18299 |
++ calc = delta * n; |
18300 |
++ calc <<= FSHIFT; |
18301 |
++ prev = (wsize - delta); |
18302 |
++ prev *= load; |
18303 |
++ calc += prev; |
18304 |
++ do_div(calc, wsize); |
18305 |
++ return calc; |
18306 |
++} |
18307 |
++ |
18308 |
++ |
18309 |
++void vx_update_load(struct vx_info *vxi) |
18310 |
++{ |
18311 |
++ uint32_t now, last, delta; |
18312 |
++ unsigned int nr_running, nr_uninterruptible; |
18313 |
++ unsigned int total; |
18314 |
++ unsigned long flags; |
18315 |
++ |
18316 |
++ spin_lock_irqsave(&vxi->cvirt.load_lock, flags); |
18317 |
++ |
18318 |
++ now = jiffies; |
18319 |
++ last = vxi->cvirt.load_last; |
18320 |
++ delta = now - last; |
18321 |
++ |
18322 |
++ if (delta < 5*HZ) |
18323 |
++ goto out; |
18324 |
++ |
18325 |
++ nr_running = atomic_read(&vxi->cvirt.nr_running); |
18326 |
++ nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible); |
18327 |
++ total = nr_running + nr_uninterruptible; |
18328 |
++ |
18329 |
++ vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0], |
18330 |
++ 60*HZ, delta, total); |
18331 |
++ vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1], |
18332 |
++ 5*60*HZ, delta, total); |
18333 |
++ vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2], |
18334 |
++ 15*60*HZ, delta, total); |
18335 |
++ |
18336 |
++ vxi->cvirt.load_last = now; |
18337 |
++out: |
18338 |
++ atomic_inc(&vxi->cvirt.load_updates); |
18339 |
++ spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags); |
18340 |
++} |
18341 |
++ |
18342 |
++ |
18343 |
++/* |
18344 |
++ * Commands to do_syslog: |
18345 |
++ * |
18346 |
++ * 0 -- Close the log. Currently a NOP. |
18347 |
++ * 1 -- Open the log. Currently a NOP. |
18348 |
++ * 2 -- Read from the log. |
18349 |
++ * 3 -- Read all messages remaining in the ring buffer. |
18350 |
++ * 4 -- Read and clear all messages remaining in the ring buffer |
18351 |
++ * 5 -- Clear ring buffer. |
18352 |
++ * 6 -- Disable printk's to console |
18353 |
++ * 7 -- Enable printk's to console |
18354 |
++ * 8 -- Set level of messages printed to console |
18355 |
++ * 9 -- Return number of unread characters in the log buffer |
18356 |
++ * 10 -- Return size of the log buffer |
18357 |
++ */ |
18358 |
++int vx_do_syslog(int type, char __user *buf, int len) |
18359 |
++{ |
18360 |
++ int error = 0; |
18361 |
++ int do_clear = 0; |
18362 |
++ struct vx_info *vxi = current->vx_info; |
18363 |
++ struct _vx_syslog *log; |
18364 |
++ |
18365 |
++ if (!vxi) |
18366 |
++ return -EINVAL; |
18367 |
++ log = &vxi->cvirt.syslog; |
18368 |
++ |
18369 |
++ switch (type) { |
18370 |
++ case 0: /* Close log */ |
18371 |
++ case 1: /* Open log */ |
18372 |
++ break; |
18373 |
++ case 2: /* Read from log */ |
18374 |
++ error = wait_event_interruptible(log->log_wait, |
18375 |
++ (log->log_start - log->log_end)); |
18376 |
++ if (error) |
18377 |
++ break; |
18378 |
++ spin_lock_irq(&log->logbuf_lock); |
18379 |
++ spin_unlock_irq(&log->logbuf_lock); |
18380 |
++ break; |
18381 |
++ case 4: /* Read/clear last kernel messages */ |
18382 |
++ do_clear = 1; |
18383 |
++ /* fall through */ |
18384 |
++ case 3: /* Read last kernel messages */ |
18385 |
++ return 0; |
18386 |
++ |
18387 |
++ case 5: /* Clear ring buffer */ |
18388 |
++ return 0; |
18389 |
++ |
18390 |
++ case 6: /* Disable logging to console */ |
18391 |
++ case 7: /* Enable logging to console */ |
18392 |
++ case 8: /* Set level of messages printed to console */ |
18393 |
++ break; |
18394 |
++ |
18395 |
++ case 9: /* Number of chars in the log buffer */ |
18396 |
++ return 0; |
18397 |
++ case 10: /* Size of the log buffer */ |
18398 |
++ return 0; |
18399 |
++ default: |
18400 |
++ error = -EINVAL; |
18401 |
++ break; |
18402 |
++ } |
18403 |
++ return error; |
18404 |
++} |
18405 |
++ |
18406 |
++ |
18407 |
++/* virtual host info names */ |
18408 |
++ |
18409 |
++static char *vx_vhi_name(struct vx_info *vxi, int id) |
18410 |
++{ |
18411 |
++ struct nsproxy *nsproxy; |
18412 |
++ struct uts_namespace *uts; |
18413 |
++ |
18414 |
++ if (id == VHIN_CONTEXT) |
18415 |
++ return vxi->vx_name; |
18416 |
++ |
18417 |
++ nsproxy = vxi->vx_nsproxy[0]; |
18418 |
++ if (!nsproxy) |
18419 |
++ return NULL; |
18420 |
++ |
18421 |
++ uts = nsproxy->uts_ns; |
18422 |
++ if (!uts) |
18423 |
++ return NULL; |
18424 |
++ |
18425 |
++ switch (id) { |
18426 |
++ case VHIN_SYSNAME: |
18427 |
++ return uts->name.sysname; |
18428 |
++ case VHIN_NODENAME: |
18429 |
++ return uts->name.nodename; |
18430 |
++ case VHIN_RELEASE: |
18431 |
++ return uts->name.release; |
18432 |
++ case VHIN_VERSION: |
18433 |
++ return uts->name.version; |
18434 |
++ case VHIN_MACHINE: |
18435 |
++ return uts->name.machine; |
18436 |
++ case VHIN_DOMAINNAME: |
18437 |
++ return uts->name.domainname; |
18438 |
++ default: |
18439 |
++ return NULL; |
18440 |
++ } |
18441 |
++ return NULL; |
18442 |
++} |
18443 |
++ |
18444 |
++int vc_set_vhi_name(struct vx_info *vxi, void __user *data) |
18445 |
++{ |
18446 |
++ struct vcmd_vhi_name_v0 vc_data; |
18447 |
++ char *name; |
18448 |
++ |
18449 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
18450 |
++ return -EFAULT; |
18451 |
++ |
18452 |
++ name = vx_vhi_name(vxi, vc_data.field); |
18453 |
++ if (!name) |
18454 |
++ return -EINVAL; |
18455 |
++ |
18456 |
++ memcpy(name, vc_data.name, 65); |
18457 |
++ return 0; |
18458 |
++} |
18459 |
++ |
18460 |
++int vc_get_vhi_name(struct vx_info *vxi, void __user *data) |
18461 |
++{ |
18462 |
++ struct vcmd_vhi_name_v0 vc_data; |
18463 |
++ char *name; |
18464 |
++ |
18465 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
18466 |
++ return -EFAULT; |
18467 |
++ |
18468 |
++ name = vx_vhi_name(vxi, vc_data.field); |
18469 |
++ if (!name) |
18470 |
++ return -EINVAL; |
18471 |
++ |
18472 |
++ memcpy(vc_data.name, name, 65); |
18473 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
18474 |
++ return -EFAULT; |
18475 |
++ return 0; |
18476 |
++} |
18477 |
++ |
18478 |
++ |
18479 |
++int vc_virt_stat(struct vx_info *vxi, void __user *data) |
18480 |
++{ |
18481 |
++ struct vcmd_virt_stat_v0 vc_data; |
18482 |
++ struct _vx_cvirt *cvirt = &vxi->cvirt; |
18483 |
++ struct timespec uptime; |
18484 |
++ |
18485 |
++ do_posix_clock_monotonic_gettime(&uptime); |
18486 |
++ set_normalized_timespec(&uptime, |
18487 |
++ uptime.tv_sec - cvirt->bias_uptime.tv_sec, |
18488 |
++ uptime.tv_nsec - cvirt->bias_uptime.tv_nsec); |
18489 |
++ |
18490 |
++ vc_data.offset = timeval_to_ns(&cvirt->bias_tv); |
18491 |
++ vc_data.uptime = timespec_to_ns(&uptime); |
18492 |
++ vc_data.nr_threads = atomic_read(&cvirt->nr_threads); |
18493 |
++ vc_data.nr_running = atomic_read(&cvirt->nr_running); |
18494 |
++ vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible); |
18495 |
++ vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold); |
18496 |
++ vc_data.nr_forks = atomic_read(&cvirt->total_forks); |
18497 |
++ vc_data.load[0] = cvirt->load[0]; |
18498 |
++ vc_data.load[1] = cvirt->load[1]; |
18499 |
++ vc_data.load[2] = cvirt->load[2]; |
18500 |
++ |
18501 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
18502 |
++ return -EFAULT; |
18503 |
++ return 0; |
18504 |
++} |
18505 |
++ |
18506 |
++ |
18507 |
++#ifdef CONFIG_VSERVER_VTIME |
18508 |
++ |
18509 |
++/* virtualized time base */ |
18510 |
++ |
18511 |
++void vx_gettimeofday(struct timeval *tv) |
18512 |
++{ |
18513 |
++ do_gettimeofday(tv); |
18514 |
++ if (!vx_flags(VXF_VIRT_TIME, 0)) |
18515 |
++ return; |
18516 |
++ |
18517 |
++ tv->tv_sec += current->vx_info->cvirt.bias_tv.tv_sec; |
18518 |
++ tv->tv_usec += current->vx_info->cvirt.bias_tv.tv_usec; |
18519 |
++ |
18520 |
++ if (tv->tv_usec >= USEC_PER_SEC) { |
18521 |
++ tv->tv_sec++; |
18522 |
++ tv->tv_usec -= USEC_PER_SEC; |
18523 |
++ } else if (tv->tv_usec < 0) { |
18524 |
++ tv->tv_sec--; |
18525 |
++ tv->tv_usec += USEC_PER_SEC; |
18526 |
++ } |
18527 |
++} |
18528 |
++ |
18529 |
++int vx_settimeofday(struct timespec *ts) |
18530 |
++{ |
18531 |
++ struct timeval tv; |
18532 |
++ |
18533 |
++ if (!vx_flags(VXF_VIRT_TIME, 0)) |
18534 |
++ return do_settimeofday(ts); |
18535 |
++ |
18536 |
++ do_gettimeofday(&tv); |
18537 |
++ current->vx_info->cvirt.bias_tv.tv_sec = |
18538 |
++ ts->tv_sec - tv.tv_sec; |
18539 |
++ current->vx_info->cvirt.bias_tv.tv_usec = |
18540 |
++ (ts->tv_nsec/NSEC_PER_USEC) - tv.tv_usec; |
18541 |
++ return 0; |
18542 |
++} |
18543 |
++ |
18544 |
++#endif |
18545 |
++ |
18546 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/cvirt_init.h linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cvirt_init.h |
18547 |
+--- linux-2.6.29.4/kernel/vserver/cvirt_init.h 1970-01-01 01:00:00.000000000 +0100 |
18548 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cvirt_init.h 2009-02-22 22:54:26.000000000 +0100 |
18549 |
+@@ -0,0 +1,69 @@ |
18550 |
++ |
18551 |
++ |
18552 |
++extern uint64_t vx_idle_jiffies(void); |
18553 |
++ |
18554 |
++static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt) |
18555 |
++{ |
18556 |
++ uint64_t idle_jiffies = vx_idle_jiffies(); |
18557 |
++ uint64_t nsuptime; |
18558 |
++ |
18559 |
++ do_posix_clock_monotonic_gettime(&cvirt->bias_uptime); |
18560 |
++ nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec |
18561 |
++ * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec; |
18562 |
++ cvirt->bias_clock = nsec_to_clock_t(nsuptime); |
18563 |
++ cvirt->bias_tv.tv_sec = 0; |
18564 |
++ cvirt->bias_tv.tv_usec = 0; |
18565 |
++ |
18566 |
++ jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle); |
18567 |
++ atomic_set(&cvirt->nr_threads, 0); |
18568 |
++ atomic_set(&cvirt->nr_running, 0); |
18569 |
++ atomic_set(&cvirt->nr_uninterruptible, 0); |
18570 |
++ atomic_set(&cvirt->nr_onhold, 0); |
18571 |
++ |
18572 |
++ spin_lock_init(&cvirt->load_lock); |
18573 |
++ cvirt->load_last = jiffies; |
18574 |
++ atomic_set(&cvirt->load_updates, 0); |
18575 |
++ cvirt->load[0] = 0; |
18576 |
++ cvirt->load[1] = 0; |
18577 |
++ cvirt->load[2] = 0; |
18578 |
++ atomic_set(&cvirt->total_forks, 0); |
18579 |
++ |
18580 |
++ spin_lock_init(&cvirt->syslog.logbuf_lock); |
18581 |
++ init_waitqueue_head(&cvirt->syslog.log_wait); |
18582 |
++ cvirt->syslog.log_start = 0; |
18583 |
++ cvirt->syslog.log_end = 0; |
18584 |
++ cvirt->syslog.con_start = 0; |
18585 |
++ cvirt->syslog.logged_chars = 0; |
18586 |
++} |
18587 |
++ |
18588 |
++static inline |
18589 |
++void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu) |
18590 |
++{ |
18591 |
++ // cvirt_pc->cpustat = { 0 }; |
18592 |
++} |
18593 |
++ |
18594 |
++static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt) |
18595 |
++{ |
18596 |
++ int value; |
18597 |
++ |
18598 |
++ vxwprintk_xid((value = atomic_read(&cvirt->nr_threads)), |
18599 |
++ "!!! cvirt: %p[nr_threads] = %d on exit.", |
18600 |
++ cvirt, value); |
18601 |
++ vxwprintk_xid((value = atomic_read(&cvirt->nr_running)), |
18602 |
++ "!!! cvirt: %p[nr_running] = %d on exit.", |
18603 |
++ cvirt, value); |
18604 |
++ vxwprintk_xid((value = atomic_read(&cvirt->nr_uninterruptible)), |
18605 |
++ "!!! cvirt: %p[nr_uninterruptible] = %d on exit.", |
18606 |
++ cvirt, value); |
18607 |
++ vxwprintk_xid((value = atomic_read(&cvirt->nr_onhold)), |
18608 |
++ "!!! cvirt: %p[nr_onhold] = %d on exit.", |
18609 |
++ cvirt, value); |
18610 |
++ return; |
18611 |
++} |
18612 |
++ |
18613 |
++static inline |
18614 |
++void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu) |
18615 |
++{ |
18616 |
++ return; |
18617 |
++} |
18618 |
++ |
18619 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/cvirt_proc.h linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cvirt_proc.h |
18620 |
+--- linux-2.6.29.4/kernel/vserver/cvirt_proc.h 1970-01-01 01:00:00.000000000 +0100 |
18621 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/cvirt_proc.h 2009-02-22 22:54:26.000000000 +0100 |
18622 |
+@@ -0,0 +1,135 @@ |
18623 |
++#ifndef _VX_CVIRT_PROC_H |
18624 |
++#define _VX_CVIRT_PROC_H |
18625 |
++ |
18626 |
++#include <linux/nsproxy.h> |
18627 |
++#include <linux/mnt_namespace.h> |
18628 |
++#include <linux/ipc_namespace.h> |
18629 |
++#include <linux/utsname.h> |
18630 |
++#include <linux/ipc.h> |
18631 |
++ |
18632 |
++ |
18633 |
++static inline |
18634 |
++int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer) |
18635 |
++{ |
18636 |
++ struct mnt_namespace *ns; |
18637 |
++ struct uts_namespace *uts; |
18638 |
++ struct ipc_namespace *ipc; |
18639 |
++ struct path path; |
18640 |
++ char *pstr, *root; |
18641 |
++ int length = 0; |
18642 |
++ |
18643 |
++ if (!nsproxy) |
18644 |
++ goto out; |
18645 |
++ |
18646 |
++ length += sprintf(buffer + length, |
18647 |
++ "NSProxy:\t%p [%p,%p,%p]\n", |
18648 |
++ nsproxy, nsproxy->mnt_ns, |
18649 |
++ nsproxy->uts_ns, nsproxy->ipc_ns); |
18650 |
++ |
18651 |
++ ns = nsproxy->mnt_ns; |
18652 |
++ if (!ns) |
18653 |
++ goto skip_ns; |
18654 |
++ |
18655 |
++ pstr = kmalloc(PATH_MAX, GFP_KERNEL); |
18656 |
++ if (!pstr) |
18657 |
++ goto skip_ns; |
18658 |
++ |
18659 |
++ path.mnt = ns->root; |
18660 |
++ path.dentry = ns->root->mnt_root; |
18661 |
++ root = d_path(&path, pstr, PATH_MAX - 2); |
18662 |
++ length += sprintf(buffer + length, |
18663 |
++ "Namespace:\t%p [#%u]\n" |
18664 |
++ "RootPath:\t%s\n", |
18665 |
++ ns, atomic_read(&ns->count), |
18666 |
++ root); |
18667 |
++ kfree(pstr); |
18668 |
++skip_ns: |
18669 |
++ |
18670 |
++ uts = nsproxy->uts_ns; |
18671 |
++ if (!uts) |
18672 |
++ goto skip_uts; |
18673 |
++ |
18674 |
++ length += sprintf(buffer + length, |
18675 |
++ "SysName:\t%.*s\n" |
18676 |
++ "NodeName:\t%.*s\n" |
18677 |
++ "Release:\t%.*s\n" |
18678 |
++ "Version:\t%.*s\n" |
18679 |
++ "Machine:\t%.*s\n" |
18680 |
++ "DomainName:\t%.*s\n", |
18681 |
++ __NEW_UTS_LEN, uts->name.sysname, |
18682 |
++ __NEW_UTS_LEN, uts->name.nodename, |
18683 |
++ __NEW_UTS_LEN, uts->name.release, |
18684 |
++ __NEW_UTS_LEN, uts->name.version, |
18685 |
++ __NEW_UTS_LEN, uts->name.machine, |
18686 |
++ __NEW_UTS_LEN, uts->name.domainname); |
18687 |
++skip_uts: |
18688 |
++ |
18689 |
++ ipc = nsproxy->ipc_ns; |
18690 |
++ if (!ipc) |
18691 |
++ goto skip_ipc; |
18692 |
++ |
18693 |
++ length += sprintf(buffer + length, |
18694 |
++ "SEMS:\t\t%d %d %d %d %d\n" |
18695 |
++ "MSG:\t\t%d %d %d\n" |
18696 |
++ "SHM:\t\t%lu %lu %d %d\n", |
18697 |
++ ipc->sem_ctls[0], ipc->sem_ctls[1], |
18698 |
++ ipc->sem_ctls[2], ipc->sem_ctls[3], |
18699 |
++ ipc->used_sems, |
18700 |
++ ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni, |
18701 |
++ (unsigned long)ipc->shm_ctlmax, |
18702 |
++ (unsigned long)ipc->shm_ctlall, |
18703 |
++ ipc->shm_ctlmni, ipc->shm_tot); |
18704 |
++skip_ipc: |
18705 |
++out: |
18706 |
++ return length; |
18707 |
++} |
18708 |
++ |
18709 |
++ |
18710 |
++#include <linux/sched.h> |
18711 |
++ |
18712 |
++#define LOAD_INT(x) ((x) >> FSHIFT) |
18713 |
++#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100) |
18714 |
++ |
18715 |
++static inline |
18716 |
++int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer) |
18717 |
++{ |
18718 |
++ int length = 0; |
18719 |
++ int a, b, c; |
18720 |
++ |
18721 |
++ length += sprintf(buffer + length, |
18722 |
++ "BiasUptime:\t%lu.%02lu\n", |
18723 |
++ (unsigned long)cvirt->bias_uptime.tv_sec, |
18724 |
++ (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100))); |
18725 |
++ |
18726 |
++ a = cvirt->load[0] + (FIXED_1 / 200); |
18727 |
++ b = cvirt->load[1] + (FIXED_1 / 200); |
18728 |
++ c = cvirt->load[2] + (FIXED_1 / 200); |
18729 |
++ length += sprintf(buffer + length, |
18730 |
++ "nr_threads:\t%d\n" |
18731 |
++ "nr_running:\t%d\n" |
18732 |
++ "nr_unintr:\t%d\n" |
18733 |
++ "nr_onhold:\t%d\n" |
18734 |
++ "load_updates:\t%d\n" |
18735 |
++ "loadavg:\t%d.%02d %d.%02d %d.%02d\n" |
18736 |
++ "total_forks:\t%d\n", |
18737 |
++ atomic_read(&cvirt->nr_threads), |
18738 |
++ atomic_read(&cvirt->nr_running), |
18739 |
++ atomic_read(&cvirt->nr_uninterruptible), |
18740 |
++ atomic_read(&cvirt->nr_onhold), |
18741 |
++ atomic_read(&cvirt->load_updates), |
18742 |
++ LOAD_INT(a), LOAD_FRAC(a), |
18743 |
++ LOAD_INT(b), LOAD_FRAC(b), |
18744 |
++ LOAD_INT(c), LOAD_FRAC(c), |
18745 |
++ atomic_read(&cvirt->total_forks)); |
18746 |
++ return length; |
18747 |
++} |
18748 |
++ |
18749 |
++static inline |
18750 |
++int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, |
18751 |
++ char *buffer, int cpu) |
18752 |
++{ |
18753 |
++ int length = 0; |
18754 |
++ return length; |
18755 |
++} |
18756 |
++ |
18757 |
++#endif /* _VX_CVIRT_PROC_H */ |
18758 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/debug.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/debug.c |
18759 |
+--- linux-2.6.29.4/kernel/vserver/debug.c 1970-01-01 01:00:00.000000000 +0100 |
18760 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/debug.c 2009-02-22 22:54:26.000000000 +0100 |
18761 |
+@@ -0,0 +1,32 @@ |
18762 |
++/* |
18763 |
++ * kernel/vserver/debug.c |
18764 |
++ * |
18765 |
++ * Copyright (C) 2005-2007 Herbert Pötzl |
18766 |
++ * |
18767 |
++ * V0.01 vx_info dump support |
18768 |
++ * |
18769 |
++ */ |
18770 |
++ |
18771 |
++#include <linux/module.h> |
18772 |
++ |
18773 |
++#include <linux/vserver/context.h> |
18774 |
++ |
18775 |
++ |
18776 |
++void dump_vx_info(struct vx_info *vxi, int level) |
18777 |
++{ |
18778 |
++ printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id, |
18779 |
++ atomic_read(&vxi->vx_usecnt), |
18780 |
++ atomic_read(&vxi->vx_tasks), |
18781 |
++ vxi->vx_state); |
18782 |
++ if (level > 0) { |
18783 |
++ __dump_vx_limit(&vxi->limit); |
18784 |
++ __dump_vx_sched(&vxi->sched); |
18785 |
++ __dump_vx_cvirt(&vxi->cvirt); |
18786 |
++ __dump_vx_cacct(&vxi->cacct); |
18787 |
++ } |
18788 |
++ printk("---\n"); |
18789 |
++} |
18790 |
++ |
18791 |
++ |
18792 |
++EXPORT_SYMBOL_GPL(dump_vx_info); |
18793 |
++ |
18794 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/device.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/device.c |
18795 |
+--- linux-2.6.29.4/kernel/vserver/device.c 1970-01-01 01:00:00.000000000 +0100 |
18796 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/device.c 2009-02-22 22:54:26.000000000 +0100 |
18797 |
+@@ -0,0 +1,443 @@ |
18798 |
++/* |
18799 |
++ * linux/kernel/vserver/device.c |
18800 |
++ * |
18801 |
++ * Linux-VServer: Device Support |
18802 |
++ * |
18803 |
++ * Copyright (C) 2006 Herbert Pötzl |
18804 |
++ * Copyright (C) 2007 Daniel Hokka Zakrisson |
18805 |
++ * |
18806 |
++ * V0.01 device mapping basics |
18807 |
++ * V0.02 added defaults |
18808 |
++ * |
18809 |
++ */ |
18810 |
++ |
18811 |
++#include <linux/slab.h> |
18812 |
++#include <linux/rcupdate.h> |
18813 |
++#include <linux/fs.h> |
18814 |
++#include <linux/namei.h> |
18815 |
++#include <linux/hash.h> |
18816 |
++ |
18817 |
++#include <asm/errno.h> |
18818 |
++#include <asm/uaccess.h> |
18819 |
++#include <linux/vserver/base.h> |
18820 |
++#include <linux/vserver/debug.h> |
18821 |
++#include <linux/vserver/context.h> |
18822 |
++#include <linux/vserver/device.h> |
18823 |
++#include <linux/vserver/device_cmd.h> |
18824 |
++ |
18825 |
++ |
18826 |
++#define DMAP_HASH_BITS 4 |
18827 |
++ |
18828 |
++ |
18829 |
++struct vs_mapping { |
18830 |
++ union { |
18831 |
++ struct hlist_node hlist; |
18832 |
++ struct list_head list; |
18833 |
++ } u; |
18834 |
++#define dm_hlist u.hlist |
18835 |
++#define dm_list u.list |
18836 |
++ xid_t xid; |
18837 |
++ dev_t device; |
18838 |
++ struct vx_dmap_target target; |
18839 |
++}; |
18840 |
++ |
18841 |
++ |
18842 |
++static struct hlist_head dmap_main_hash[1 << DMAP_HASH_BITS]; |
18843 |
++ |
18844 |
++static spinlock_t dmap_main_hash_lock = SPIN_LOCK_UNLOCKED; |
18845 |
++ |
18846 |
++static struct vx_dmap_target dmap_defaults[2] = { |
18847 |
++ { .flags = DATTR_OPEN }, |
18848 |
++ { .flags = DATTR_OPEN }, |
18849 |
++}; |
18850 |
++ |
18851 |
++ |
18852 |
++struct kmem_cache *dmap_cachep __read_mostly; |
18853 |
++ |
18854 |
++int __init dmap_cache_init(void) |
18855 |
++{ |
18856 |
++ dmap_cachep = kmem_cache_create("dmap_cache", |
18857 |
++ sizeof(struct vs_mapping), 0, |
18858 |
++ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); |
18859 |
++ return 0; |
18860 |
++} |
18861 |
++ |
18862 |
++__initcall(dmap_cache_init); |
18863 |
++ |
18864 |
++ |
18865 |
++static inline unsigned int __hashval(dev_t dev, int bits) |
18866 |
++{ |
18867 |
++ return hash_long((unsigned long)dev, bits); |
18868 |
++} |
18869 |
++ |
18870 |
++ |
18871 |
++/* __hash_mapping() |
18872 |
++ * add the mapping to the hash table |
18873 |
++ */ |
18874 |
++static inline void __hash_mapping(struct vx_info *vxi, struct vs_mapping *vdm) |
18875 |
++{ |
18876 |
++ spinlock_t *hash_lock = &dmap_main_hash_lock; |
18877 |
++ struct hlist_head *head, *hash = dmap_main_hash; |
18878 |
++ int device = vdm->device; |
18879 |
++ |
18880 |
++ spin_lock(hash_lock); |
18881 |
++ vxdprintk(VXD_CBIT(misc, 8), "__hash_mapping: %p[#%d] %08x:%08x", |
18882 |
++ vxi, vxi ? vxi->vx_id : 0, device, vdm->target.target); |
18883 |
++ |
18884 |
++ head = &hash[__hashval(device, DMAP_HASH_BITS)]; |
18885 |
++ hlist_add_head(&vdm->dm_hlist, head); |
18886 |
++ spin_unlock(hash_lock); |
18887 |
++} |
18888 |
++ |
18889 |
++ |
18890 |
++static inline int __mode_to_default(umode_t mode) |
18891 |
++{ |
18892 |
++ switch (mode) { |
18893 |
++ case S_IFBLK: |
18894 |
++ return 0; |
18895 |
++ case S_IFCHR: |
18896 |
++ return 1; |
18897 |
++ default: |
18898 |
++ BUG(); |
18899 |
++ } |
18900 |
++} |
18901 |
++ |
18902 |
++ |
18903 |
++/* __set_default() |
18904 |
++ * set a default |
18905 |
++ */ |
18906 |
++static inline void __set_default(struct vx_info *vxi, umode_t mode, |
18907 |
++ struct vx_dmap_target *vdmt) |
18908 |
++{ |
18909 |
++ spinlock_t *hash_lock = &dmap_main_hash_lock; |
18910 |
++ spin_lock(hash_lock); |
18911 |
++ |
18912 |
++ if (vxi) |
18913 |
++ vxi->dmap.targets[__mode_to_default(mode)] = *vdmt; |
18914 |
++ else |
18915 |
++ dmap_defaults[__mode_to_default(mode)] = *vdmt; |
18916 |
++ |
18917 |
++ |
18918 |
++ spin_unlock(hash_lock); |
18919 |
++ |
18920 |
++ vxdprintk(VXD_CBIT(misc, 8), "__set_default: %p[#%u] %08x %04x", |
18921 |
++ vxi, vxi ? vxi->vx_id : 0, vdmt->target, vdmt->flags); |
18922 |
++} |
18923 |
++ |
18924 |
++ |
18925 |
++/* __remove_default() |
18926 |
++ * remove a default |
18927 |
++ */ |
18928 |
++static inline int __remove_default(struct vx_info *vxi, umode_t mode) |
18929 |
++{ |
18930 |
++ spinlock_t *hash_lock = &dmap_main_hash_lock; |
18931 |
++ spin_lock(hash_lock); |
18932 |
++ |
18933 |
++ if (vxi) |
18934 |
++ vxi->dmap.targets[__mode_to_default(mode)].flags = 0; |
18935 |
++ else /* remove == reset */ |
18936 |
++ dmap_defaults[__mode_to_default(mode)].flags = DATTR_OPEN | mode; |
18937 |
++ |
18938 |
++ spin_unlock(hash_lock); |
18939 |
++ return 0; |
18940 |
++} |
18941 |
++ |
18942 |
++ |
18943 |
++/* __find_mapping() |
18944 |
++ * find a mapping in the hash table |
18945 |
++ * |
18946 |
++ * caller must hold hash_lock |
18947 |
++ */ |
18948 |
++static inline int __find_mapping(xid_t xid, dev_t device, umode_t mode, |
18949 |
++ struct vs_mapping **local, struct vs_mapping **global) |
18950 |
++{ |
18951 |
++ struct hlist_head *hash = dmap_main_hash; |
18952 |
++ struct hlist_head *head = &hash[__hashval(device, DMAP_HASH_BITS)]; |
18953 |
++ struct hlist_node *pos; |
18954 |
++ struct vs_mapping *vdm; |
18955 |
++ |
18956 |
++ *local = NULL; |
18957 |
++ if (global) |
18958 |
++ *global = NULL; |
18959 |
++ |
18960 |
++ hlist_for_each(pos, head) { |
18961 |
++ vdm = hlist_entry(pos, struct vs_mapping, dm_hlist); |
18962 |
++ |
18963 |
++ if ((vdm->device == device) && |
18964 |
++ !((vdm->target.flags ^ mode) & S_IFMT)) { |
18965 |
++ if (vdm->xid == xid) { |
18966 |
++ *local = vdm; |
18967 |
++ return 1; |
18968 |
++ } else if (global && vdm->xid == 0) |
18969 |
++ *global = vdm; |
18970 |
++ } |
18971 |
++ } |
18972 |
++ |
18973 |
++ if (global && *global) |
18974 |
++ return 0; |
18975 |
++ else |
18976 |
++ return -ENOENT; |
18977 |
++} |
18978 |
++ |
18979 |
++ |
18980 |
++/* __lookup_mapping() |
18981 |
++ * find a mapping and store the result in target and flags |
18982 |
++ */ |
18983 |
++static inline int __lookup_mapping(struct vx_info *vxi, |
18984 |
++ dev_t device, dev_t *target, int *flags, umode_t mode) |
18985 |
++{ |
18986 |
++ spinlock_t *hash_lock = &dmap_main_hash_lock; |
18987 |
++ struct vs_mapping *vdm, *global; |
18988 |
++ struct vx_dmap_target *vdmt; |
18989 |
++ int ret = 0; |
18990 |
++ xid_t xid = vxi->vx_id; |
18991 |
++ int index; |
18992 |
++ |
18993 |
++ spin_lock(hash_lock); |
18994 |
++ if (__find_mapping(xid, device, mode, &vdm, &global) > 0) { |
18995 |
++ ret = 1; |
18996 |
++ vdmt = &vdm->target; |
18997 |
++ goto found; |
18998 |
++ } |
18999 |
++ |
19000 |
++ index = __mode_to_default(mode); |
19001 |
++ if (vxi && vxi->dmap.targets[index].flags) { |
19002 |
++ ret = 2; |
19003 |
++ vdmt = &vxi->dmap.targets[index]; |
19004 |
++ } else if (global) { |
19005 |
++ ret = 3; |
19006 |
++ vdmt = &global->target; |
19007 |
++ goto found; |
19008 |
++ } else { |
19009 |
++ ret = 4; |
19010 |
++ vdmt = &dmap_defaults[index]; |
19011 |
++ } |
19012 |
++ |
19013 |
++found: |
19014 |
++ if (target && (vdmt->flags & DATTR_REMAP)) |
19015 |
++ *target = vdmt->target; |
19016 |
++ else if (target) |
19017 |
++ *target = device; |
19018 |
++ if (flags) |
19019 |
++ *flags = vdmt->flags; |
19020 |
++ |
19021 |
++ spin_unlock(hash_lock); |
19022 |
++ |
19023 |
++ return ret; |
19024 |
++} |
19025 |
++ |
19026 |
++ |
19027 |
++/* __remove_mapping() |
19028 |
++ * remove a mapping from the hash table |
19029 |
++ */ |
19030 |
++static inline int __remove_mapping(struct vx_info *vxi, dev_t device, |
19031 |
++ umode_t mode) |
19032 |
++{ |
19033 |
++ spinlock_t *hash_lock = &dmap_main_hash_lock; |
19034 |
++ struct vs_mapping *vdm = NULL; |
19035 |
++ int ret = 0; |
19036 |
++ |
19037 |
++ spin_lock(hash_lock); |
19038 |
++ |
19039 |
++ ret = __find_mapping((vxi ? vxi->vx_id : 0), device, mode, &vdm, |
19040 |
++ NULL); |
19041 |
++ vxdprintk(VXD_CBIT(misc, 8), "__remove_mapping: %p[#%d] %08x %04x", |
19042 |
++ vxi, vxi ? vxi->vx_id : 0, device, mode); |
19043 |
++ if (ret < 0) |
19044 |
++ goto out; |
19045 |
++ hlist_del(&vdm->dm_hlist); |
19046 |
++ |
19047 |
++out: |
19048 |
++ spin_unlock(hash_lock); |
19049 |
++ if (vdm) |
19050 |
++ kmem_cache_free(dmap_cachep, vdm); |
19051 |
++ return ret; |
19052 |
++} |
19053 |
++ |
19054 |
++ |
19055 |
++ |
19056 |
++int vs_map_device(struct vx_info *vxi, |
19057 |
++ dev_t device, dev_t *target, umode_t mode) |
19058 |
++{ |
19059 |
++ int ret, flags = DATTR_MASK; |
19060 |
++ |
19061 |
++ if (!vxi) { |
19062 |
++ if (target) |
19063 |
++ *target = device; |
19064 |
++ goto out; |
19065 |
++ } |
19066 |
++ ret = __lookup_mapping(vxi, device, target, &flags, mode); |
19067 |
++ vxdprintk(VXD_CBIT(misc, 8), "vs_map_device: %08x target: %08x flags: %04x mode: %04x mapped=%d", |
19068 |
++ device, target ? *target : 0, flags, mode, ret); |
19069 |
++out: |
19070 |
++ return (flags & DATTR_MASK); |
19071 |
++} |
19072 |
++ |
19073 |
++ |
19074 |
++ |
19075 |
++static int do_set_mapping(struct vx_info *vxi, |
19076 |
++ dev_t device, dev_t target, int flags, umode_t mode) |
19077 |
++{ |
19078 |
++ if (device) { |
19079 |
++ struct vs_mapping *new; |
19080 |
++ |
19081 |
++ new = kmem_cache_alloc(dmap_cachep, GFP_KERNEL); |
19082 |
++ if (!new) |
19083 |
++ return -ENOMEM; |
19084 |
++ |
19085 |
++ INIT_HLIST_NODE(&new->dm_hlist); |
19086 |
++ new->device = device; |
19087 |
++ new->target.target = target; |
19088 |
++ new->target.flags = flags | mode; |
19089 |
++ new->xid = (vxi ? vxi->vx_id : 0); |
19090 |
++ |
19091 |
++ vxdprintk(VXD_CBIT(misc, 8), "do_set_mapping: %08x target: %08x flags: %04x", device, target, flags); |
19092 |
++ __hash_mapping(vxi, new); |
19093 |
++ } else { |
19094 |
++ struct vx_dmap_target new = { |
19095 |
++ .target = target, |
19096 |
++ .flags = flags | mode, |
19097 |
++ }; |
19098 |
++ __set_default(vxi, mode, &new); |
19099 |
++ } |
19100 |
++ return 0; |
19101 |
++} |
19102 |
++ |
19103 |
++ |
19104 |
++static int do_unset_mapping(struct vx_info *vxi, |
19105 |
++ dev_t device, dev_t target, int flags, umode_t mode) |
19106 |
++{ |
19107 |
++ int ret = -EINVAL; |
19108 |
++ |
19109 |
++ if (device) { |
19110 |
++ ret = __remove_mapping(vxi, device, mode); |
19111 |
++ if (ret < 0) |
19112 |
++ goto out; |
19113 |
++ } else { |
19114 |
++ ret = __remove_default(vxi, mode); |
19115 |
++ if (ret < 0) |
19116 |
++ goto out; |
19117 |
++ } |
19118 |
++ |
19119 |
++out: |
19120 |
++ return ret; |
19121 |
++} |
19122 |
++ |
19123 |
++ |
19124 |
++static inline int __user_device(const char __user *name, dev_t *dev, |
19125 |
++ umode_t *mode) |
19126 |
++{ |
19127 |
++ struct nameidata nd; |
19128 |
++ int ret; |
19129 |
++ |
19130 |
++ if (!name) { |
19131 |
++ *dev = 0; |
19132 |
++ return 0; |
19133 |
++ } |
19134 |
++ ret = user_lpath(name, &nd.path); |
19135 |
++ if (ret) |
19136 |
++ return ret; |
19137 |
++ if (nd.path.dentry->d_inode) { |
19138 |
++ *dev = nd.path.dentry->d_inode->i_rdev; |
19139 |
++ *mode = nd.path.dentry->d_inode->i_mode; |
19140 |
++ } |
19141 |
++ path_put(&nd.path); |
19142 |
++ return 0; |
19143 |
++} |
19144 |
++ |
19145 |
++static inline int __mapping_mode(dev_t device, dev_t target, |
19146 |
++ umode_t device_mode, umode_t target_mode, umode_t *mode) |
19147 |
++{ |
19148 |
++ if (device) |
19149 |
++ *mode = device_mode & S_IFMT; |
19150 |
++ else if (target) |
19151 |
++ *mode = target_mode & S_IFMT; |
19152 |
++ else |
19153 |
++ return -EINVAL; |
19154 |
++ |
19155 |
++ /* if both given, device and target mode have to match */ |
19156 |
++ if (device && target && |
19157 |
++ ((device_mode ^ target_mode) & S_IFMT)) |
19158 |
++ return -EINVAL; |
19159 |
++ return 0; |
19160 |
++} |
19161 |
++ |
19162 |
++ |
19163 |
++static inline int do_mapping(struct vx_info *vxi, const char __user *device_path, |
19164 |
++ const char __user *target_path, int flags, int set) |
19165 |
++{ |
19166 |
++ dev_t device = ~0, target = ~0; |
19167 |
++ umode_t device_mode = 0, target_mode = 0, mode; |
19168 |
++ int ret; |
19169 |
++ |
19170 |
++ ret = __user_device(device_path, &device, &device_mode); |
19171 |
++ if (ret) |
19172 |
++ return ret; |
19173 |
++ ret = __user_device(target_path, &target, &target_mode); |
19174 |
++ if (ret) |
19175 |
++ return ret; |
19176 |
++ |
19177 |
++ ret = __mapping_mode(device, target, |
19178 |
++ device_mode, target_mode, &mode); |
19179 |
++ if (ret) |
19180 |
++ return ret; |
19181 |
++ |
19182 |
++ if (set) |
19183 |
++ return do_set_mapping(vxi, device, target, |
19184 |
++ flags, mode); |
19185 |
++ else |
19186 |
++ return do_unset_mapping(vxi, device, target, |
19187 |
++ flags, mode); |
19188 |
++} |
19189 |
++ |
19190 |
++ |
19191 |
++int vc_set_mapping(struct vx_info *vxi, void __user *data) |
19192 |
++{ |
19193 |
++ struct vcmd_set_mapping_v0 vc_data; |
19194 |
++ |
19195 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19196 |
++ return -EFAULT; |
19197 |
++ |
19198 |
++ return do_mapping(vxi, vc_data.device, vc_data.target, |
19199 |
++ vc_data.flags, 1); |
19200 |
++} |
19201 |
++ |
19202 |
++int vc_unset_mapping(struct vx_info *vxi, void __user *data) |
19203 |
++{ |
19204 |
++ struct vcmd_set_mapping_v0 vc_data; |
19205 |
++ |
19206 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19207 |
++ return -EFAULT; |
19208 |
++ |
19209 |
++ return do_mapping(vxi, vc_data.device, vc_data.target, |
19210 |
++ vc_data.flags, 0); |
19211 |
++} |
19212 |
++ |
19213 |
++ |
19214 |
++#ifdef CONFIG_COMPAT |
19215 |
++ |
19216 |
++int vc_set_mapping_x32(struct vx_info *vxi, void __user *data) |
19217 |
++{ |
19218 |
++ struct vcmd_set_mapping_v0_x32 vc_data; |
19219 |
++ |
19220 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19221 |
++ return -EFAULT; |
19222 |
++ |
19223 |
++ return do_mapping(vxi, compat_ptr(vc_data.device_ptr), |
19224 |
++ compat_ptr(vc_data.target_ptr), vc_data.flags, 1); |
19225 |
++} |
19226 |
++ |
19227 |
++int vc_unset_mapping_x32(struct vx_info *vxi, void __user *data) |
19228 |
++{ |
19229 |
++ struct vcmd_set_mapping_v0_x32 vc_data; |
19230 |
++ |
19231 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19232 |
++ return -EFAULT; |
19233 |
++ |
19234 |
++ return do_mapping(vxi, compat_ptr(vc_data.device_ptr), |
19235 |
++ compat_ptr(vc_data.target_ptr), vc_data.flags, 0); |
19236 |
++} |
19237 |
++ |
19238 |
++#endif /* CONFIG_COMPAT */ |
19239 |
++ |
19240 |
++ |
19241 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/dlimit.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/dlimit.c |
19242 |
+--- linux-2.6.29.4/kernel/vserver/dlimit.c 1970-01-01 01:00:00.000000000 +0100 |
19243 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/dlimit.c 2009-02-22 22:54:26.000000000 +0100 |
19244 |
+@@ -0,0 +1,522 @@ |
19245 |
++/* |
19246 |
++ * linux/kernel/vserver/dlimit.c |
19247 |
++ * |
19248 |
++ * Virtual Server: Context Disk Limits |
19249 |
++ * |
19250 |
++ * Copyright (C) 2004-2007 Herbert Pötzl |
19251 |
++ * |
19252 |
++ * V0.01 initial version |
19253 |
++ * V0.02 compat32 splitup |
19254 |
++ * |
19255 |
++ */ |
19256 |
++ |
19257 |
++#include <linux/statfs.h> |
19258 |
++#include <linux/sched.h> |
19259 |
++#include <linux/namei.h> |
19260 |
++#include <linux/vs_tag.h> |
19261 |
++#include <linux/vs_dlimit.h> |
19262 |
++#include <linux/vserver/dlimit_cmd.h> |
19263 |
++ |
19264 |
++#include <asm/uaccess.h> |
19265 |
++ |
19266 |
++/* __alloc_dl_info() |
19267 |
++ |
19268 |
++ * allocate an initialized dl_info struct |
19269 |
++ * doesn't make it visible (hash) */ |
19270 |
++ |
19271 |
++static struct dl_info *__alloc_dl_info(struct super_block *sb, tag_t tag) |
19272 |
++{ |
19273 |
++ struct dl_info *new = NULL; |
19274 |
++ |
19275 |
++ vxdprintk(VXD_CBIT(dlim, 5), |
19276 |
++ "alloc_dl_info(%p,%d)*", sb, tag); |
19277 |
++ |
19278 |
++ /* would this benefit from a slab cache? */ |
19279 |
++ new = kmalloc(sizeof(struct dl_info), GFP_KERNEL); |
19280 |
++ if (!new) |
19281 |
++ return 0; |
19282 |
++ |
19283 |
++ memset(new, 0, sizeof(struct dl_info)); |
19284 |
++ new->dl_tag = tag; |
19285 |
++ new->dl_sb = sb; |
19286 |
++ INIT_RCU_HEAD(&new->dl_rcu); |
19287 |
++ INIT_HLIST_NODE(&new->dl_hlist); |
19288 |
++ spin_lock_init(&new->dl_lock); |
19289 |
++ atomic_set(&new->dl_refcnt, 0); |
19290 |
++ atomic_set(&new->dl_usecnt, 0); |
19291 |
++ |
19292 |
++ /* rest of init goes here */ |
19293 |
++ |
19294 |
++ vxdprintk(VXD_CBIT(dlim, 4), |
19295 |
++ "alloc_dl_info(%p,%d) = %p", sb, tag, new); |
19296 |
++ return new; |
19297 |
++} |
19298 |
++ |
19299 |
++/* __dealloc_dl_info() |
19300 |
++ |
19301 |
++ * final disposal of dl_info */ |
19302 |
++ |
19303 |
++static void __dealloc_dl_info(struct dl_info *dli) |
19304 |
++{ |
19305 |
++ vxdprintk(VXD_CBIT(dlim, 4), |
19306 |
++ "dealloc_dl_info(%p)", dli); |
19307 |
++ |
19308 |
++ dli->dl_hlist.next = LIST_POISON1; |
19309 |
++ dli->dl_tag = -1; |
19310 |
++ dli->dl_sb = 0; |
19311 |
++ |
19312 |
++ BUG_ON(atomic_read(&dli->dl_usecnt)); |
19313 |
++ BUG_ON(atomic_read(&dli->dl_refcnt)); |
19314 |
++ |
19315 |
++ kfree(dli); |
19316 |
++} |
19317 |
++ |
19318 |
++ |
19319 |
++/* hash table for dl_info hash */ |
19320 |
++ |
19321 |
++#define DL_HASH_SIZE 13 |
19322 |
++ |
19323 |
++struct hlist_head dl_info_hash[DL_HASH_SIZE]; |
19324 |
++ |
19325 |
++static spinlock_t dl_info_hash_lock = SPIN_LOCK_UNLOCKED; |
19326 |
++ |
19327 |
++ |
19328 |
++static inline unsigned int __hashval(struct super_block *sb, tag_t tag) |
19329 |
++{ |
19330 |
++ return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE); |
19331 |
++} |
19332 |
++ |
19333 |
++ |
19334 |
++ |
19335 |
++/* __hash_dl_info() |
19336 |
++ |
19337 |
++ * add the dli to the global hash table |
19338 |
++ * requires the hash_lock to be held */ |
19339 |
++ |
19340 |
++static inline void __hash_dl_info(struct dl_info *dli) |
19341 |
++{ |
19342 |
++ struct hlist_head *head; |
19343 |
++ |
19344 |
++ vxdprintk(VXD_CBIT(dlim, 6), |
19345 |
++ "__hash_dl_info: %p[#%d]", dli, dli->dl_tag); |
19346 |
++ get_dl_info(dli); |
19347 |
++ head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)]; |
19348 |
++ hlist_add_head_rcu(&dli->dl_hlist, head); |
19349 |
++} |
19350 |
++ |
19351 |
++/* __unhash_dl_info() |
19352 |
++ |
19353 |
++ * remove the dli from the global hash table |
19354 |
++ * requires the hash_lock to be held */ |
19355 |
++ |
19356 |
++static inline void __unhash_dl_info(struct dl_info *dli) |
19357 |
++{ |
19358 |
++ vxdprintk(VXD_CBIT(dlim, 6), |
19359 |
++ "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag); |
19360 |
++ hlist_del_rcu(&dli->dl_hlist); |
19361 |
++ put_dl_info(dli); |
19362 |
++} |
19363 |
++ |
19364 |
++ |
19365 |
++/* __lookup_dl_info() |
19366 |
++ |
19367 |
++ * requires the rcu_read_lock() |
19368 |
++ * doesn't increment the dl_refcnt */ |
19369 |
++ |
19370 |
++static inline struct dl_info *__lookup_dl_info(struct super_block *sb, tag_t tag) |
19371 |
++{ |
19372 |
++ struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)]; |
19373 |
++ struct hlist_node *pos; |
19374 |
++ struct dl_info *dli; |
19375 |
++ |
19376 |
++ hlist_for_each_entry_rcu(dli, pos, head, dl_hlist) { |
19377 |
++ |
19378 |
++ if (dli->dl_tag == tag && dli->dl_sb == sb) { |
19379 |
++ return dli; |
19380 |
++ } |
19381 |
++ } |
19382 |
++ return NULL; |
19383 |
++} |
19384 |
++ |
19385 |
++ |
19386 |
++struct dl_info *locate_dl_info(struct super_block *sb, tag_t tag) |
19387 |
++{ |
19388 |
++ struct dl_info *dli; |
19389 |
++ |
19390 |
++ rcu_read_lock(); |
19391 |
++ dli = get_dl_info(__lookup_dl_info(sb, tag)); |
19392 |
++ vxdprintk(VXD_CBIT(dlim, 7), |
19393 |
++ "locate_dl_info(%p,#%d) = %p", sb, tag, dli); |
19394 |
++ rcu_read_unlock(); |
19395 |
++ return dli; |
19396 |
++} |
19397 |
++ |
19398 |
++void rcu_free_dl_info(struct rcu_head *head) |
19399 |
++{ |
19400 |
++ struct dl_info *dli = container_of(head, struct dl_info, dl_rcu); |
19401 |
++ int usecnt, refcnt; |
19402 |
++ |
19403 |
++ BUG_ON(!dli || !head); |
19404 |
++ |
19405 |
++ usecnt = atomic_read(&dli->dl_usecnt); |
19406 |
++ BUG_ON(usecnt < 0); |
19407 |
++ |
19408 |
++ refcnt = atomic_read(&dli->dl_refcnt); |
19409 |
++ BUG_ON(refcnt < 0); |
19410 |
++ |
19411 |
++ vxdprintk(VXD_CBIT(dlim, 3), |
19412 |
++ "rcu_free_dl_info(%p)", dli); |
19413 |
++ if (!usecnt) |
19414 |
++ __dealloc_dl_info(dli); |
19415 |
++ else |
19416 |
++ printk("!!! rcu didn't free\n"); |
19417 |
++} |
19418 |
++ |
19419 |
++ |
19420 |
++ |
19421 |
++ |
19422 |
++static int do_addrem_dlimit(uint32_t id, const char __user *name, |
19423 |
++ uint32_t flags, int add) |
19424 |
++{ |
19425 |
++ struct path path; |
19426 |
++ int ret; |
19427 |
++ |
19428 |
++ ret = user_lpath(name, &path); |
19429 |
++ if (!ret) { |
19430 |
++ struct super_block *sb; |
19431 |
++ struct dl_info *dli; |
19432 |
++ |
19433 |
++ ret = -EINVAL; |
19434 |
++ if (!path.dentry->d_inode) |
19435 |
++ goto out_release; |
19436 |
++ if (!(sb = path.dentry->d_inode->i_sb)) |
19437 |
++ goto out_release; |
19438 |
++ |
19439 |
++ if (add) { |
19440 |
++ dli = __alloc_dl_info(sb, id); |
19441 |
++ spin_lock(&dl_info_hash_lock); |
19442 |
++ |
19443 |
++ ret = -EEXIST; |
19444 |
++ if (__lookup_dl_info(sb, id)) |
19445 |
++ goto out_unlock; |
19446 |
++ __hash_dl_info(dli); |
19447 |
++ dli = NULL; |
19448 |
++ } else { |
19449 |
++ spin_lock(&dl_info_hash_lock); |
19450 |
++ dli = __lookup_dl_info(sb, id); |
19451 |
++ |
19452 |
++ ret = -ESRCH; |
19453 |
++ if (!dli) |
19454 |
++ goto out_unlock; |
19455 |
++ __unhash_dl_info(dli); |
19456 |
++ } |
19457 |
++ ret = 0; |
19458 |
++ out_unlock: |
19459 |
++ spin_unlock(&dl_info_hash_lock); |
19460 |
++ if (add && dli) |
19461 |
++ __dealloc_dl_info(dli); |
19462 |
++ out_release: |
19463 |
++ path_put(&path); |
19464 |
++ } |
19465 |
++ return ret; |
19466 |
++} |
19467 |
++ |
19468 |
++int vc_add_dlimit(uint32_t id, void __user *data) |
19469 |
++{ |
19470 |
++ struct vcmd_ctx_dlimit_base_v0 vc_data; |
19471 |
++ |
19472 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19473 |
++ return -EFAULT; |
19474 |
++ |
19475 |
++ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1); |
19476 |
++} |
19477 |
++ |
19478 |
++int vc_rem_dlimit(uint32_t id, void __user *data) |
19479 |
++{ |
19480 |
++ struct vcmd_ctx_dlimit_base_v0 vc_data; |
19481 |
++ |
19482 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19483 |
++ return -EFAULT; |
19484 |
++ |
19485 |
++ return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0); |
19486 |
++} |
19487 |
++ |
19488 |
++#ifdef CONFIG_COMPAT |
19489 |
++ |
19490 |
++int vc_add_dlimit_x32(uint32_t id, void __user *data) |
19491 |
++{ |
19492 |
++ struct vcmd_ctx_dlimit_base_v0_x32 vc_data; |
19493 |
++ |
19494 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19495 |
++ return -EFAULT; |
19496 |
++ |
19497 |
++ return do_addrem_dlimit(id, |
19498 |
++ compat_ptr(vc_data.name_ptr), vc_data.flags, 1); |
19499 |
++} |
19500 |
++ |
19501 |
++int vc_rem_dlimit_x32(uint32_t id, void __user *data) |
19502 |
++{ |
19503 |
++ struct vcmd_ctx_dlimit_base_v0_x32 vc_data; |
19504 |
++ |
19505 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19506 |
++ return -EFAULT; |
19507 |
++ |
19508 |
++ return do_addrem_dlimit(id, |
19509 |
++ compat_ptr(vc_data.name_ptr), vc_data.flags, 0); |
19510 |
++} |
19511 |
++ |
19512 |
++#endif /* CONFIG_COMPAT */ |
19513 |
++ |
19514 |
++ |
19515 |
++static inline |
19516 |
++int do_set_dlimit(uint32_t id, const char __user *name, |
19517 |
++ uint32_t space_used, uint32_t space_total, |
19518 |
++ uint32_t inodes_used, uint32_t inodes_total, |
19519 |
++ uint32_t reserved, uint32_t flags) |
19520 |
++{ |
19521 |
++ struct path path; |
19522 |
++ int ret; |
19523 |
++ |
19524 |
++ ret = user_lpath(name, &path); |
19525 |
++ if (!ret) { |
19526 |
++ struct super_block *sb; |
19527 |
++ struct dl_info *dli; |
19528 |
++ |
19529 |
++ ret = -EINVAL; |
19530 |
++ if (!path.dentry->d_inode) |
19531 |
++ goto out_release; |
19532 |
++ if (!(sb = path.dentry->d_inode->i_sb)) |
19533 |
++ goto out_release; |
19534 |
++ if ((reserved != CDLIM_KEEP && |
19535 |
++ reserved > 100) || |
19536 |
++ (inodes_used != CDLIM_KEEP && |
19537 |
++ inodes_used > inodes_total) || |
19538 |
++ (space_used != CDLIM_KEEP && |
19539 |
++ space_used > space_total)) |
19540 |
++ goto out_release; |
19541 |
++ |
19542 |
++ ret = -ESRCH; |
19543 |
++ dli = locate_dl_info(sb, id); |
19544 |
++ if (!dli) |
19545 |
++ goto out_release; |
19546 |
++ |
19547 |
++ spin_lock(&dli->dl_lock); |
19548 |
++ |
19549 |
++ if (inodes_used != CDLIM_KEEP) |
19550 |
++ dli->dl_inodes_used = inodes_used; |
19551 |
++ if (inodes_total != CDLIM_KEEP) |
19552 |
++ dli->dl_inodes_total = inodes_total; |
19553 |
++ if (space_used != CDLIM_KEEP) { |
19554 |
++ dli->dl_space_used = space_used; |
19555 |
++ dli->dl_space_used <<= 10; |
19556 |
++ } |
19557 |
++ if (space_total == CDLIM_INFINITY) |
19558 |
++ dli->dl_space_total = DLIM_INFINITY; |
19559 |
++ else if (space_total != CDLIM_KEEP) { |
19560 |
++ dli->dl_space_total = space_total; |
19561 |
++ dli->dl_space_total <<= 10; |
19562 |
++ } |
19563 |
++ if (reserved != CDLIM_KEEP) |
19564 |
++ dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100; |
19565 |
++ |
19566 |
++ spin_unlock(&dli->dl_lock); |
19567 |
++ |
19568 |
++ put_dl_info(dli); |
19569 |
++ ret = 0; |
19570 |
++ |
19571 |
++ out_release: |
19572 |
++ path_put(&path); |
19573 |
++ } |
19574 |
++ return ret; |
19575 |
++} |
19576 |
++ |
19577 |
++int vc_set_dlimit(uint32_t id, void __user *data) |
19578 |
++{ |
19579 |
++ struct vcmd_ctx_dlimit_v0 vc_data; |
19580 |
++ |
19581 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19582 |
++ return -EFAULT; |
19583 |
++ |
19584 |
++ return do_set_dlimit(id, vc_data.name, |
19585 |
++ vc_data.space_used, vc_data.space_total, |
19586 |
++ vc_data.inodes_used, vc_data.inodes_total, |
19587 |
++ vc_data.reserved, vc_data.flags); |
19588 |
++} |
19589 |
++ |
19590 |
++#ifdef CONFIG_COMPAT |
19591 |
++ |
19592 |
++int vc_set_dlimit_x32(uint32_t id, void __user *data) |
19593 |
++{ |
19594 |
++ struct vcmd_ctx_dlimit_v0_x32 vc_data; |
19595 |
++ |
19596 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19597 |
++ return -EFAULT; |
19598 |
++ |
19599 |
++ return do_set_dlimit(id, compat_ptr(vc_data.name_ptr), |
19600 |
++ vc_data.space_used, vc_data.space_total, |
19601 |
++ vc_data.inodes_used, vc_data.inodes_total, |
19602 |
++ vc_data.reserved, vc_data.flags); |
19603 |
++} |
19604 |
++ |
19605 |
++#endif /* CONFIG_COMPAT */ |
19606 |
++ |
19607 |
++ |
19608 |
++static inline |
19609 |
++int do_get_dlimit(uint32_t id, const char __user *name, |
19610 |
++ uint32_t *space_used, uint32_t *space_total, |
19611 |
++ uint32_t *inodes_used, uint32_t *inodes_total, |
19612 |
++ uint32_t *reserved, uint32_t *flags) |
19613 |
++{ |
19614 |
++ struct path path; |
19615 |
++ int ret; |
19616 |
++ |
19617 |
++ ret = user_lpath(name, &path); |
19618 |
++ if (!ret) { |
19619 |
++ struct super_block *sb; |
19620 |
++ struct dl_info *dli; |
19621 |
++ |
19622 |
++ ret = -EINVAL; |
19623 |
++ if (!path.dentry->d_inode) |
19624 |
++ goto out_release; |
19625 |
++ if (!(sb = path.dentry->d_inode->i_sb)) |
19626 |
++ goto out_release; |
19627 |
++ |
19628 |
++ ret = -ESRCH; |
19629 |
++ dli = locate_dl_info(sb, id); |
19630 |
++ if (!dli) |
19631 |
++ goto out_release; |
19632 |
++ |
19633 |
++ spin_lock(&dli->dl_lock); |
19634 |
++ *inodes_used = dli->dl_inodes_used; |
19635 |
++ *inodes_total = dli->dl_inodes_total; |
19636 |
++ *space_used = dli->dl_space_used >> 10; |
19637 |
++ if (dli->dl_space_total == DLIM_INFINITY) |
19638 |
++ *space_total = CDLIM_INFINITY; |
19639 |
++ else |
19640 |
++ *space_total = dli->dl_space_total >> 10; |
19641 |
++ |
19642 |
++ *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10); |
19643 |
++ spin_unlock(&dli->dl_lock); |
19644 |
++ |
19645 |
++ put_dl_info(dli); |
19646 |
++ ret = -EFAULT; |
19647 |
++ |
19648 |
++ ret = 0; |
19649 |
++ out_release: |
19650 |
++ path_put(&path); |
19651 |
++ } |
19652 |
++ return ret; |
19653 |
++} |
19654 |
++ |
19655 |
++ |
19656 |
++int vc_get_dlimit(uint32_t id, void __user *data) |
19657 |
++{ |
19658 |
++ struct vcmd_ctx_dlimit_v0 vc_data; |
19659 |
++ int ret; |
19660 |
++ |
19661 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19662 |
++ return -EFAULT; |
19663 |
++ |
19664 |
++ ret = do_get_dlimit(id, vc_data.name, |
19665 |
++ &vc_data.space_used, &vc_data.space_total, |
19666 |
++ &vc_data.inodes_used, &vc_data.inodes_total, |
19667 |
++ &vc_data.reserved, &vc_data.flags); |
19668 |
++ if (ret) |
19669 |
++ return ret; |
19670 |
++ |
19671 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
19672 |
++ return -EFAULT; |
19673 |
++ return 0; |
19674 |
++} |
19675 |
++ |
19676 |
++#ifdef CONFIG_COMPAT |
19677 |
++ |
19678 |
++int vc_get_dlimit_x32(uint32_t id, void __user *data) |
19679 |
++{ |
19680 |
++ struct vcmd_ctx_dlimit_v0_x32 vc_data; |
19681 |
++ int ret; |
19682 |
++ |
19683 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
19684 |
++ return -EFAULT; |
19685 |
++ |
19686 |
++ ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr), |
19687 |
++ &vc_data.space_used, &vc_data.space_total, |
19688 |
++ &vc_data.inodes_used, &vc_data.inodes_total, |
19689 |
++ &vc_data.reserved, &vc_data.flags); |
19690 |
++ if (ret) |
19691 |
++ return ret; |
19692 |
++ |
19693 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
19694 |
++ return -EFAULT; |
19695 |
++ return 0; |
19696 |
++} |
19697 |
++ |
19698 |
++#endif /* CONFIG_COMPAT */ |
19699 |
++ |
19700 |
++ |
19701 |
++void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf) |
19702 |
++{ |
19703 |
++ struct dl_info *dli; |
19704 |
++ __u64 blimit, bfree, bavail; |
19705 |
++ __u32 ifree; |
19706 |
++ |
19707 |
++ dli = locate_dl_info(sb, dx_current_tag()); |
19708 |
++ if (!dli) |
19709 |
++ return; |
19710 |
++ |
19711 |
++ spin_lock(&dli->dl_lock); |
19712 |
++ if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY) |
19713 |
++ goto no_ilim; |
19714 |
++ |
19715 |
++ /* reduce max inodes available to limit */ |
19716 |
++ if (buf->f_files > dli->dl_inodes_total) |
19717 |
++ buf->f_files = dli->dl_inodes_total; |
19718 |
++ |
19719 |
++ ifree = dli->dl_inodes_total - dli->dl_inodes_used; |
19720 |
++ /* reduce free inodes to min */ |
19721 |
++ if (ifree < buf->f_ffree) |
19722 |
++ buf->f_ffree = ifree; |
19723 |
++ |
19724 |
++no_ilim: |
19725 |
++ if (dli->dl_space_total == DLIM_INFINITY) |
19726 |
++ goto no_blim; |
19727 |
++ |
19728 |
++ blimit = dli->dl_space_total >> sb->s_blocksize_bits; |
19729 |
++ |
19730 |
++ if (dli->dl_space_total < dli->dl_space_used) |
19731 |
++ bfree = 0; |
19732 |
++ else |
19733 |
++ bfree = (dli->dl_space_total - dli->dl_space_used) |
19734 |
++ >> sb->s_blocksize_bits; |
19735 |
++ |
19736 |
++ bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult); |
19737 |
++ if (bavail < dli->dl_space_used) |
19738 |
++ bavail = 0; |
19739 |
++ else |
19740 |
++ bavail = (bavail - dli->dl_space_used) |
19741 |
++ >> sb->s_blocksize_bits; |
19742 |
++ |
19743 |
++ /* reduce max space available to limit */ |
19744 |
++ if (buf->f_blocks > blimit) |
19745 |
++ buf->f_blocks = blimit; |
19746 |
++ |
19747 |
++ /* reduce free space to min */ |
19748 |
++ if (bfree < buf->f_bfree) |
19749 |
++ buf->f_bfree = bfree; |
19750 |
++ |
19751 |
++ /* reduce avail space to min */ |
19752 |
++ if (bavail < buf->f_bavail) |
19753 |
++ buf->f_bavail = bavail; |
19754 |
++ |
19755 |
++no_blim: |
19756 |
++ spin_unlock(&dli->dl_lock); |
19757 |
++ put_dl_info(dli); |
19758 |
++ |
19759 |
++ return; |
19760 |
++} |
19761 |
++ |
19762 |
++#include <linux/module.h> |
19763 |
++ |
19764 |
++EXPORT_SYMBOL_GPL(locate_dl_info); |
19765 |
++EXPORT_SYMBOL_GPL(rcu_free_dl_info); |
19766 |
++ |
19767 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/helper.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/helper.c |
19768 |
+--- linux-2.6.29.4/kernel/vserver/helper.c 1970-01-01 01:00:00.000000000 +0100 |
19769 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/helper.c 2009-03-25 00:40:43.000000000 +0100 |
19770 |
+@@ -0,0 +1,199 @@ |
19771 |
++/* |
19772 |
++ * linux/kernel/vserver/helper.c |
19773 |
++ * |
19774 |
++ * Virtual Context Support |
19775 |
++ * |
19776 |
++ * Copyright (C) 2004-2007 Herbert Pötzl |
19777 |
++ * |
19778 |
++ * V0.01 basic helper |
19779 |
++ * |
19780 |
++ */ |
19781 |
++ |
19782 |
++#include <linux/kmod.h> |
19783 |
++#include <linux/reboot.h> |
19784 |
++#include <linux/vs_context.h> |
19785 |
++#include <linux/vs_network.h> |
19786 |
++#include <linux/vserver/signal.h> |
19787 |
++ |
19788 |
++ |
19789 |
++char vshelper_path[255] = "/sbin/vshelper"; |
19790 |
++ |
19791 |
++ |
19792 |
++static int do_vshelper(char *name, char *argv[], char *envp[], int sync) |
19793 |
++{ |
19794 |
++ int ret; |
19795 |
++ |
19796 |
++ if ((ret = call_usermodehelper(name, argv, envp, sync))) { |
19797 |
++ printk( KERN_WARNING |
19798 |
++ "%s: (%s %s) returned %s with %d\n", |
19799 |
++ name, argv[1], argv[2], |
19800 |
++ sync ? "sync" : "async", ret); |
19801 |
++ } |
19802 |
++ vxdprintk(VXD_CBIT(switch, 4), |
19803 |
++ "%s: (%s %s) returned %s with %d", |
19804 |
++ name, argv[1], argv[2], sync ? "sync" : "async", ret); |
19805 |
++ return ret; |
19806 |
++} |
19807 |
++ |
19808 |
++/* |
19809 |
++ * vshelper path is set via /proc/sys |
19810 |
++ * invoked by vserver sys_reboot(), with |
19811 |
++ * the following arguments |
19812 |
++ * |
19813 |
++ * argv [0] = vshelper_path; |
19814 |
++ * argv [1] = action: "restart", "halt", "poweroff", ... |
19815 |
++ * argv [2] = context identifier |
19816 |
++ * |
19817 |
++ * envp [*] = type-specific parameters |
19818 |
++ */ |
19819 |
++ |
19820 |
++long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg) |
19821 |
++{ |
19822 |
++ char id_buf[8], cmd_buf[16]; |
19823 |
++ char uid_buf[16], pid_buf[16]; |
19824 |
++ int ret; |
19825 |
++ |
19826 |
++ char *argv[] = {vshelper_path, NULL, id_buf, 0}; |
19827 |
++ char *envp[] = {"HOME=/", "TERM=linux", |
19828 |
++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", |
19829 |
++ uid_buf, pid_buf, cmd_buf, 0}; |
19830 |
++ |
19831 |
++ if (vx_info_state(vxi, VXS_HELPER)) |
19832 |
++ return -EAGAIN; |
19833 |
++ vxi->vx_state |= VXS_HELPER; |
19834 |
++ |
19835 |
++ snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id); |
19836 |
++ |
19837 |
++ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd); |
19838 |
++ snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current_uid()); |
19839 |
++ snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid); |
19840 |
++ |
19841 |
++ switch (cmd) { |
19842 |
++ case LINUX_REBOOT_CMD_RESTART: |
19843 |
++ argv[1] = "restart"; |
19844 |
++ break; |
19845 |
++ |
19846 |
++ case LINUX_REBOOT_CMD_HALT: |
19847 |
++ argv[1] = "halt"; |
19848 |
++ break; |
19849 |
++ |
19850 |
++ case LINUX_REBOOT_CMD_POWER_OFF: |
19851 |
++ argv[1] = "poweroff"; |
19852 |
++ break; |
19853 |
++ |
19854 |
++ case LINUX_REBOOT_CMD_SW_SUSPEND: |
19855 |
++ argv[1] = "swsusp"; |
19856 |
++ break; |
19857 |
++ |
19858 |
++ default: |
19859 |
++ vxi->vx_state &= ~VXS_HELPER; |
19860 |
++ return 0; |
19861 |
++ } |
19862 |
++ |
19863 |
++ ret = do_vshelper(vshelper_path, argv, envp, 0); |
19864 |
++ vxi->vx_state &= ~VXS_HELPER; |
19865 |
++ __wakeup_vx_info(vxi); |
19866 |
++ return (ret) ? -EPERM : 0; |
19867 |
++} |
19868 |
++ |
19869 |
++ |
19870 |
++long vs_reboot(unsigned int cmd, void __user *arg) |
19871 |
++{ |
19872 |
++ struct vx_info *vxi = current->vx_info; |
19873 |
++ long ret = 0; |
19874 |
++ |
19875 |
++ vxdprintk(VXD_CBIT(misc, 5), |
19876 |
++ "vs_reboot(%p[#%d],%d)", |
19877 |
++ vxi, vxi ? vxi->vx_id : 0, cmd); |
19878 |
++ |
19879 |
++ ret = vs_reboot_helper(vxi, cmd, arg); |
19880 |
++ if (ret) |
19881 |
++ return ret; |
19882 |
++ |
19883 |
++ vxi->reboot_cmd = cmd; |
19884 |
++ if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) { |
19885 |
++ switch (cmd) { |
19886 |
++ case LINUX_REBOOT_CMD_RESTART: |
19887 |
++ case LINUX_REBOOT_CMD_HALT: |
19888 |
++ case LINUX_REBOOT_CMD_POWER_OFF: |
19889 |
++ vx_info_kill(vxi, 0, SIGKILL); |
19890 |
++ vx_info_kill(vxi, 1, SIGKILL); |
19891 |
++ default: |
19892 |
++ break; |
19893 |
++ } |
19894 |
++ } |
19895 |
++ return 0; |
19896 |
++} |
19897 |
++ |
19898 |
++ |
19899 |
++/* |
19900 |
++ * argv [0] = vshelper_path; |
19901 |
++ * argv [1] = action: "startup", "shutdown" |
19902 |
++ * argv [2] = context identifier |
19903 |
++ * |
19904 |
++ * envp [*] = type-specific parameters |
19905 |
++ */ |
19906 |
++ |
19907 |
++long vs_state_change(struct vx_info *vxi, unsigned int cmd) |
19908 |
++{ |
19909 |
++ char id_buf[8], cmd_buf[16]; |
19910 |
++ char *argv[] = {vshelper_path, NULL, id_buf, 0}; |
19911 |
++ char *envp[] = {"HOME=/", "TERM=linux", |
19912 |
++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0}; |
19913 |
++ |
19914 |
++ if (!vx_info_flags(vxi, VXF_SC_HELPER, 0)) |
19915 |
++ return 0; |
19916 |
++ |
19917 |
++ snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id); |
19918 |
++ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd); |
19919 |
++ |
19920 |
++ switch (cmd) { |
19921 |
++ case VSC_STARTUP: |
19922 |
++ argv[1] = "startup"; |
19923 |
++ break; |
19924 |
++ case VSC_SHUTDOWN: |
19925 |
++ argv[1] = "shutdown"; |
19926 |
++ break; |
19927 |
++ default: |
19928 |
++ return 0; |
19929 |
++ } |
19930 |
++ |
19931 |
++ return do_vshelper(vshelper_path, argv, envp, 1); |
19932 |
++} |
19933 |
++ |
19934 |
++ |
19935 |
++/* |
19936 |
++ * argv [0] = vshelper_path; |
19937 |
++ * argv [1] = action: "netup", "netdown" |
19938 |
++ * argv [2] = context identifier |
19939 |
++ * |
19940 |
++ * envp [*] = type-specific parameters |
19941 |
++ */ |
19942 |
++ |
19943 |
++long vs_net_change(struct nx_info *nxi, unsigned int cmd) |
19944 |
++{ |
19945 |
++ char id_buf[8], cmd_buf[16]; |
19946 |
++ char *argv[] = {vshelper_path, NULL, id_buf, 0}; |
19947 |
++ char *envp[] = {"HOME=/", "TERM=linux", |
19948 |
++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0}; |
19949 |
++ |
19950 |
++ if (!nx_info_flags(nxi, NXF_SC_HELPER, 0)) |
19951 |
++ return 0; |
19952 |
++ |
19953 |
++ snprintf(id_buf, sizeof(id_buf)-1, "%d", nxi->nx_id); |
19954 |
++ snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd); |
19955 |
++ |
19956 |
++ switch (cmd) { |
19957 |
++ case VSC_NETUP: |
19958 |
++ argv[1] = "netup"; |
19959 |
++ break; |
19960 |
++ case VSC_NETDOWN: |
19961 |
++ argv[1] = "netdown"; |
19962 |
++ break; |
19963 |
++ default: |
19964 |
++ return 0; |
19965 |
++ } |
19966 |
++ |
19967 |
++ return do_vshelper(vshelper_path, argv, envp, 1); |
19968 |
++} |
19969 |
++ |
19970 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/history.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/history.c |
19971 |
+--- linux-2.6.29.4/kernel/vserver/history.c 1970-01-01 01:00:00.000000000 +0100 |
19972 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/history.c 2009-02-22 22:54:26.000000000 +0100 |
19973 |
+@@ -0,0 +1,258 @@ |
19974 |
++/* |
19975 |
++ * kernel/vserver/history.c |
19976 |
++ * |
19977 |
++ * Virtual Context History Backtrace |
19978 |
++ * |
19979 |
++ * Copyright (C) 2004-2007 Herbert Pötzl |
19980 |
++ * |
19981 |
++ * V0.01 basic structure |
19982 |
++ * V0.02 hash/unhash and trace |
19983 |
++ * V0.03 preemption fixes |
19984 |
++ * |
19985 |
++ */ |
19986 |
++ |
19987 |
++#include <linux/module.h> |
19988 |
++#include <asm/uaccess.h> |
19989 |
++ |
19990 |
++#include <linux/vserver/context.h> |
19991 |
++#include <linux/vserver/debug.h> |
19992 |
++#include <linux/vserver/debug_cmd.h> |
19993 |
++#include <linux/vserver/history.h> |
19994 |
++ |
19995 |
++ |
19996 |
++#ifdef CONFIG_VSERVER_HISTORY |
19997 |
++#define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE |
19998 |
++#else |
19999 |
++#define VXH_SIZE 64 |
20000 |
++#endif |
20001 |
++ |
20002 |
++struct _vx_history { |
20003 |
++ unsigned int counter; |
20004 |
++ |
20005 |
++ struct _vx_hist_entry entry[VXH_SIZE + 1]; |
20006 |
++}; |
20007 |
++ |
20008 |
++ |
20009 |
++DEFINE_PER_CPU(struct _vx_history, vx_history_buffer); |
20010 |
++ |
20011 |
++unsigned volatile int vxh_active = 1; |
20012 |
++ |
20013 |
++static atomic_t sequence = ATOMIC_INIT(0); |
20014 |
++ |
20015 |
++ |
20016 |
++/* vxh_advance() |
20017 |
++ |
20018 |
++ * requires disabled preemption */ |
20019 |
++ |
20020 |
++struct _vx_hist_entry *vxh_advance(void *loc) |
20021 |
++{ |
20022 |
++ unsigned int cpu = smp_processor_id(); |
20023 |
++ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu); |
20024 |
++ struct _vx_hist_entry *entry; |
20025 |
++ unsigned int index; |
20026 |
++ |
20027 |
++ index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE; |
20028 |
++ entry = &hist->entry[index]; |
20029 |
++ |
20030 |
++ entry->seq = atomic_inc_return(&sequence); |
20031 |
++ entry->loc = loc; |
20032 |
++ return entry; |
20033 |
++} |
20034 |
++ |
20035 |
++EXPORT_SYMBOL_GPL(vxh_advance); |
20036 |
++ |
20037 |
++ |
20038 |
++#define VXH_LOC_FMTS "(#%04x,*%d):%p" |
20039 |
++ |
20040 |
++#define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc |
20041 |
++ |
20042 |
++ |
20043 |
++#define VXH_VXI_FMTS "%p[#%d,%d.%d]" |
20044 |
++ |
20045 |
++#define VXH_VXI_ARGS(e) (e)->vxi.ptr, \ |
20046 |
++ (e)->vxi.ptr ? (e)->vxi.xid : 0, \ |
20047 |
++ (e)->vxi.ptr ? (e)->vxi.usecnt : 0, \ |
20048 |
++ (e)->vxi.ptr ? (e)->vxi.tasks : 0 |
20049 |
++ |
20050 |
++void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu) |
20051 |
++{ |
20052 |
++ switch (e->type) { |
20053 |
++ case VXH_THROW_OOPS: |
20054 |
++ printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e)); |
20055 |
++ break; |
20056 |
++ |
20057 |
++ case VXH_GET_VX_INFO: |
20058 |
++ case VXH_PUT_VX_INFO: |
20059 |
++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n", |
20060 |
++ VXH_LOC_ARGS(e), |
20061 |
++ (e->type == VXH_GET_VX_INFO) ? "get" : "put", |
20062 |
++ VXH_VXI_ARGS(e)); |
20063 |
++ break; |
20064 |
++ |
20065 |
++ case VXH_INIT_VX_INFO: |
20066 |
++ case VXH_SET_VX_INFO: |
20067 |
++ case VXH_CLR_VX_INFO: |
20068 |
++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n", |
20069 |
++ VXH_LOC_ARGS(e), |
20070 |
++ (e->type == VXH_INIT_VX_INFO) ? "init" : |
20071 |
++ ((e->type == VXH_SET_VX_INFO) ? "set" : "clr"), |
20072 |
++ VXH_VXI_ARGS(e), e->sc.data); |
20073 |
++ break; |
20074 |
++ |
20075 |
++ case VXH_CLAIM_VX_INFO: |
20076 |
++ case VXH_RELEASE_VX_INFO: |
20077 |
++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n", |
20078 |
++ VXH_LOC_ARGS(e), |
20079 |
++ (e->type == VXH_CLAIM_VX_INFO) ? "claim" : "release", |
20080 |
++ VXH_VXI_ARGS(e), e->sc.data); |
20081 |
++ break; |
20082 |
++ |
20083 |
++ case VXH_ALLOC_VX_INFO: |
20084 |
++ case VXH_DEALLOC_VX_INFO: |
20085 |
++ printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n", |
20086 |
++ VXH_LOC_ARGS(e), |
20087 |
++ (e->type == VXH_ALLOC_VX_INFO) ? "alloc" : "dealloc", |
20088 |
++ VXH_VXI_ARGS(e)); |
20089 |
++ break; |
20090 |
++ |
20091 |
++ case VXH_HASH_VX_INFO: |
20092 |
++ case VXH_UNHASH_VX_INFO: |
20093 |
++ printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n", |
20094 |
++ VXH_LOC_ARGS(e), |
20095 |
++ (e->type == VXH_HASH_VX_INFO) ? "hash" : "unhash", |
20096 |
++ VXH_VXI_ARGS(e)); |
20097 |
++ break; |
20098 |
++ |
20099 |
++ case VXH_LOC_VX_INFO: |
20100 |
++ case VXH_LOOKUP_VX_INFO: |
20101 |
++ case VXH_CREATE_VX_INFO: |
20102 |
++ printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n", |
20103 |
++ VXH_LOC_ARGS(e), |
20104 |
++ (e->type == VXH_CREATE_VX_INFO) ? "create" : |
20105 |
++ ((e->type == VXH_LOC_VX_INFO) ? "loc" : "lookup"), |
20106 |
++ e->ll.arg, VXH_VXI_ARGS(e)); |
20107 |
++ break; |
20108 |
++ } |
20109 |
++} |
20110 |
++ |
20111 |
++static void __vxh_dump_history(void) |
20112 |
++{ |
20113 |
++ unsigned int i, cpu; |
20114 |
++ |
20115 |
++ printk("History:\tSEQ: %8x\tNR_CPUS: %d\n", |
20116 |
++ atomic_read(&sequence), NR_CPUS); |
20117 |
++ |
20118 |
++ for (i = 0; i < VXH_SIZE; i++) { |
20119 |
++ for_each_online_cpu(cpu) { |
20120 |
++ struct _vx_history *hist = |
20121 |
++ &per_cpu(vx_history_buffer, cpu); |
20122 |
++ unsigned int index = (hist->counter - i) % VXH_SIZE; |
20123 |
++ struct _vx_hist_entry *entry = &hist->entry[index]; |
20124 |
++ |
20125 |
++ vxh_dump_entry(entry, cpu); |
20126 |
++ } |
20127 |
++ } |
20128 |
++} |
20129 |
++ |
20130 |
++void vxh_dump_history(void) |
20131 |
++{ |
20132 |
++ vxh_active = 0; |
20133 |
++#ifdef CONFIG_SMP |
20134 |
++ local_irq_enable(); |
20135 |
++ smp_send_stop(); |
20136 |
++ local_irq_disable(); |
20137 |
++#endif |
20138 |
++ __vxh_dump_history(); |
20139 |
++} |
20140 |
++ |
20141 |
++ |
20142 |
++/* vserver syscall commands below here */ |
20143 |
++ |
20144 |
++ |
20145 |
++int vc_dump_history(uint32_t id) |
20146 |
++{ |
20147 |
++ vxh_active = 0; |
20148 |
++ __vxh_dump_history(); |
20149 |
++ vxh_active = 1; |
20150 |
++ |
20151 |
++ return 0; |
20152 |
++} |
20153 |
++ |
20154 |
++ |
20155 |
++int do_read_history(struct __user _vx_hist_entry *data, |
20156 |
++ int cpu, uint32_t *index, uint32_t *count) |
20157 |
++{ |
20158 |
++ int pos, ret = 0; |
20159 |
++ struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu); |
20160 |
++ int end = hist->counter; |
20161 |
++ int start = end - VXH_SIZE + 2; |
20162 |
++ int idx = *index; |
20163 |
++ |
20164 |
++ /* special case: get current pos */ |
20165 |
++ if (!*count) { |
20166 |
++ *index = end; |
20167 |
++ return 0; |
20168 |
++ } |
20169 |
++ |
20170 |
++ /* have we lost some data? */ |
20171 |
++ if (idx < start) |
20172 |
++ idx = start; |
20173 |
++ |
20174 |
++ for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) { |
20175 |
++ struct _vx_hist_entry *entry = |
20176 |
++ &hist->entry[idx % VXH_SIZE]; |
20177 |
++ |
20178 |
++ /* send entry to userspace */ |
20179 |
++ ret = copy_to_user(&data[pos], entry, sizeof(*entry)); |
20180 |
++ if (ret) |
20181 |
++ break; |
20182 |
++ } |
20183 |
++ /* save new index and count */ |
20184 |
++ *index = idx; |
20185 |
++ *count = pos; |
20186 |
++ return ret ? ret : (*index < end); |
20187 |
++} |
20188 |
++ |
20189 |
++int vc_read_history(uint32_t id, void __user *data) |
20190 |
++{ |
20191 |
++ struct vcmd_read_history_v0 vc_data; |
20192 |
++ int ret; |
20193 |
++ |
20194 |
++ if (id >= NR_CPUS) |
20195 |
++ return -EINVAL; |
20196 |
++ |
20197 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
20198 |
++ return -EFAULT; |
20199 |
++ |
20200 |
++ ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data, |
20201 |
++ id, &vc_data.index, &vc_data.count); |
20202 |
++ |
20203 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
20204 |
++ return -EFAULT; |
20205 |
++ return ret; |
20206 |
++} |
20207 |
++ |
20208 |
++#ifdef CONFIG_COMPAT |
20209 |
++ |
20210 |
++int vc_read_history_x32(uint32_t id, void __user *data) |
20211 |
++{ |
20212 |
++ struct vcmd_read_history_v0_x32 vc_data; |
20213 |
++ int ret; |
20214 |
++ |
20215 |
++ if (id >= NR_CPUS) |
20216 |
++ return -EINVAL; |
20217 |
++ |
20218 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
20219 |
++ return -EFAULT; |
20220 |
++ |
20221 |
++ ret = do_read_history((struct __user _vx_hist_entry *) |
20222 |
++ compat_ptr(vc_data.data_ptr), |
20223 |
++ id, &vc_data.index, &vc_data.count); |
20224 |
++ |
20225 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
20226 |
++ return -EFAULT; |
20227 |
++ return ret; |
20228 |
++} |
20229 |
++ |
20230 |
++#endif /* CONFIG_COMPAT */ |
20231 |
++ |
20232 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/inet.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/inet.c |
20233 |
+--- linux-2.6.29.4/kernel/vserver/inet.c 1970-01-01 01:00:00.000000000 +0100 |
20234 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/inet.c 2009-02-22 22:54:26.000000000 +0100 |
20235 |
+@@ -0,0 +1,225 @@ |
20236 |
++ |
20237 |
++#include <linux/in.h> |
20238 |
++#include <linux/inetdevice.h> |
20239 |
++#include <linux/vs_inet.h> |
20240 |
++#include <linux/vs_inet6.h> |
20241 |
++#include <linux/vserver/debug.h> |
20242 |
++#include <net/route.h> |
20243 |
++#include <net/addrconf.h> |
20244 |
++ |
20245 |
++ |
20246 |
++int nx_v4_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2) |
20247 |
++{ |
20248 |
++ int ret = 0; |
20249 |
++ |
20250 |
++ if (!nxi1 || !nxi2 || nxi1 == nxi2) |
20251 |
++ ret = 1; |
20252 |
++ else { |
20253 |
++ struct nx_addr_v4 *ptr; |
20254 |
++ |
20255 |
++ for (ptr = &nxi1->v4; ptr; ptr = ptr->next) { |
20256 |
++ if (v4_nx_addr_in_nx_info(nxi2, ptr, -1)) { |
20257 |
++ ret = 1; |
20258 |
++ break; |
20259 |
++ } |
20260 |
++ } |
20261 |
++ } |
20262 |
++ |
20263 |
++ vxdprintk(VXD_CBIT(net, 2), |
20264 |
++ "nx_v4_addr_conflict(%p,%p): %d", |
20265 |
++ nxi1, nxi2, ret); |
20266 |
++ |
20267 |
++ return ret; |
20268 |
++} |
20269 |
++ |
20270 |
++ |
20271 |
++#ifdef CONFIG_IPV6 |
20272 |
++ |
20273 |
++int nx_v6_addr_conflict(struct nx_info *nxi1, struct nx_info *nxi2) |
20274 |
++{ |
20275 |
++ int ret = 0; |
20276 |
++ |
20277 |
++ if (!nxi1 || !nxi2 || nxi1 == nxi2) |
20278 |
++ ret = 1; |
20279 |
++ else { |
20280 |
++ struct nx_addr_v6 *ptr; |
20281 |
++ |
20282 |
++ for (ptr = &nxi1->v6; ptr; ptr = ptr->next) { |
20283 |
++ if (v6_nx_addr_in_nx_info(nxi2, ptr, -1)) { |
20284 |
++ ret = 1; |
20285 |
++ break; |
20286 |
++ } |
20287 |
++ } |
20288 |
++ } |
20289 |
++ |
20290 |
++ vxdprintk(VXD_CBIT(net, 2), |
20291 |
++ "nx_v6_addr_conflict(%p,%p): %d", |
20292 |
++ nxi1, nxi2, ret); |
20293 |
++ |
20294 |
++ return ret; |
20295 |
++} |
20296 |
++ |
20297 |
++#endif |
20298 |
++ |
20299 |
++int v4_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi) |
20300 |
++{ |
20301 |
++ struct in_device *in_dev; |
20302 |
++ struct in_ifaddr **ifap; |
20303 |
++ struct in_ifaddr *ifa; |
20304 |
++ int ret = 0; |
20305 |
++ |
20306 |
++ if (!dev) |
20307 |
++ goto out; |
20308 |
++ in_dev = in_dev_get(dev); |
20309 |
++ if (!in_dev) |
20310 |
++ goto out; |
20311 |
++ |
20312 |
++ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; |
20313 |
++ ifap = &ifa->ifa_next) { |
20314 |
++ if (v4_addr_in_nx_info(nxi, ifa->ifa_local, NXA_MASK_SHOW)) { |
20315 |
++ ret = 1; |
20316 |
++ break; |
20317 |
++ } |
20318 |
++ } |
20319 |
++ in_dev_put(in_dev); |
20320 |
++out: |
20321 |
++ return ret; |
20322 |
++} |
20323 |
++ |
20324 |
++ |
20325 |
++#ifdef CONFIG_IPV6 |
20326 |
++ |
20327 |
++int v6_dev_in_nx_info(struct net_device *dev, struct nx_info *nxi) |
20328 |
++{ |
20329 |
++ struct inet6_dev *in_dev; |
20330 |
++ struct inet6_ifaddr **ifap; |
20331 |
++ struct inet6_ifaddr *ifa; |
20332 |
++ int ret = 0; |
20333 |
++ |
20334 |
++ if (!dev) |
20335 |
++ goto out; |
20336 |
++ in_dev = in6_dev_get(dev); |
20337 |
++ if (!in_dev) |
20338 |
++ goto out; |
20339 |
++ |
20340 |
++ for (ifap = &in_dev->addr_list; (ifa = *ifap) != NULL; |
20341 |
++ ifap = &ifa->if_next) { |
20342 |
++ if (v6_addr_in_nx_info(nxi, &ifa->addr, -1)) { |
20343 |
++ ret = 1; |
20344 |
++ break; |
20345 |
++ } |
20346 |
++ } |
20347 |
++ in6_dev_put(in_dev); |
20348 |
++out: |
20349 |
++ return ret; |
20350 |
++} |
20351 |
++ |
20352 |
++#endif |
20353 |
++ |
20354 |
++int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi) |
20355 |
++{ |
20356 |
++ int ret = 1; |
20357 |
++ |
20358 |
++ if (!nxi) |
20359 |
++ goto out; |
20360 |
++ if (nxi->v4.type && v4_dev_in_nx_info(dev, nxi)) |
20361 |
++ goto out; |
20362 |
++#ifdef CONFIG_IPV6 |
20363 |
++ ret = 2; |
20364 |
++ if (nxi->v6.type && v6_dev_in_nx_info(dev, nxi)) |
20365 |
++ goto out; |
20366 |
++#endif |
20367 |
++ ret = 0; |
20368 |
++out: |
20369 |
++ vxdprintk(VXD_CBIT(net, 3), |
20370 |
++ "dev_in_nx_info(%p,%p[#%d]) = %d", |
20371 |
++ dev, nxi, nxi ? nxi->nx_id : 0, ret); |
20372 |
++ return ret; |
20373 |
++} |
20374 |
++ |
20375 |
++int ip_v4_find_src(struct net *net, struct nx_info *nxi, |
20376 |
++ struct rtable **rp, struct flowi *fl) |
20377 |
++{ |
20378 |
++ if (!nxi) |
20379 |
++ return 0; |
20380 |
++ |
20381 |
++ /* FIXME: handle lback only case */ |
20382 |
++ if (!NX_IPV4(nxi)) |
20383 |
++ return -EPERM; |
20384 |
++ |
20385 |
++ vxdprintk(VXD_CBIT(net, 4), |
20386 |
++ "ip_v4_find_src(%p[#%u]) " NIPQUAD_FMT " -> " NIPQUAD_FMT, |
20387 |
++ nxi, nxi ? nxi->nx_id : 0, |
20388 |
++ NIPQUAD(fl->fl4_src), NIPQUAD(fl->fl4_dst)); |
20389 |
++ |
20390 |
++ /* single IP is unconditional */ |
20391 |
++ if (nx_info_flags(nxi, NXF_SINGLE_IP, 0) && |
20392 |
++ (fl->fl4_src == INADDR_ANY)) |
20393 |
++ fl->fl4_src = nxi->v4.ip[0].s_addr; |
20394 |
++ |
20395 |
++ if (fl->fl4_src == INADDR_ANY) { |
20396 |
++ struct nx_addr_v4 *ptr; |
20397 |
++ __be32 found = 0; |
20398 |
++ int err; |
20399 |
++ |
20400 |
++ err = __ip_route_output_key(net, rp, fl); |
20401 |
++ if (!err) { |
20402 |
++ found = (*rp)->rt_src; |
20403 |
++ ip_rt_put(*rp); |
20404 |
++ vxdprintk(VXD_CBIT(net, 4), |
20405 |
++ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT, |
20406 |
++ nxi, nxi ? nxi->nx_id : 0, fl->oif, NIPQUAD(found)); |
20407 |
++ if (v4_addr_in_nx_info(nxi, found, NXA_MASK_BIND)) |
20408 |
++ goto found; |
20409 |
++ } |
20410 |
++ |
20411 |
++ for (ptr = &nxi->v4; ptr; ptr = ptr->next) { |
20412 |
++ __be32 primary = ptr->ip[0].s_addr; |
20413 |
++ __be32 mask = ptr->mask.s_addr; |
20414 |
++ __be32 neta = primary & mask; |
20415 |
++ |
20416 |
++ vxdprintk(VXD_CBIT(net, 4), "ip_v4_find_src(%p[#%u]) chk: " |
20417 |
++ NIPQUAD_FMT "/" NIPQUAD_FMT "/" NIPQUAD_FMT, |
20418 |
++ nxi, nxi ? nxi->nx_id : 0, NIPQUAD(primary), |
20419 |
++ NIPQUAD(mask), NIPQUAD(neta)); |
20420 |
++ if ((found & mask) != neta) |
20421 |
++ continue; |
20422 |
++ |
20423 |
++ fl->fl4_src = primary; |
20424 |
++ err = __ip_route_output_key(net, rp, fl); |
20425 |
++ vxdprintk(VXD_CBIT(net, 4), |
20426 |
++ "ip_v4_find_src(%p[#%u]) rok[%u]: " NIPQUAD_FMT, |
20427 |
++ nxi, nxi ? nxi->nx_id : 0, fl->oif, NIPQUAD(primary)); |
20428 |
++ if (!err) { |
20429 |
++ found = (*rp)->rt_src; |
20430 |
++ ip_rt_put(*rp); |
20431 |
++ if (found == primary) |
20432 |
++ goto found; |
20433 |
++ } |
20434 |
++ } |
20435 |
++ /* still no source ip? */ |
20436 |
++ found = ipv4_is_loopback(fl->fl4_dst) |
20437 |
++ ? IPI_LOOPBACK : nxi->v4.ip[0].s_addr; |
20438 |
++ found: |
20439 |
++ /* assign src ip to flow */ |
20440 |
++ fl->fl4_src = found; |
20441 |
++ |
20442 |
++ } else { |
20443 |
++ if (!v4_addr_in_nx_info(nxi, fl->fl4_src, NXA_MASK_BIND)) |
20444 |
++ return -EPERM; |
20445 |
++ } |
20446 |
++ |
20447 |
++ if (nx_info_flags(nxi, NXF_LBACK_REMAP, 0)) { |
20448 |
++ if (ipv4_is_loopback(fl->fl4_dst)) |
20449 |
++ fl->fl4_dst = nxi->v4_lback.s_addr; |
20450 |
++ if (ipv4_is_loopback(fl->fl4_src)) |
20451 |
++ fl->fl4_src = nxi->v4_lback.s_addr; |
20452 |
++ } else if (ipv4_is_loopback(fl->fl4_dst) && |
20453 |
++ !nx_info_flags(nxi, NXF_LBACK_ALLOW, 0)) |
20454 |
++ return -EPERM; |
20455 |
++ |
20456 |
++ return 0; |
20457 |
++} |
20458 |
++ |
20459 |
++EXPORT_SYMBOL_GPL(ip_v4_find_src); |
20460 |
++ |
20461 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/init.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/init.c |
20462 |
+--- linux-2.6.29.4/kernel/vserver/init.c 1970-01-01 01:00:00.000000000 +0100 |
20463 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/init.c 2009-02-22 22:54:26.000000000 +0100 |
20464 |
+@@ -0,0 +1,45 @@ |
20465 |
++/* |
20466 |
++ * linux/kernel/init.c |
20467 |
++ * |
20468 |
++ * Virtual Server Init |
20469 |
++ * |
20470 |
++ * Copyright (C) 2004-2007 Herbert Pötzl |
20471 |
++ * |
20472 |
++ * V0.01 basic structure |
20473 |
++ * |
20474 |
++ */ |
20475 |
++ |
20476 |
++#include <linux/init.h> |
20477 |
++ |
20478 |
++int vserver_register_sysctl(void); |
20479 |
++void vserver_unregister_sysctl(void); |
20480 |
++ |
20481 |
++ |
20482 |
++static int __init init_vserver(void) |
20483 |
++{ |
20484 |
++ int ret = 0; |
20485 |
++ |
20486 |
++#ifdef CONFIG_VSERVER_DEBUG |
20487 |
++ vserver_register_sysctl(); |
20488 |
++#endif |
20489 |
++ return ret; |
20490 |
++} |
20491 |
++ |
20492 |
++ |
20493 |
++static void __exit exit_vserver(void) |
20494 |
++{ |
20495 |
++ |
20496 |
++#ifdef CONFIG_VSERVER_DEBUG |
20497 |
++ vserver_unregister_sysctl(); |
20498 |
++#endif |
20499 |
++ return; |
20500 |
++} |
20501 |
++ |
20502 |
++/* FIXME: GFP_ZONETYPES gone |
20503 |
++long vx_slab[GFP_ZONETYPES]; */ |
20504 |
++long vx_area; |
20505 |
++ |
20506 |
++ |
20507 |
++module_init(init_vserver); |
20508 |
++module_exit(exit_vserver); |
20509 |
++ |
20510 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/inode.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/inode.c |
20511 |
+--- linux-2.6.29.4/kernel/vserver/inode.c 1970-01-01 01:00:00.000000000 +0100 |
20512 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/inode.c 2009-02-22 22:54:26.000000000 +0100 |
20513 |
+@@ -0,0 +1,422 @@ |
20514 |
++/* |
20515 |
++ * linux/kernel/vserver/inode.c |
20516 |
++ * |
20517 |
++ * Virtual Server: File System Support |
20518 |
++ * |
20519 |
++ * Copyright (C) 2004-2007 Herbert Pötzl |
20520 |
++ * |
20521 |
++ * V0.01 separated from vcontext V0.05 |
20522 |
++ * V0.02 moved to tag (instead of xid) |
20523 |
++ * |
20524 |
++ */ |
20525 |
++ |
20526 |
++#include <linux/tty.h> |
20527 |
++#include <linux/proc_fs.h> |
20528 |
++#include <linux/devpts_fs.h> |
20529 |
++#include <linux/fs.h> |
20530 |
++#include <linux/file.h> |
20531 |
++#include <linux/mount.h> |
20532 |
++#include <linux/parser.h> |
20533 |
++#include <linux/namei.h> |
20534 |
++#include <linux/vserver/inode.h> |
20535 |
++#include <linux/vserver/inode_cmd.h> |
20536 |
++#include <linux/vs_base.h> |
20537 |
++#include <linux/vs_tag.h> |
20538 |
++ |
20539 |
++#include <asm/uaccess.h> |
20540 |
++ |
20541 |
++ |
20542 |
++static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask) |
20543 |
++{ |
20544 |
++ struct proc_dir_entry *entry; |
20545 |
++ |
20546 |
++ if (!in || !in->i_sb) |
20547 |
++ return -ESRCH; |
20548 |
++ |
20549 |
++ *flags = IATTR_TAG |
20550 |
++ | (IS_BARRIER(in) ? IATTR_BARRIER : 0) |
20551 |
++ | (IS_IXUNLINK(in) ? IATTR_IXUNLINK : 0) |
20552 |
++ | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0); |
20553 |
++ *mask = IATTR_IXUNLINK | IATTR_IMMUTABLE; |
20554 |
++ |
20555 |
++ if (S_ISDIR(in->i_mode)) |
20556 |
++ *mask |= IATTR_BARRIER; |
20557 |
++ |
20558 |
++ if (IS_TAGGED(in)) { |
20559 |
++ *tag = in->i_tag; |
20560 |
++ *mask |= IATTR_TAG; |
20561 |
++ } |
20562 |
++ |
20563 |
++ switch (in->i_sb->s_magic) { |
20564 |
++ case PROC_SUPER_MAGIC: |
20565 |
++ entry = PROC_I(in)->pde; |
20566 |
++ |
20567 |
++ /* check for specific inodes? */ |
20568 |
++ if (entry) |
20569 |
++ *mask |= IATTR_FLAGS; |
20570 |
++ if (entry) |
20571 |
++ *flags |= (entry->vx_flags & IATTR_FLAGS); |
20572 |
++ else |
20573 |
++ *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS); |
20574 |
++ break; |
20575 |
++ |
20576 |
++ case DEVPTS_SUPER_MAGIC: |
20577 |
++ *tag = in->i_tag; |
20578 |
++ *mask |= IATTR_TAG; |
20579 |
++ break; |
20580 |
++ |
20581 |
++ default: |
20582 |
++ break; |
20583 |
++ } |
20584 |
++ return 0; |
20585 |
++} |
20586 |
++ |
20587 |
++int vc_get_iattr(void __user *data) |
20588 |
++{ |
20589 |
++ struct path path; |
20590 |
++ struct vcmd_ctx_iattr_v1 vc_data = { .tag = -1 }; |
20591 |
++ int ret; |
20592 |
++ |
20593 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
20594 |
++ return -EFAULT; |
20595 |
++ |
20596 |
++ ret = user_lpath(vc_data.name, &path); |
20597 |
++ if (!ret) { |
20598 |
++ ret = __vc_get_iattr(path.dentry->d_inode, |
20599 |
++ &vc_data.tag, &vc_data.flags, &vc_data.mask); |
20600 |
++ path_put(&path); |
20601 |
++ } |
20602 |
++ if (ret) |
20603 |
++ return ret; |
20604 |
++ |
20605 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
20606 |
++ ret = -EFAULT; |
20607 |
++ return ret; |
20608 |
++} |
20609 |
++ |
20610 |
++#ifdef CONFIG_COMPAT |
20611 |
++ |
20612 |
++int vc_get_iattr_x32(void __user *data) |
20613 |
++{ |
20614 |
++ struct path path; |
20615 |
++ struct vcmd_ctx_iattr_v1_x32 vc_data = { .tag = -1 }; |
20616 |
++ int ret; |
20617 |
++ |
20618 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
20619 |
++ return -EFAULT; |
20620 |
++ |
20621 |
++ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path); |
20622 |
++ if (!ret) { |
20623 |
++ ret = __vc_get_iattr(path.dentry->d_inode, |
20624 |
++ &vc_data.tag, &vc_data.flags, &vc_data.mask); |
20625 |
++ path_put(&path); |
20626 |
++ } |
20627 |
++ if (ret) |
20628 |
++ return ret; |
20629 |
++ |
20630 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
20631 |
++ ret = -EFAULT; |
20632 |
++ return ret; |
20633 |
++} |
20634 |
++ |
20635 |
++#endif /* CONFIG_COMPAT */ |
20636 |
++ |
20637 |
++ |
20638 |
++int vc_fget_iattr(uint32_t fd, void __user *data) |
20639 |
++{ |
20640 |
++ struct file *filp; |
20641 |
++ struct vcmd_ctx_fiattr_v0 vc_data = { .tag = -1 }; |
20642 |
++ int ret; |
20643 |
++ |
20644 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
20645 |
++ return -EFAULT; |
20646 |
++ |
20647 |
++ filp = fget(fd); |
20648 |
++ if (!filp || !filp->f_dentry || !filp->f_dentry->d_inode) |
20649 |
++ return -EBADF; |
20650 |
++ |
20651 |
++ ret = __vc_get_iattr(filp->f_dentry->d_inode, |
20652 |
++ &vc_data.tag, &vc_data.flags, &vc_data.mask); |
20653 |
++ |
20654 |
++ fput(filp); |
20655 |
++ |
20656 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
20657 |
++ ret = -EFAULT; |
20658 |
++ return ret; |
20659 |
++} |
20660 |
++ |
20661 |
++ |
20662 |
++static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask) |
20663 |
++{ |
20664 |
++ struct inode *in = de->d_inode; |
20665 |
++ int error = 0, is_proc = 0, has_tag = 0; |
20666 |
++ struct iattr attr = { 0 }; |
20667 |
++ |
20668 |
++ if (!in || !in->i_sb) |
20669 |
++ return -ESRCH; |
20670 |
++ |
20671 |
++ is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC); |
20672 |
++ if ((*mask & IATTR_FLAGS) && !is_proc) |
20673 |
++ return -EINVAL; |
20674 |
++ |
20675 |
++ has_tag = IS_TAGGED(in) || |
20676 |
++ (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC); |
20677 |
++ if ((*mask & IATTR_TAG) && !has_tag) |
20678 |
++ return -EINVAL; |
20679 |
++ |
20680 |
++ mutex_lock(&in->i_mutex); |
20681 |
++ if (*mask & IATTR_TAG) { |
20682 |
++ attr.ia_tag = *tag; |
20683 |
++ attr.ia_valid |= ATTR_TAG; |
20684 |
++ } |
20685 |
++ |
20686 |
++ if (*mask & IATTR_FLAGS) { |
20687 |
++ struct proc_dir_entry *entry = PROC_I(in)->pde; |
20688 |
++ unsigned int iflags = PROC_I(in)->vx_flags; |
20689 |
++ |
20690 |
++ iflags = (iflags & ~(*mask & IATTR_FLAGS)) |
20691 |
++ | (*flags & IATTR_FLAGS); |
20692 |
++ PROC_I(in)->vx_flags = iflags; |
20693 |
++ if (entry) |
20694 |
++ entry->vx_flags = iflags; |
20695 |
++ } |
20696 |
++ |
20697 |
++ if (*mask & (IATTR_BARRIER | IATTR_IXUNLINK | IATTR_IMMUTABLE)) { |
20698 |
++ if (*mask & IATTR_IMMUTABLE) { |
20699 |
++ if (*flags & IATTR_IMMUTABLE) |
20700 |
++ in->i_flags |= S_IMMUTABLE; |
20701 |
++ else |
20702 |
++ in->i_flags &= ~S_IMMUTABLE; |
20703 |
++ } |
20704 |
++ if (*mask & IATTR_IXUNLINK) { |
20705 |
++ if (*flags & IATTR_IXUNLINK) |
20706 |
++ in->i_flags |= S_IXUNLINK; |
20707 |
++ else |
20708 |
++ in->i_flags &= ~S_IXUNLINK; |
20709 |
++ } |
20710 |
++ if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) { |
20711 |
++ if (*flags & IATTR_BARRIER) |
20712 |
++ in->i_vflags |= V_BARRIER; |
20713 |
++ else |
20714 |
++ in->i_vflags &= ~V_BARRIER; |
20715 |
++ } |
20716 |
++ if (in->i_op && in->i_op->sync_flags) { |
20717 |
++ error = in->i_op->sync_flags(in); |
20718 |
++ if (error) |
20719 |
++ goto out; |
20720 |
++ } |
20721 |
++ } |
20722 |
++ |
20723 |
++ if (attr.ia_valid) { |
20724 |
++ if (in->i_op && in->i_op->setattr) |
20725 |
++ error = in->i_op->setattr(de, &attr); |
20726 |
++ else { |
20727 |
++ error = inode_change_ok(in, &attr); |
20728 |
++ if (!error) |
20729 |
++ error = inode_setattr(in, &attr); |
20730 |
++ } |
20731 |
++ } |
20732 |
++ |
20733 |
++out: |
20734 |
++ mutex_unlock(&in->i_mutex); |
20735 |
++ return error; |
20736 |
++} |
20737 |
++ |
20738 |
++int vc_set_iattr(void __user *data) |
20739 |
++{ |
20740 |
++ struct path path; |
20741 |
++ struct vcmd_ctx_iattr_v1 vc_data; |
20742 |
++ int ret; |
20743 |
++ |
20744 |
++ if (!capable(CAP_LINUX_IMMUTABLE)) |
20745 |
++ return -EPERM; |
20746 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
20747 |
++ return -EFAULT; |
20748 |
++ |
20749 |
++ ret = user_lpath(vc_data.name, &path); |
20750 |
++ if (!ret) { |
20751 |
++ ret = __vc_set_iattr(path.dentry, |
20752 |
++ &vc_data.tag, &vc_data.flags, &vc_data.mask); |
20753 |
++ path_put(&path); |
20754 |
++ } |
20755 |
++ |
20756 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
20757 |
++ ret = -EFAULT; |
20758 |
++ return ret; |
20759 |
++} |
20760 |
++ |
20761 |
++#ifdef CONFIG_COMPAT |
20762 |
++ |
20763 |
++int vc_set_iattr_x32(void __user *data) |
20764 |
++{ |
20765 |
++ struct path path; |
20766 |
++ struct vcmd_ctx_iattr_v1_x32 vc_data; |
20767 |
++ int ret; |
20768 |
++ |
20769 |
++ if (!capable(CAP_LINUX_IMMUTABLE)) |
20770 |
++ return -EPERM; |
20771 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
20772 |
++ return -EFAULT; |
20773 |
++ |
20774 |
++ ret = user_lpath(compat_ptr(vc_data.name_ptr), &path); |
20775 |
++ if (!ret) { |
20776 |
++ ret = __vc_set_iattr(path.dentry, |
20777 |
++ &vc_data.tag, &vc_data.flags, &vc_data.mask); |
20778 |
++ path_put(&path); |
20779 |
++ } |
20780 |
++ |
20781 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
20782 |
++ ret = -EFAULT; |
20783 |
++ return ret; |
20784 |
++} |
20785 |
++ |
20786 |
++#endif /* CONFIG_COMPAT */ |
20787 |
++ |
20788 |
++int vc_fset_iattr(uint32_t fd, void __user *data) |
20789 |
++{ |
20790 |
++ struct file *filp; |
20791 |
++ struct vcmd_ctx_fiattr_v0 vc_data; |
20792 |
++ int ret; |
20793 |
++ |
20794 |
++ if (!capable(CAP_LINUX_IMMUTABLE)) |
20795 |
++ return -EPERM; |
20796 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
20797 |
++ return -EFAULT; |
20798 |
++ |
20799 |
++ filp = fget(fd); |
20800 |
++ if (!filp || !filp->f_dentry || !filp->f_dentry->d_inode) |
20801 |
++ return -EBADF; |
20802 |
++ |
20803 |
++ ret = __vc_set_iattr(filp->f_dentry, &vc_data.tag, |
20804 |
++ &vc_data.flags, &vc_data.mask); |
20805 |
++ |
20806 |
++ fput(filp); |
20807 |
++ |
20808 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
20809 |
++ return -EFAULT; |
20810 |
++ return ret; |
20811 |
++} |
20812 |
++ |
20813 |
++ |
20814 |
++enum { Opt_notagcheck, Opt_tag, Opt_notag, Opt_tagid, Opt_err }; |
20815 |
++ |
20816 |
++static match_table_t tokens = { |
20817 |
++ {Opt_notagcheck, "notagcheck"}, |
20818 |
++#ifdef CONFIG_PROPAGATE |
20819 |
++ {Opt_notag, "notag"}, |
20820 |
++ {Opt_tag, "tag"}, |
20821 |
++ {Opt_tagid, "tagid=%u"}, |
20822 |
++#endif |
20823 |
++ {Opt_err, NULL} |
20824 |
++}; |
20825 |
++ |
20826 |
++ |
20827 |
++static void __dx_parse_remove(char *string, char *opt) |
20828 |
++{ |
20829 |
++ char *p = strstr(string, opt); |
20830 |
++ char *q = p; |
20831 |
++ |
20832 |
++ if (p) { |
20833 |
++ while (*q != '\0' && *q != ',') |
20834 |
++ q++; |
20835 |
++ while (*q) |
20836 |
++ *p++ = *q++; |
20837 |
++ while (*p) |
20838 |
++ *p++ = '\0'; |
20839 |
++ } |
20840 |
++} |
20841 |
++ |
20842 |
++int dx_parse_tag(char *string, tag_t *tag, int remove, int *mnt_flags, |
20843 |
++ unsigned long *flags) |
20844 |
++{ |
20845 |
++ int set = 0; |
20846 |
++ substring_t args[MAX_OPT_ARGS]; |
20847 |
++ int token, option = 0; |
20848 |
++ char *s, *p, *opts; |
20849 |
++ |
20850 |
++ if (!string) |
20851 |
++ return 0; |
20852 |
++ s = kstrdup(string, GFP_KERNEL | GFP_ATOMIC); |
20853 |
++ if (!s) |
20854 |
++ return 0; |
20855 |
++ |
20856 |
++ opts = s; |
20857 |
++ while ((p = strsep(&opts, ",")) != NULL) { |
20858 |
++ token = match_token(p, tokens, args); |
20859 |
++ |
20860 |
++ vxdprintk(VXD_CBIT(tag, 7), |
20861 |
++ "dx_parse_tag(»%s«): %d:#%d", |
20862 |
++ p, token, option); |
20863 |
++ |
20864 |
++ switch (token) { |
20865 |
++#ifdef CONFIG_PROPAGATE |
20866 |
++ case Opt_tag: |
20867 |
++ if (tag) |
20868 |
++ *tag = 0; |
20869 |
++ if (remove) |
20870 |
++ __dx_parse_remove(s, "tag"); |
20871 |
++ *mnt_flags |= MNT_TAGID; |
20872 |
++ set |= MNT_TAGID; |
20873 |
++ break; |
20874 |
++ case Opt_notag: |
20875 |
++ if (remove) |
20876 |
++ __dx_parse_remove(s, "notag"); |
20877 |
++ *mnt_flags |= MNT_NOTAG; |
20878 |
++ set |= MNT_NOTAG; |
20879 |
++ break; |
20880 |
++ case Opt_tagid: |
20881 |
++ if (tag && !match_int(args, &option)) |
20882 |
++ *tag = option; |
20883 |
++ if (remove) |
20884 |
++ __dx_parse_remove(s, "tagid"); |
20885 |
++ *mnt_flags |= MNT_TAGID; |
20886 |
++ set |= MNT_TAGID; |
20887 |
++ break; |
20888 |
++#endif |
20889 |
++ case Opt_notagcheck: |
20890 |
++ if (remove) |
20891 |
++ __dx_parse_remove(s, "notagcheck"); |
20892 |
++ *flags |= MS_NOTAGCHECK; |
20893 |
++ set |= MS_NOTAGCHECK; |
20894 |
++ break; |
20895 |
++ } |
20896 |
++ } |
20897 |
++ if (set) |
20898 |
++ strcpy(string, s); |
20899 |
++ kfree(s); |
20900 |
++ return set; |
20901 |
++} |
20902 |
++ |
20903 |
++#ifdef CONFIG_PROPAGATE |
20904 |
++ |
20905 |
++void __dx_propagate_tag(struct nameidata *nd, struct inode *inode) |
20906 |
++{ |
20907 |
++ tag_t new_tag = 0; |
20908 |
++ struct vfsmount *mnt; |
20909 |
++ int propagate; |
20910 |
++ |
20911 |
++ if (!nd) |
20912 |
++ return; |
20913 |
++ mnt = nd->path.mnt; |
20914 |
++ if (!mnt) |
20915 |
++ return; |
20916 |
++ |
20917 |
++ propagate = (mnt->mnt_flags & MNT_TAGID); |
20918 |
++ if (propagate) |
20919 |
++ new_tag = mnt->mnt_tag; |
20920 |
++ |
20921 |
++ vxdprintk(VXD_CBIT(tag, 7), |
20922 |
++ "dx_propagate_tag(%p[#%lu.%d]): %d,%d", |
20923 |
++ inode, inode->i_ino, inode->i_tag, |
20924 |
++ new_tag, (propagate) ? 1 : 0); |
20925 |
++ |
20926 |
++ if (propagate) |
20927 |
++ inode->i_tag = new_tag; |
20928 |
++} |
20929 |
++ |
20930 |
++#include <linux/module.h> |
20931 |
++ |
20932 |
++EXPORT_SYMBOL_GPL(__dx_propagate_tag); |
20933 |
++ |
20934 |
++#endif /* CONFIG_PROPAGATE */ |
20935 |
++ |
20936 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/Kconfig linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/Kconfig |
20937 |
+--- linux-2.6.29.4/kernel/vserver/Kconfig 1970-01-01 01:00:00.000000000 +0100 |
20938 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/Kconfig 2009-02-22 22:54:26.000000000 +0100 |
20939 |
+@@ -0,0 +1,251 @@ |
20940 |
++# |
20941 |
++# Linux VServer configuration |
20942 |
++# |
20943 |
++ |
20944 |
++menu "Linux VServer" |
20945 |
++ |
20946 |
++config VSERVER_AUTO_LBACK |
20947 |
++ bool "Automatically Assign Loopback IP" |
20948 |
++ default y |
20949 |
++ help |
20950 |
++ Automatically assign a guest specific loopback |
20951 |
++ IP and add it to the kernel network stack on |
20952 |
++ startup. |
20953 |
++ |
20954 |
++config VSERVER_AUTO_SINGLE |
20955 |
++ bool "Automatic Single IP Special Casing" |
20956 |
++ depends on EXPERIMENTAL |
20957 |
++ default y |
20958 |
++ help |
20959 |
++ This allows network contexts with a single IP to |
20960 |
++ automatically remap 0.0.0.0 bindings to that IP, |
20961 |
++ avoiding further network checks and improving |
20962 |
++ performance. |
20963 |
++ |
20964 |
++ (note: such guests do not allow to change the ip |
20965 |
++ on the fly and do not show loopback addresses) |
20966 |
++ |
20967 |
++config VSERVER_COWBL |
20968 |
++ bool "Enable COW Immutable Link Breaking" |
20969 |
++ default y |
20970 |
++ help |
20971 |
++ This enables the COW (Copy-On-Write) link break code. |
20972 |
++ It allows you to treat unified files like normal files |
20973 |
++ when writing to them (which will implicitely break the |
20974 |
++ link and create a copy of the unified file) |
20975 |
++ |
20976 |
++config VSERVER_VTIME |
20977 |
++ bool "Enable Virtualized Guest Time" |
20978 |
++ depends on EXPERIMENTAL |
20979 |
++ default n |
20980 |
++ help |
20981 |
++ This enables per guest time offsets to allow for |
20982 |
++ adjusting the system clock individually per guest. |
20983 |
++ this adds some overhead to the time functions and |
20984 |
++ therefore should not be enabled without good reason. |
20985 |
++ |
20986 |
++config VSERVER_DEVICE |
20987 |
++ bool "Enable Guest Device Mapping" |
20988 |
++ depends on EXPERIMENTAL |
20989 |
++ default n |
20990 |
++ help |
20991 |
++ This enables generic device remapping. |
20992 |
++ |
20993 |
++config VSERVER_PROC_SECURE |
20994 |
++ bool "Enable Proc Security" |
20995 |
++ depends on PROC_FS |
20996 |
++ default y |
20997 |
++ help |
20998 |
++ This configures ProcFS security to initially hide |
20999 |
++ non-process entries for all contexts except the main and |
21000 |
++ spectator context (i.e. for all guests), which is a secure |
21001 |
++ default. |
21002 |
++ |
21003 |
++ (note: on 1.2x the entries were visible by default) |
21004 |
++ |
21005 |
++config VSERVER_HARDCPU |
21006 |
++ bool "Enable Hard CPU Limits" |
21007 |
++ default y |
21008 |
++ help |
21009 |
++ Activate the Hard CPU Limits |
21010 |
++ |
21011 |
++ This will compile in code that allows the Token Bucket |
21012 |
++ Scheduler to put processes on hold when a context's |
21013 |
++ tokens are depleted (provided that its per-context |
21014 |
++ sched_hard flag is set). |
21015 |
++ |
21016 |
++ Processes belonging to that context will not be able |
21017 |
++ to consume CPU resources again until a per-context |
21018 |
++ configured minimum of tokens has been reached. |
21019 |
++ |
21020 |
++config VSERVER_IDLETIME |
21021 |
++ bool "Avoid idle CPUs by skipping Time" |
21022 |
++ depends on VSERVER_HARDCPU |
21023 |
++ default y |
21024 |
++ help |
21025 |
++ This option allows the scheduler to artificially |
21026 |
++ advance time (per cpu) when otherwise the idle |
21027 |
++ task would be scheduled, thus keeping the cpu |
21028 |
++ busy and sharing the available resources among |
21029 |
++ certain contexts. |
21030 |
++ |
21031 |
++config VSERVER_IDLELIMIT |
21032 |
++ bool "Limit the IDLE task" |
21033 |
++ depends on VSERVER_HARDCPU |
21034 |
++ default n |
21035 |
++ help |
21036 |
++ Limit the idle slices, so the the next context |
21037 |
++ will be scheduled as soon as possible. |
21038 |
++ |
21039 |
++ This might improve interactivity and latency, but |
21040 |
++ will also marginally increase scheduling overhead. |
21041 |
++ |
21042 |
++choice |
21043 |
++ prompt "Persistent Inode Tagging" |
21044 |
++ default TAGGING_ID24 |
21045 |
++ help |
21046 |
++ This adds persistent context information to filesystems |
21047 |
++ mounted with the tagxid option. Tagging is a requirement |
21048 |
++ for per-context disk limits and per-context quota. |
21049 |
++ |
21050 |
++ |
21051 |
++config TAGGING_NONE |
21052 |
++ bool "Disabled" |
21053 |
++ help |
21054 |
++ do not store per-context information in inodes. |
21055 |
++ |
21056 |
++config TAGGING_UID16 |
21057 |
++ bool "UID16/GID32" |
21058 |
++ help |
21059 |
++ reduces UID to 16 bit, but leaves GID at 32 bit. |
21060 |
++ |
21061 |
++config TAGGING_GID16 |
21062 |
++ bool "UID32/GID16" |
21063 |
++ help |
21064 |
++ reduces GID to 16 bit, but leaves UID at 32 bit. |
21065 |
++ |
21066 |
++config TAGGING_ID24 |
21067 |
++ bool "UID24/GID24" |
21068 |
++ help |
21069 |
++ uses the upper 8bit from UID and GID for XID tagging |
21070 |
++ which leaves 24bit for UID/GID each, which should be |
21071 |
++ more than sufficient for normal use. |
21072 |
++ |
21073 |
++config TAGGING_INTERN |
21074 |
++ bool "UID32/GID32" |
21075 |
++ help |
21076 |
++ this uses otherwise reserved inode fields in the on |
21077 |
++ disk representation, which limits the use to a few |
21078 |
++ filesystems (currently ext2 and ext3) |
21079 |
++ |
21080 |
++endchoice |
21081 |
++ |
21082 |
++config TAG_NFSD |
21083 |
++ bool "Tag NFSD User Auth and Files" |
21084 |
++ default n |
21085 |
++ help |
21086 |
++ Enable this if you do want the in-kernel NFS |
21087 |
++ Server to use the tagging specified above. |
21088 |
++ (will require patched clients too) |
21089 |
++ |
21090 |
++config VSERVER_PRIVACY |
21091 |
++ bool "Honor Privacy Aspects of Guests" |
21092 |
++ default n |
21093 |
++ help |
21094 |
++ When enabled, most context checks will disallow |
21095 |
++ access to structures assigned to a specific context, |
21096 |
++ like ptys or loop devices. |
21097 |
++ |
21098 |
++config VSERVER_CONTEXTS |
21099 |
++ int "Maximum number of Contexts (1-65533)" if EMBEDDED |
21100 |
++ range 1 65533 |
21101 |
++ default "768" if 64BIT |
21102 |
++ default "256" |
21103 |
++ help |
21104 |
++ This setting will optimize certain data structures |
21105 |
++ and memory allocations according to the expected |
21106 |
++ maximum. |
21107 |
++ |
21108 |
++ note: this is not a strict upper limit. |
21109 |
++ |
21110 |
++config VSERVER_WARN |
21111 |
++ bool "VServer Warnings" |
21112 |
++ default y |
21113 |
++ help |
21114 |
++ This enables various runtime warnings, which will |
21115 |
++ notify about potential manipulation attempts or |
21116 |
++ resource shortage. It is generally considered to |
21117 |
++ be a good idea to have that enabled. |
21118 |
++ |
21119 |
++config VSERVER_DEBUG |
21120 |
++ bool "VServer Debugging Code" |
21121 |
++ default n |
21122 |
++ help |
21123 |
++ Set this to yes if you want to be able to activate |
21124 |
++ debugging output at runtime. It adds a very small |
21125 |
++ overhead to all vserver related functions and |
21126 |
++ increases the kernel size by about 20k. |
21127 |
++ |
21128 |
++config VSERVER_HISTORY |
21129 |
++ bool "VServer History Tracing" |
21130 |
++ depends on VSERVER_DEBUG |
21131 |
++ default n |
21132 |
++ help |
21133 |
++ Set this to yes if you want to record the history of |
21134 |
++ linux-vserver activities, so they can be replayed in |
21135 |
++ the event of a kernel panic or oops. |
21136 |
++ |
21137 |
++config VSERVER_HISTORY_SIZE |
21138 |
++ int "Per-CPU History Size (32-65536)" |
21139 |
++ depends on VSERVER_HISTORY |
21140 |
++ range 32 65536 |
21141 |
++ default 64 |
21142 |
++ help |
21143 |
++ This allows you to specify the number of entries in |
21144 |
++ the per-CPU history buffer. |
21145 |
++ |
21146 |
++config VSERVER_MONITOR |
21147 |
++ bool "VServer Scheduling Monitor" |
21148 |
++ depends on VSERVER_DISABLED |
21149 |
++ default n |
21150 |
++ help |
21151 |
++ Set this to yes if you want to record the scheduling |
21152 |
++ decisions, so that they can be relayed to userspace |
21153 |
++ for detailed analysis. |
21154 |
++ |
21155 |
++config VSERVER_MONITOR_SIZE |
21156 |
++ int "Per-CPU Monitor Queue Size (32-65536)" |
21157 |
++ depends on VSERVER_MONITOR |
21158 |
++ range 32 65536 |
21159 |
++ default 1024 |
21160 |
++ help |
21161 |
++ This allows you to specify the number of entries in |
21162 |
++ the per-CPU scheduling monitor buffer. |
21163 |
++ |
21164 |
++config VSERVER_MONITOR_SYNC |
21165 |
++ int "Per-CPU Monitor Sync Interval (0-65536)" |
21166 |
++ depends on VSERVER_MONITOR |
21167 |
++ range 0 65536 |
21168 |
++ default 256 |
21169 |
++ help |
21170 |
++ This allows you to specify the interval in ticks |
21171 |
++ when a time sync entry is inserted. |
21172 |
++ |
21173 |
++endmenu |
21174 |
++ |
21175 |
++ |
21176 |
++config VSERVER |
21177 |
++ bool |
21178 |
++ default y |
21179 |
++ select NAMESPACES |
21180 |
++ select UTS_NS |
21181 |
++ select IPC_NS |
21182 |
++ select USER_NS |
21183 |
++ select SYSVIPC |
21184 |
++ |
21185 |
++config VSERVER_SECURITY |
21186 |
++ bool |
21187 |
++ depends on SECURITY |
21188 |
++ default y |
21189 |
++ select SECURITY_CAPABILITIES |
21190 |
++ |
21191 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/limit.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/limit.c |
21192 |
+--- linux-2.6.29.4/kernel/vserver/limit.c 1970-01-01 01:00:00.000000000 +0100 |
21193 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/limit.c 2009-02-22 22:54:26.000000000 +0100 |
21194 |
+@@ -0,0 +1,319 @@ |
21195 |
++/* |
21196 |
++ * linux/kernel/vserver/limit.c |
21197 |
++ * |
21198 |
++ * Virtual Server: Context Limits |
21199 |
++ * |
21200 |
++ * Copyright (C) 2004-2007 Herbert Pötzl |
21201 |
++ * |
21202 |
++ * V0.01 broken out from vcontext V0.05 |
21203 |
++ * V0.02 changed vcmds to vxi arg |
21204 |
++ * |
21205 |
++ */ |
21206 |
++ |
21207 |
++#include <linux/sched.h> |
21208 |
++#include <linux/module.h> |
21209 |
++#include <linux/vs_limit.h> |
21210 |
++#include <linux/vserver/limit.h> |
21211 |
++#include <linux/vserver/limit_cmd.h> |
21212 |
++ |
21213 |
++#include <asm/uaccess.h> |
21214 |
++ |
21215 |
++ |
21216 |
++const char *vlimit_name[NUM_LIMITS] = { |
21217 |
++ [RLIMIT_CPU] = "CPU", |
21218 |
++ [RLIMIT_RSS] = "RSS", |
21219 |
++ [RLIMIT_NPROC] = "NPROC", |
21220 |
++ [RLIMIT_NOFILE] = "NOFILE", |
21221 |
++ [RLIMIT_MEMLOCK] = "VML", |
21222 |
++ [RLIMIT_AS] = "VM", |
21223 |
++ [RLIMIT_LOCKS] = "LOCKS", |
21224 |
++ [RLIMIT_SIGPENDING] = "SIGP", |
21225 |
++ [RLIMIT_MSGQUEUE] = "MSGQ", |
21226 |
++ |
21227 |
++ [VLIMIT_NSOCK] = "NSOCK", |
21228 |
++ [VLIMIT_OPENFD] = "OPENFD", |
21229 |
++ [VLIMIT_ANON] = "ANON", |
21230 |
++ [VLIMIT_SHMEM] = "SHMEM", |
21231 |
++ [VLIMIT_DENTRY] = "DENTRY", |
21232 |
++}; |
21233 |
++ |
21234 |
++EXPORT_SYMBOL_GPL(vlimit_name); |
21235 |
++ |
21236 |
++#define MASK_ENTRY(x) (1 << (x)) |
21237 |
++ |
21238 |
++const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = { |
21239 |
++ /* minimum */ |
21240 |
++ 0 |
21241 |
++ , /* softlimit */ |
21242 |
++ MASK_ENTRY( RLIMIT_RSS ) | |
21243 |
++ MASK_ENTRY( VLIMIT_ANON ) | |
21244 |
++ 0 |
21245 |
++ , /* maximum */ |
21246 |
++ MASK_ENTRY( RLIMIT_RSS ) | |
21247 |
++ MASK_ENTRY( RLIMIT_NPROC ) | |
21248 |
++ MASK_ENTRY( RLIMIT_NOFILE ) | |
21249 |
++ MASK_ENTRY( RLIMIT_MEMLOCK ) | |
21250 |
++ MASK_ENTRY( RLIMIT_AS ) | |
21251 |
++ MASK_ENTRY( RLIMIT_LOCKS ) | |
21252 |
++ MASK_ENTRY( RLIMIT_MSGQUEUE ) | |
21253 |
++ |
21254 |
++ MASK_ENTRY( VLIMIT_NSOCK ) | |
21255 |
++ MASK_ENTRY( VLIMIT_OPENFD ) | |
21256 |
++ MASK_ENTRY( VLIMIT_ANON ) | |
21257 |
++ MASK_ENTRY( VLIMIT_SHMEM ) | |
21258 |
++ MASK_ENTRY( VLIMIT_DENTRY ) | |
21259 |
++ 0 |
21260 |
++}; |
21261 |
++ /* accounting only */ |
21262 |
++uint32_t account_mask = |
21263 |
++ MASK_ENTRY( VLIMIT_SEMARY ) | |
21264 |
++ MASK_ENTRY( VLIMIT_NSEMS ) | |
21265 |
++ MASK_ENTRY( VLIMIT_MAPPED ) | |
21266 |
++ 0; |
21267 |
++ |
21268 |
++ |
21269 |
++static int is_valid_vlimit(int id) |
21270 |
++{ |
21271 |
++ uint32_t mask = vlimit_mask.minimum | |
21272 |
++ vlimit_mask.softlimit | vlimit_mask.maximum; |
21273 |
++ return mask & (1 << id); |
21274 |
++} |
21275 |
++ |
21276 |
++static int is_accounted_vlimit(int id) |
21277 |
++{ |
21278 |
++ if (is_valid_vlimit(id)) |
21279 |
++ return 1; |
21280 |
++ return account_mask & (1 << id); |
21281 |
++} |
21282 |
++ |
21283 |
++ |
21284 |
++static inline uint64_t vc_get_soft(struct vx_info *vxi, int id) |
21285 |
++{ |
21286 |
++ rlim_t limit = __rlim_soft(&vxi->limit, id); |
21287 |
++ return VX_VLIM(limit); |
21288 |
++} |
21289 |
++ |
21290 |
++static inline uint64_t vc_get_hard(struct vx_info *vxi, int id) |
21291 |
++{ |
21292 |
++ rlim_t limit = __rlim_hard(&vxi->limit, id); |
21293 |
++ return VX_VLIM(limit); |
21294 |
++} |
21295 |
++ |
21296 |
++static int do_get_rlimit(struct vx_info *vxi, uint32_t id, |
21297 |
++ uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum) |
21298 |
++{ |
21299 |
++ if (!is_valid_vlimit(id)) |
21300 |
++ return -EINVAL; |
21301 |
++ |
21302 |
++ if (minimum) |
21303 |
++ *minimum = CRLIM_UNSET; |
21304 |
++ if (softlimit) |
21305 |
++ *softlimit = vc_get_soft(vxi, id); |
21306 |
++ if (maximum) |
21307 |
++ *maximum = vc_get_hard(vxi, id); |
21308 |
++ return 0; |
21309 |
++} |
21310 |
++ |
21311 |
++int vc_get_rlimit(struct vx_info *vxi, void __user *data) |
21312 |
++{ |
21313 |
++ struct vcmd_ctx_rlimit_v0 vc_data; |
21314 |
++ int ret; |
21315 |
++ |
21316 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
21317 |
++ return -EFAULT; |
21318 |
++ |
21319 |
++ ret = do_get_rlimit(vxi, vc_data.id, |
21320 |
++ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum); |
21321 |
++ if (ret) |
21322 |
++ return ret; |
21323 |
++ |
21324 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
21325 |
++ return -EFAULT; |
21326 |
++ return 0; |
21327 |
++} |
21328 |
++ |
21329 |
++static int do_set_rlimit(struct vx_info *vxi, uint32_t id, |
21330 |
++ uint64_t minimum, uint64_t softlimit, uint64_t maximum) |
21331 |
++{ |
21332 |
++ if (!is_valid_vlimit(id)) |
21333 |
++ return -EINVAL; |
21334 |
++ |
21335 |
++ if (maximum != CRLIM_KEEP) |
21336 |
++ __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum); |
21337 |
++ if (softlimit != CRLIM_KEEP) |
21338 |
++ __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit); |
21339 |
++ |
21340 |
++ /* clamp soft limit */ |
21341 |
++ if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id)) |
21342 |
++ __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id); |
21343 |
++ |
21344 |
++ return 0; |
21345 |
++} |
21346 |
++ |
21347 |
++int vc_set_rlimit(struct vx_info *vxi, void __user *data) |
21348 |
++{ |
21349 |
++ struct vcmd_ctx_rlimit_v0 vc_data; |
21350 |
++ |
21351 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
21352 |
++ return -EFAULT; |
21353 |
++ |
21354 |
++ return do_set_rlimit(vxi, vc_data.id, |
21355 |
++ vc_data.minimum, vc_data.softlimit, vc_data.maximum); |
21356 |
++} |
21357 |
++ |
21358 |
++#ifdef CONFIG_IA32_EMULATION |
21359 |
++ |
21360 |
++int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data) |
21361 |
++{ |
21362 |
++ struct vcmd_ctx_rlimit_v0_x32 vc_data; |
21363 |
++ |
21364 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
21365 |
++ return -EFAULT; |
21366 |
++ |
21367 |
++ return do_set_rlimit(vxi, vc_data.id, |
21368 |
++ vc_data.minimum, vc_data.softlimit, vc_data.maximum); |
21369 |
++} |
21370 |
++ |
21371 |
++int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data) |
21372 |
++{ |
21373 |
++ struct vcmd_ctx_rlimit_v0_x32 vc_data; |
21374 |
++ int ret; |
21375 |
++ |
21376 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
21377 |
++ return -EFAULT; |
21378 |
++ |
21379 |
++ ret = do_get_rlimit(vxi, vc_data.id, |
21380 |
++ &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum); |
21381 |
++ if (ret) |
21382 |
++ return ret; |
21383 |
++ |
21384 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
21385 |
++ return -EFAULT; |
21386 |
++ return 0; |
21387 |
++} |
21388 |
++ |
21389 |
++#endif /* CONFIG_IA32_EMULATION */ |
21390 |
++ |
21391 |
++ |
21392 |
++int vc_get_rlimit_mask(uint32_t id, void __user *data) |
21393 |
++{ |
21394 |
++ if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask))) |
21395 |
++ return -EFAULT; |
21396 |
++ return 0; |
21397 |
++} |
21398 |
++ |
21399 |
++ |
21400 |
++static inline void vx_reset_minmax(struct _vx_limit *limit) |
21401 |
++{ |
21402 |
++ rlim_t value; |
21403 |
++ int lim; |
21404 |
++ |
21405 |
++ for (lim = 0; lim < NUM_LIMITS; lim++) { |
21406 |
++ value = __rlim_get(limit, lim); |
21407 |
++ __rlim_rmax(limit, lim) = value; |
21408 |
++ __rlim_rmin(limit, lim) = value; |
21409 |
++ } |
21410 |
++} |
21411 |
++ |
21412 |
++ |
21413 |
++int vc_reset_minmax(struct vx_info *vxi, void __user *data) |
21414 |
++{ |
21415 |
++ vx_reset_minmax(&vxi->limit); |
21416 |
++ return 0; |
21417 |
++} |
21418 |
++ |
21419 |
++ |
21420 |
++int vc_rlimit_stat(struct vx_info *vxi, void __user *data) |
21421 |
++{ |
21422 |
++ struct vcmd_rlimit_stat_v0 vc_data; |
21423 |
++ struct _vx_limit *limit = &vxi->limit; |
21424 |
++ int id; |
21425 |
++ |
21426 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
21427 |
++ return -EFAULT; |
21428 |
++ |
21429 |
++ id = vc_data.id; |
21430 |
++ if (!is_accounted_vlimit(id)) |
21431 |
++ return -EINVAL; |
21432 |
++ |
21433 |
++ vx_limit_fixup(limit, id); |
21434 |
++ vc_data.hits = atomic_read(&__rlim_lhit(limit, id)); |
21435 |
++ vc_data.value = __rlim_get(limit, id); |
21436 |
++ vc_data.minimum = __rlim_rmin(limit, id); |
21437 |
++ vc_data.maximum = __rlim_rmax(limit, id); |
21438 |
++ |
21439 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
21440 |
++ return -EFAULT; |
21441 |
++ return 0; |
21442 |
++} |
21443 |
++ |
21444 |
++ |
21445 |
++void vx_vsi_meminfo(struct sysinfo *val) |
21446 |
++{ |
21447 |
++ struct vx_info *vxi = current->vx_info; |
21448 |
++ unsigned long totalram, freeram; |
21449 |
++ rlim_t v; |
21450 |
++ |
21451 |
++ /* we blindly accept the max */ |
21452 |
++ v = __rlim_soft(&vxi->limit, RLIMIT_RSS); |
21453 |
++ totalram = (v != RLIM_INFINITY) ? v : val->totalram; |
21454 |
++ |
21455 |
++ /* total minus used equals free */ |
21456 |
++ v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS); |
21457 |
++ freeram = (v < totalram) ? totalram - v : 0; |
21458 |
++ |
21459 |
++ val->totalram = totalram; |
21460 |
++ val->freeram = freeram; |
21461 |
++ val->bufferram = 0; |
21462 |
++ val->totalhigh = 0; |
21463 |
++ val->freehigh = 0; |
21464 |
++ return; |
21465 |
++} |
21466 |
++ |
21467 |
++void vx_vsi_swapinfo(struct sysinfo *val) |
21468 |
++{ |
21469 |
++ struct vx_info *vxi = current->vx_info; |
21470 |
++ unsigned long totalswap, freeswap; |
21471 |
++ rlim_t v, w; |
21472 |
++ |
21473 |
++ v = __rlim_soft(&vxi->limit, RLIMIT_RSS); |
21474 |
++ if (v == RLIM_INFINITY) { |
21475 |
++ val->freeswap = val->totalswap; |
21476 |
++ return; |
21477 |
++ } |
21478 |
++ |
21479 |
++ /* we blindly accept the max */ |
21480 |
++ w = __rlim_hard(&vxi->limit, RLIMIT_RSS); |
21481 |
++ totalswap = (w != RLIM_INFINITY) ? (w - v) : val->totalswap; |
21482 |
++ |
21483 |
++ /* currently 'used' swap */ |
21484 |
++ w = __vx_cres_array_fixup(&vxi->limit, VLA_RSS); |
21485 |
++ w -= (w > v) ? v : w; |
21486 |
++ |
21487 |
++ /* total minus used equals free */ |
21488 |
++ freeswap = (w < totalswap) ? totalswap - w : 0; |
21489 |
++ |
21490 |
++ val->totalswap = totalswap; |
21491 |
++ val->freeswap = freeswap; |
21492 |
++ return; |
21493 |
++} |
21494 |
++ |
21495 |
++ |
21496 |
++unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm) |
21497 |
++{ |
21498 |
++ struct vx_info *vxi = mm->mm_vx_info; |
21499 |
++ unsigned long points; |
21500 |
++ rlim_t v, w; |
21501 |
++ |
21502 |
++ if (!vxi) |
21503 |
++ return 0; |
21504 |
++ |
21505 |
++ points = vxi->vx_badness_bias; |
21506 |
++ |
21507 |
++ v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS); |
21508 |
++ w = __rlim_soft(&vxi->limit, RLIMIT_RSS); |
21509 |
++ points += (v > w) ? (v - w) : 0; |
21510 |
++ |
21511 |
++ return points; |
21512 |
++} |
21513 |
++ |
21514 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/limit_init.h linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/limit_init.h |
21515 |
+--- linux-2.6.29.4/kernel/vserver/limit_init.h 1970-01-01 01:00:00.000000000 +0100 |
21516 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/limit_init.h 2009-02-22 22:54:26.000000000 +0100 |
21517 |
+@@ -0,0 +1,31 @@ |
21518 |
++ |
21519 |
++ |
21520 |
++static inline void vx_info_init_limit(struct _vx_limit *limit) |
21521 |
++{ |
21522 |
++ int lim; |
21523 |
++ |
21524 |
++ for (lim = 0; lim < NUM_LIMITS; lim++) { |
21525 |
++ __rlim_soft(limit, lim) = RLIM_INFINITY; |
21526 |
++ __rlim_hard(limit, lim) = RLIM_INFINITY; |
21527 |
++ __rlim_set(limit, lim, 0); |
21528 |
++ atomic_set(&__rlim_lhit(limit, lim), 0); |
21529 |
++ __rlim_rmin(limit, lim) = 0; |
21530 |
++ __rlim_rmax(limit, lim) = 0; |
21531 |
++ } |
21532 |
++} |
21533 |
++ |
21534 |
++static inline void vx_info_exit_limit(struct _vx_limit *limit) |
21535 |
++{ |
21536 |
++ rlim_t value; |
21537 |
++ int lim; |
21538 |
++ |
21539 |
++ for (lim = 0; lim < NUM_LIMITS; lim++) { |
21540 |
++ if ((1 << lim) & VLIM_NOCHECK) |
21541 |
++ continue; |
21542 |
++ value = __rlim_get(limit, lim); |
21543 |
++ vxwprintk_xid(value, |
21544 |
++ "!!! limit: %p[%s,%d] = %ld on exit.", |
21545 |
++ limit, vlimit_name[lim], lim, (long)value); |
21546 |
++ } |
21547 |
++} |
21548 |
++ |
21549 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/limit_proc.h linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/limit_proc.h |
21550 |
+--- linux-2.6.29.4/kernel/vserver/limit_proc.h 1970-01-01 01:00:00.000000000 +0100 |
21551 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/limit_proc.h 2009-02-22 22:54:26.000000000 +0100 |
21552 |
+@@ -0,0 +1,57 @@ |
21553 |
++#ifndef _VX_LIMIT_PROC_H |
21554 |
++#define _VX_LIMIT_PROC_H |
21555 |
++ |
21556 |
++#include <linux/vserver/limit_int.h> |
21557 |
++ |
21558 |
++ |
21559 |
++#define VX_LIMIT_FMT ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n" |
21560 |
++#define VX_LIMIT_TOP \ |
21561 |
++ "Limit\t current\t min/max\t\t soft/hard\t\thits\n" |
21562 |
++ |
21563 |
++#define VX_LIMIT_ARG(r) \ |
21564 |
++ (unsigned long)__rlim_get(limit, r), \ |
21565 |
++ (unsigned long)__rlim_rmin(limit, r), \ |
21566 |
++ (unsigned long)__rlim_rmax(limit, r), \ |
21567 |
++ VX_VLIM(__rlim_soft(limit, r)), \ |
21568 |
++ VX_VLIM(__rlim_hard(limit, r)), \ |
21569 |
++ atomic_read(&__rlim_lhit(limit, r)) |
21570 |
++ |
21571 |
++static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer) |
21572 |
++{ |
21573 |
++ vx_limit_fixup(limit, -1); |
21574 |
++ return sprintf(buffer, VX_LIMIT_TOP |
21575 |
++ "PROC" VX_LIMIT_FMT |
21576 |
++ "VM" VX_LIMIT_FMT |
21577 |
++ "VML" VX_LIMIT_FMT |
21578 |
++ "RSS" VX_LIMIT_FMT |
21579 |
++ "ANON" VX_LIMIT_FMT |
21580 |
++ "RMAP" VX_LIMIT_FMT |
21581 |
++ "FILES" VX_LIMIT_FMT |
21582 |
++ "OFD" VX_LIMIT_FMT |
21583 |
++ "LOCKS" VX_LIMIT_FMT |
21584 |
++ "SOCK" VX_LIMIT_FMT |
21585 |
++ "MSGQ" VX_LIMIT_FMT |
21586 |
++ "SHM" VX_LIMIT_FMT |
21587 |
++ "SEMA" VX_LIMIT_FMT |
21588 |
++ "SEMS" VX_LIMIT_FMT |
21589 |
++ "DENT" VX_LIMIT_FMT, |
21590 |
++ VX_LIMIT_ARG(RLIMIT_NPROC), |
21591 |
++ VX_LIMIT_ARG(RLIMIT_AS), |
21592 |
++ VX_LIMIT_ARG(RLIMIT_MEMLOCK), |
21593 |
++ VX_LIMIT_ARG(RLIMIT_RSS), |
21594 |
++ VX_LIMIT_ARG(VLIMIT_ANON), |
21595 |
++ VX_LIMIT_ARG(VLIMIT_MAPPED), |
21596 |
++ VX_LIMIT_ARG(RLIMIT_NOFILE), |
21597 |
++ VX_LIMIT_ARG(VLIMIT_OPENFD), |
21598 |
++ VX_LIMIT_ARG(RLIMIT_LOCKS), |
21599 |
++ VX_LIMIT_ARG(VLIMIT_NSOCK), |
21600 |
++ VX_LIMIT_ARG(RLIMIT_MSGQUEUE), |
21601 |
++ VX_LIMIT_ARG(VLIMIT_SHMEM), |
21602 |
++ VX_LIMIT_ARG(VLIMIT_SEMARY), |
21603 |
++ VX_LIMIT_ARG(VLIMIT_NSEMS), |
21604 |
++ VX_LIMIT_ARG(VLIMIT_DENTRY)); |
21605 |
++} |
21606 |
++ |
21607 |
++#endif /* _VX_LIMIT_PROC_H */ |
21608 |
++ |
21609 |
++ |
21610 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/Makefile linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/Makefile |
21611 |
+--- linux-2.6.29.4/kernel/vserver/Makefile 1970-01-01 01:00:00.000000000 +0100 |
21612 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/Makefile 2009-02-22 22:54:26.000000000 +0100 |
21613 |
+@@ -0,0 +1,18 @@ |
21614 |
++# |
21615 |
++# Makefile for the Linux vserver routines. |
21616 |
++# |
21617 |
++ |
21618 |
++ |
21619 |
++obj-y += vserver.o |
21620 |
++ |
21621 |
++vserver-y := switch.o context.o space.o sched.o network.o inode.o \ |
21622 |
++ limit.o cvirt.o cacct.o signal.o helper.o init.o \ |
21623 |
++ dlimit.o tag.o |
21624 |
++ |
21625 |
++vserver-$(CONFIG_INET) += inet.o |
21626 |
++vserver-$(CONFIG_PROC_FS) += proc.o |
21627 |
++vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o |
21628 |
++vserver-$(CONFIG_VSERVER_HISTORY) += history.o |
21629 |
++vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o |
21630 |
++vserver-$(CONFIG_VSERVER_DEVICE) += device.o |
21631 |
++ |
21632 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/monitor.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/monitor.c |
21633 |
+--- linux-2.6.29.4/kernel/vserver/monitor.c 1970-01-01 01:00:00.000000000 +0100 |
21634 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/monitor.c 2009-02-22 22:54:26.000000000 +0100 |
21635 |
+@@ -0,0 +1,138 @@ |
21636 |
++/* |
21637 |
++ * kernel/vserver/monitor.c |
21638 |
++ * |
21639 |
++ * Virtual Context Scheduler Monitor |
21640 |
++ * |
21641 |
++ * Copyright (C) 2006-2007 Herbert Pötzl |
21642 |
++ * |
21643 |
++ * V0.01 basic design |
21644 |
++ * |
21645 |
++ */ |
21646 |
++ |
21647 |
++#include <linux/module.h> |
21648 |
++#include <linux/jiffies.h> |
21649 |
++#include <asm/uaccess.h> |
21650 |
++#include <asm/atomic.h> |
21651 |
++ |
21652 |
++#include <linux/vserver/monitor.h> |
21653 |
++#include <linux/vserver/debug_cmd.h> |
21654 |
++ |
21655 |
++ |
21656 |
++#ifdef CONFIG_VSERVER_MONITOR |
21657 |
++#define VXM_SIZE CONFIG_VSERVER_MONITOR_SIZE |
21658 |
++#else |
21659 |
++#define VXM_SIZE 64 |
21660 |
++#endif |
21661 |
++ |
21662 |
++struct _vx_monitor { |
21663 |
++ unsigned int counter; |
21664 |
++ |
21665 |
++ struct _vx_mon_entry entry[VXM_SIZE+1]; |
21666 |
++}; |
21667 |
++ |
21668 |
++ |
21669 |
++DEFINE_PER_CPU(struct _vx_monitor, vx_monitor_buffer); |
21670 |
++ |
21671 |
++unsigned volatile int vxm_active = 1; |
21672 |
++ |
21673 |
++static atomic_t sequence = ATOMIC_INIT(0); |
21674 |
++ |
21675 |
++ |
21676 |
++/* vxm_advance() |
21677 |
++ |
21678 |
++ * requires disabled preemption */ |
21679 |
++ |
21680 |
++struct _vx_mon_entry *vxm_advance(int cpu) |
21681 |
++{ |
21682 |
++ struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu); |
21683 |
++ struct _vx_mon_entry *entry; |
21684 |
++ unsigned int index; |
21685 |
++ |
21686 |
++ index = vxm_active ? (mon->counter++ % VXM_SIZE) : VXM_SIZE; |
21687 |
++ entry = &mon->entry[index]; |
21688 |
++ |
21689 |
++ entry->ev.seq = atomic_inc_return(&sequence); |
21690 |
++ entry->ev.jif = jiffies; |
21691 |
++ return entry; |
21692 |
++} |
21693 |
++ |
21694 |
++EXPORT_SYMBOL_GPL(vxm_advance); |
21695 |
++ |
21696 |
++ |
21697 |
++int do_read_monitor(struct __user _vx_mon_entry *data, |
21698 |
++ int cpu, uint32_t *index, uint32_t *count) |
21699 |
++{ |
21700 |
++ int pos, ret = 0; |
21701 |
++ struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu); |
21702 |
++ int end = mon->counter; |
21703 |
++ int start = end - VXM_SIZE + 2; |
21704 |
++ int idx = *index; |
21705 |
++ |
21706 |
++ /* special case: get current pos */ |
21707 |
++ if (!*count) { |
21708 |
++ *index = end; |
21709 |
++ return 0; |
21710 |
++ } |
21711 |
++ |
21712 |
++ /* have we lost some data? */ |
21713 |
++ if (idx < start) |
21714 |
++ idx = start; |
21715 |
++ |
21716 |
++ for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) { |
21717 |
++ struct _vx_mon_entry *entry = |
21718 |
++ &mon->entry[idx % VXM_SIZE]; |
21719 |
++ |
21720 |
++ /* send entry to userspace */ |
21721 |
++ ret = copy_to_user(&data[pos], entry, sizeof(*entry)); |
21722 |
++ if (ret) |
21723 |
++ break; |
21724 |
++ } |
21725 |
++ /* save new index and count */ |
21726 |
++ *index = idx; |
21727 |
++ *count = pos; |
21728 |
++ return ret ? ret : (*index < end); |
21729 |
++} |
21730 |
++ |
21731 |
++int vc_read_monitor(uint32_t id, void __user *data) |
21732 |
++{ |
21733 |
++ struct vcmd_read_monitor_v0 vc_data; |
21734 |
++ int ret; |
21735 |
++ |
21736 |
++ if (id >= NR_CPUS) |
21737 |
++ return -EINVAL; |
21738 |
++ |
21739 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
21740 |
++ return -EFAULT; |
21741 |
++ |
21742 |
++ ret = do_read_monitor((struct __user _vx_mon_entry *)vc_data.data, |
21743 |
++ id, &vc_data.index, &vc_data.count); |
21744 |
++ |
21745 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
21746 |
++ return -EFAULT; |
21747 |
++ return ret; |
21748 |
++} |
21749 |
++ |
21750 |
++#ifdef CONFIG_COMPAT |
21751 |
++ |
21752 |
++int vc_read_monitor_x32(uint32_t id, void __user *data) |
21753 |
++{ |
21754 |
++ struct vcmd_read_monitor_v0_x32 vc_data; |
21755 |
++ int ret; |
21756 |
++ |
21757 |
++ if (id >= NR_CPUS) |
21758 |
++ return -EINVAL; |
21759 |
++ |
21760 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
21761 |
++ return -EFAULT; |
21762 |
++ |
21763 |
++ ret = do_read_monitor((struct __user _vx_mon_entry *) |
21764 |
++ compat_ptr(vc_data.data_ptr), |
21765 |
++ id, &vc_data.index, &vc_data.count); |
21766 |
++ |
21767 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
21768 |
++ return -EFAULT; |
21769 |
++ return ret; |
21770 |
++} |
21771 |
++ |
21772 |
++#endif /* CONFIG_COMPAT */ |
21773 |
++ |
21774 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/network.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/network.c |
21775 |
+--- linux-2.6.29.4/kernel/vserver/network.c 1970-01-01 01:00:00.000000000 +0100 |
21776 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/network.c 2009-02-22 22:54:26.000000000 +0100 |
21777 |
+@@ -0,0 +1,864 @@ |
21778 |
++/* |
21779 |
++ * linux/kernel/vserver/network.c |
21780 |
++ * |
21781 |
++ * Virtual Server: Network Support |
21782 |
++ * |
21783 |
++ * Copyright (C) 2003-2007 Herbert Pötzl |
21784 |
++ * |
21785 |
++ * V0.01 broken out from vcontext V0.05 |
21786 |
++ * V0.02 cleaned up implementation |
21787 |
++ * V0.03 added equiv nx commands |
21788 |
++ * V0.04 switch to RCU based hash |
21789 |
++ * V0.05 and back to locking again |
21790 |
++ * V0.06 changed vcmds to nxi arg |
21791 |
++ * V0.07 have __create claim() the nxi |
21792 |
++ * |
21793 |
++ */ |
21794 |
++ |
21795 |
++#include <linux/err.h> |
21796 |
++#include <linux/slab.h> |
21797 |
++#include <linux/rcupdate.h> |
21798 |
++ |
21799 |
++#include <linux/vs_network.h> |
21800 |
++#include <linux/vs_pid.h> |
21801 |
++#include <linux/vserver/network_cmd.h> |
21802 |
++ |
21803 |
++ |
21804 |
++atomic_t nx_global_ctotal = ATOMIC_INIT(0); |
21805 |
++atomic_t nx_global_cactive = ATOMIC_INIT(0); |
21806 |
++ |
21807 |
++static struct kmem_cache *nx_addr_v4_cachep = NULL; |
21808 |
++static struct kmem_cache *nx_addr_v6_cachep = NULL; |
21809 |
++ |
21810 |
++ |
21811 |
++static int __init init_network(void) |
21812 |
++{ |
21813 |
++ nx_addr_v4_cachep = kmem_cache_create("nx_v4_addr_cache", |
21814 |
++ sizeof(struct nx_addr_v4), 0, |
21815 |
++ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); |
21816 |
++ nx_addr_v6_cachep = kmem_cache_create("nx_v6_addr_cache", |
21817 |
++ sizeof(struct nx_addr_v6), 0, |
21818 |
++ SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); |
21819 |
++ return 0; |
21820 |
++} |
21821 |
++ |
21822 |
++ |
21823 |
++/* __alloc_nx_addr_v4() */ |
21824 |
++ |
21825 |
++static inline struct nx_addr_v4 *__alloc_nx_addr_v4(void) |
21826 |
++{ |
21827 |
++ struct nx_addr_v4 *nxa = kmem_cache_alloc( |
21828 |
++ nx_addr_v4_cachep, GFP_KERNEL); |
21829 |
++ |
21830 |
++ if (!IS_ERR(nxa)) |
21831 |
++ memset(nxa, 0, sizeof(*nxa)); |
21832 |
++ return nxa; |
21833 |
++} |
21834 |
++ |
21835 |
++/* __dealloc_nx_addr_v4() */ |
21836 |
++ |
21837 |
++static inline void __dealloc_nx_addr_v4(struct nx_addr_v4 *nxa) |
21838 |
++{ |
21839 |
++ kmem_cache_free(nx_addr_v4_cachep, nxa); |
21840 |
++} |
21841 |
++ |
21842 |
++/* __dealloc_nx_addr_v4_all() */ |
21843 |
++ |
21844 |
++static inline void __dealloc_nx_addr_v4_all(struct nx_addr_v4 *nxa) |
21845 |
++{ |
21846 |
++ while (nxa) { |
21847 |
++ struct nx_addr_v4 *next = nxa->next; |
21848 |
++ |
21849 |
++ __dealloc_nx_addr_v4(nxa); |
21850 |
++ nxa = next; |
21851 |
++ } |
21852 |
++} |
21853 |
++ |
21854 |
++ |
21855 |
++#ifdef CONFIG_IPV6 |
21856 |
++ |
21857 |
++/* __alloc_nx_addr_v6() */ |
21858 |
++ |
21859 |
++static inline struct nx_addr_v6 *__alloc_nx_addr_v6(void) |
21860 |
++{ |
21861 |
++ struct nx_addr_v6 *nxa = kmem_cache_alloc( |
21862 |
++ nx_addr_v6_cachep, GFP_KERNEL); |
21863 |
++ |
21864 |
++ if (!IS_ERR(nxa)) |
21865 |
++ memset(nxa, 0, sizeof(*nxa)); |
21866 |
++ return nxa; |
21867 |
++} |
21868 |
++ |
21869 |
++/* __dealloc_nx_addr_v6() */ |
21870 |
++ |
21871 |
++static inline void __dealloc_nx_addr_v6(struct nx_addr_v6 *nxa) |
21872 |
++{ |
21873 |
++ kmem_cache_free(nx_addr_v6_cachep, nxa); |
21874 |
++} |
21875 |
++ |
21876 |
++/* __dealloc_nx_addr_v6_all() */ |
21877 |
++ |
21878 |
++static inline void __dealloc_nx_addr_v6_all(struct nx_addr_v6 *nxa) |
21879 |
++{ |
21880 |
++ while (nxa) { |
21881 |
++ struct nx_addr_v6 *next = nxa->next; |
21882 |
++ |
21883 |
++ __dealloc_nx_addr_v6(nxa); |
21884 |
++ nxa = next; |
21885 |
++ } |
21886 |
++} |
21887 |
++ |
21888 |
++#endif /* CONFIG_IPV6 */ |
21889 |
++ |
21890 |
++/* __alloc_nx_info() |
21891 |
++ |
21892 |
++ * allocate an initialized nx_info struct |
21893 |
++ * doesn't make it visible (hash) */ |
21894 |
++ |
21895 |
++static struct nx_info *__alloc_nx_info(nid_t nid) |
21896 |
++{ |
21897 |
++ struct nx_info *new = NULL; |
21898 |
++ |
21899 |
++ vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid); |
21900 |
++ |
21901 |
++ /* would this benefit from a slab cache? */ |
21902 |
++ new = kmalloc(sizeof(struct nx_info), GFP_KERNEL); |
21903 |
++ if (!new) |
21904 |
++ return 0; |
21905 |
++ |
21906 |
++ memset(new, 0, sizeof(struct nx_info)); |
21907 |
++ new->nx_id = nid; |
21908 |
++ INIT_HLIST_NODE(&new->nx_hlist); |
21909 |
++ atomic_set(&new->nx_usecnt, 0); |
21910 |
++ atomic_set(&new->nx_tasks, 0); |
21911 |
++ new->nx_state = 0; |
21912 |
++ |
21913 |
++ new->nx_flags = NXF_INIT_SET; |
21914 |
++ |
21915 |
++ /* rest of init goes here */ |
21916 |
++ |
21917 |
++ new->v4_lback.s_addr = htonl(INADDR_LOOPBACK); |
21918 |
++ new->v4_bcast.s_addr = htonl(INADDR_BROADCAST); |
21919 |
++ |
21920 |
++ vxdprintk(VXD_CBIT(nid, 0), |
21921 |
++ "alloc_nx_info(%d) = %p", nid, new); |
21922 |
++ atomic_inc(&nx_global_ctotal); |
21923 |
++ return new; |
21924 |
++} |
21925 |
++ |
21926 |
++/* __dealloc_nx_info() |
21927 |
++ |
21928 |
++ * final disposal of nx_info */ |
21929 |
++ |
21930 |
++static void __dealloc_nx_info(struct nx_info *nxi) |
21931 |
++{ |
21932 |
++ vxdprintk(VXD_CBIT(nid, 0), |
21933 |
++ "dealloc_nx_info(%p)", nxi); |
21934 |
++ |
21935 |
++ nxi->nx_hlist.next = LIST_POISON1; |
21936 |
++ nxi->nx_id = -1; |
21937 |
++ |
21938 |
++ BUG_ON(atomic_read(&nxi->nx_usecnt)); |
21939 |
++ BUG_ON(atomic_read(&nxi->nx_tasks)); |
21940 |
++ |
21941 |
++ __dealloc_nx_addr_v4_all(nxi->v4.next); |
21942 |
++ |
21943 |
++ nxi->nx_state |= NXS_RELEASED; |
21944 |
++ kfree(nxi); |
21945 |
++ atomic_dec(&nx_global_ctotal); |
21946 |
++} |
21947 |
++ |
21948 |
++static void __shutdown_nx_info(struct nx_info *nxi) |
21949 |
++{ |
21950 |
++ nxi->nx_state |= NXS_SHUTDOWN; |
21951 |
++ vs_net_change(nxi, VSC_NETDOWN); |
21952 |
++} |
21953 |
++ |
21954 |
++/* exported stuff */ |
21955 |
++ |
21956 |
++void free_nx_info(struct nx_info *nxi) |
21957 |
++{ |
21958 |
++ /* context shutdown is mandatory */ |
21959 |
++ BUG_ON(nxi->nx_state != NXS_SHUTDOWN); |
21960 |
++ |
21961 |
++ /* context must not be hashed */ |
21962 |
++ BUG_ON(nxi->nx_state & NXS_HASHED); |
21963 |
++ |
21964 |
++ BUG_ON(atomic_read(&nxi->nx_usecnt)); |
21965 |
++ BUG_ON(atomic_read(&nxi->nx_tasks)); |
21966 |
++ |
21967 |
++ __dealloc_nx_info(nxi); |
21968 |
++} |
21969 |
++ |
21970 |
++ |
21971 |
++void __nx_set_lback(struct nx_info *nxi) |
21972 |
++{ |
21973 |
++ int nid = nxi->nx_id; |
21974 |
++ __be32 lback = htonl(INADDR_LOOPBACK ^ ((nid & 0xFFFF) << 8)); |
21975 |
++ |
21976 |
++ nxi->v4_lback.s_addr = lback; |
21977 |
++} |
21978 |
++ |
21979 |
++extern int __nx_inet_add_lback(__be32 addr); |
21980 |
++extern int __nx_inet_del_lback(__be32 addr); |
21981 |
++ |
21982 |
++ |
21983 |
++/* hash table for nx_info hash */ |
21984 |
++ |
21985 |
++#define NX_HASH_SIZE 13 |
21986 |
++ |
21987 |
++struct hlist_head nx_info_hash[NX_HASH_SIZE]; |
21988 |
++ |
21989 |
++static spinlock_t nx_info_hash_lock = SPIN_LOCK_UNLOCKED; |
21990 |
++ |
21991 |
++ |
21992 |
++static inline unsigned int __hashval(nid_t nid) |
21993 |
++{ |
21994 |
++ return (nid % NX_HASH_SIZE); |
21995 |
++} |
21996 |
++ |
21997 |
++ |
21998 |
++ |
21999 |
++/* __hash_nx_info() |
22000 |
++ |
22001 |
++ * add the nxi to the global hash table |
22002 |
++ * requires the hash_lock to be held */ |
22003 |
++ |
22004 |
++static inline void __hash_nx_info(struct nx_info *nxi) |
22005 |
++{ |
22006 |
++ struct hlist_head *head; |
22007 |
++ |
22008 |
++ vxd_assert_lock(&nx_info_hash_lock); |
22009 |
++ vxdprintk(VXD_CBIT(nid, 4), |
22010 |
++ "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id); |
22011 |
++ |
22012 |
++ /* context must not be hashed */ |
22013 |
++ BUG_ON(nx_info_state(nxi, NXS_HASHED)); |
22014 |
++ |
22015 |
++ nxi->nx_state |= NXS_HASHED; |
22016 |
++ head = &nx_info_hash[__hashval(nxi->nx_id)]; |
22017 |
++ hlist_add_head(&nxi->nx_hlist, head); |
22018 |
++ atomic_inc(&nx_global_cactive); |
22019 |
++} |
22020 |
++ |
22021 |
++/* __unhash_nx_info() |
22022 |
++ |
22023 |
++ * remove the nxi from the global hash table |
22024 |
++ * requires the hash_lock to be held */ |
22025 |
++ |
22026 |
++static inline void __unhash_nx_info(struct nx_info *nxi) |
22027 |
++{ |
22028 |
++ vxd_assert_lock(&nx_info_hash_lock); |
22029 |
++ vxdprintk(VXD_CBIT(nid, 4), |
22030 |
++ "__unhash_nx_info: %p[#%d.%d.%d]", nxi, nxi->nx_id, |
22031 |
++ atomic_read(&nxi->nx_usecnt), atomic_read(&nxi->nx_tasks)); |
22032 |
++ |
22033 |
++ /* context must be hashed */ |
22034 |
++ BUG_ON(!nx_info_state(nxi, NXS_HASHED)); |
22035 |
++ /* but without tasks */ |
22036 |
++ BUG_ON(atomic_read(&nxi->nx_tasks)); |
22037 |
++ |
22038 |
++ nxi->nx_state &= ~NXS_HASHED; |
22039 |
++ hlist_del(&nxi->nx_hlist); |
22040 |
++ atomic_dec(&nx_global_cactive); |
22041 |
++} |
22042 |
++ |
22043 |
++ |
22044 |
++/* __lookup_nx_info() |
22045 |
++ |
22046 |
++ * requires the hash_lock to be held |
22047 |
++ * doesn't increment the nx_refcnt */ |
22048 |
++ |
22049 |
++static inline struct nx_info *__lookup_nx_info(nid_t nid) |
22050 |
++{ |
22051 |
++ struct hlist_head *head = &nx_info_hash[__hashval(nid)]; |
22052 |
++ struct hlist_node *pos; |
22053 |
++ struct nx_info *nxi; |
22054 |
++ |
22055 |
++ vxd_assert_lock(&nx_info_hash_lock); |
22056 |
++ hlist_for_each(pos, head) { |
22057 |
++ nxi = hlist_entry(pos, struct nx_info, nx_hlist); |
22058 |
++ |
22059 |
++ if (nxi->nx_id == nid) |
22060 |
++ goto found; |
22061 |
++ } |
22062 |
++ nxi = NULL; |
22063 |
++found: |
22064 |
++ vxdprintk(VXD_CBIT(nid, 0), |
22065 |
++ "__lookup_nx_info(#%u): %p[#%u]", |
22066 |
++ nid, nxi, nxi ? nxi->nx_id : 0); |
22067 |
++ return nxi; |
22068 |
++} |
22069 |
++ |
22070 |
++ |
22071 |
++/* __create_nx_info() |
22072 |
++ |
22073 |
++ * create the requested context |
22074 |
++ * get(), claim() and hash it */ |
22075 |
++ |
22076 |
++static struct nx_info *__create_nx_info(int id) |
22077 |
++{ |
22078 |
++ struct nx_info *new, *nxi = NULL; |
22079 |
++ |
22080 |
++ vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id); |
22081 |
++ |
22082 |
++ if (!(new = __alloc_nx_info(id))) |
22083 |
++ return ERR_PTR(-ENOMEM); |
22084 |
++ |
22085 |
++ /* required to make dynamic xids unique */ |
22086 |
++ spin_lock(&nx_info_hash_lock); |
22087 |
++ |
22088 |
++ /* static context requested */ |
22089 |
++ if ((nxi = __lookup_nx_info(id))) { |
22090 |
++ vxdprintk(VXD_CBIT(nid, 0), |
22091 |
++ "create_nx_info(%d) = %p (already there)", id, nxi); |
22092 |
++ if (nx_info_flags(nxi, NXF_STATE_SETUP, 0)) |
22093 |
++ nxi = ERR_PTR(-EBUSY); |
22094 |
++ else |
22095 |
++ nxi = ERR_PTR(-EEXIST); |
22096 |
++ goto out_unlock; |
22097 |
++ } |
22098 |
++ /* new context */ |
22099 |
++ vxdprintk(VXD_CBIT(nid, 0), |
22100 |
++ "create_nx_info(%d) = %p (new)", id, new); |
22101 |
++ claim_nx_info(new, NULL); |
22102 |
++ __nx_set_lback(new); |
22103 |
++ __hash_nx_info(get_nx_info(new)); |
22104 |
++ nxi = new, new = NULL; |
22105 |
++ |
22106 |
++out_unlock: |
22107 |
++ spin_unlock(&nx_info_hash_lock); |
22108 |
++ if (new) |
22109 |
++ __dealloc_nx_info(new); |
22110 |
++ return nxi; |
22111 |
++} |
22112 |
++ |
22113 |
++ |
22114 |
++ |
22115 |
++/* exported stuff */ |
22116 |
++ |
22117 |
++ |
22118 |
++void unhash_nx_info(struct nx_info *nxi) |
22119 |
++{ |
22120 |
++ __shutdown_nx_info(nxi); |
22121 |
++ spin_lock(&nx_info_hash_lock); |
22122 |
++ __unhash_nx_info(nxi); |
22123 |
++ spin_unlock(&nx_info_hash_lock); |
22124 |
++} |
22125 |
++ |
22126 |
++/* lookup_nx_info() |
22127 |
++ |
22128 |
++ * search for a nx_info and get() it |
22129 |
++ * negative id means current */ |
22130 |
++ |
22131 |
++struct nx_info *lookup_nx_info(int id) |
22132 |
++{ |
22133 |
++ struct nx_info *nxi = NULL; |
22134 |
++ |
22135 |
++ if (id < 0) { |
22136 |
++ nxi = get_nx_info(current->nx_info); |
22137 |
++ } else if (id > 1) { |
22138 |
++ spin_lock(&nx_info_hash_lock); |
22139 |
++ nxi = get_nx_info(__lookup_nx_info(id)); |
22140 |
++ spin_unlock(&nx_info_hash_lock); |
22141 |
++ } |
22142 |
++ return nxi; |
22143 |
++} |
22144 |
++ |
22145 |
++/* nid_is_hashed() |
22146 |
++ |
22147 |
++ * verify that nid is still hashed */ |
22148 |
++ |
22149 |
++int nid_is_hashed(nid_t nid) |
22150 |
++{ |
22151 |
++ int hashed; |
22152 |
++ |
22153 |
++ spin_lock(&nx_info_hash_lock); |
22154 |
++ hashed = (__lookup_nx_info(nid) != NULL); |
22155 |
++ spin_unlock(&nx_info_hash_lock); |
22156 |
++ return hashed; |
22157 |
++} |
22158 |
++ |
22159 |
++ |
22160 |
++#ifdef CONFIG_PROC_FS |
22161 |
++ |
22162 |
++/* get_nid_list() |
22163 |
++ |
22164 |
++ * get a subset of hashed nids for proc |
22165 |
++ * assumes size is at least one */ |
22166 |
++ |
22167 |
++int get_nid_list(int index, unsigned int *nids, int size) |
22168 |
++{ |
22169 |
++ int hindex, nr_nids = 0; |
22170 |
++ |
22171 |
++ /* only show current and children */ |
22172 |
++ if (!nx_check(0, VS_ADMIN | VS_WATCH)) { |
22173 |
++ if (index > 0) |
22174 |
++ return 0; |
22175 |
++ nids[nr_nids] = nx_current_nid(); |
22176 |
++ return 1; |
22177 |
++ } |
22178 |
++ |
22179 |
++ for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) { |
22180 |
++ struct hlist_head *head = &nx_info_hash[hindex]; |
22181 |
++ struct hlist_node *pos; |
22182 |
++ |
22183 |
++ spin_lock(&nx_info_hash_lock); |
22184 |
++ hlist_for_each(pos, head) { |
22185 |
++ struct nx_info *nxi; |
22186 |
++ |
22187 |
++ if (--index > 0) |
22188 |
++ continue; |
22189 |
++ |
22190 |
++ nxi = hlist_entry(pos, struct nx_info, nx_hlist); |
22191 |
++ nids[nr_nids] = nxi->nx_id; |
22192 |
++ if (++nr_nids >= size) { |
22193 |
++ spin_unlock(&nx_info_hash_lock); |
22194 |
++ goto out; |
22195 |
++ } |
22196 |
++ } |
22197 |
++ /* keep the lock time short */ |
22198 |
++ spin_unlock(&nx_info_hash_lock); |
22199 |
++ } |
22200 |
++out: |
22201 |
++ return nr_nids; |
22202 |
++} |
22203 |
++#endif |
22204 |
++ |
22205 |
++ |
22206 |
++/* |
22207 |
++ * migrate task to new network |
22208 |
++ * gets nxi, puts old_nxi on change |
22209 |
++ */ |
22210 |
++ |
22211 |
++int nx_migrate_task(struct task_struct *p, struct nx_info *nxi) |
22212 |
++{ |
22213 |
++ struct nx_info *old_nxi; |
22214 |
++ int ret = 0; |
22215 |
++ |
22216 |
++ if (!p || !nxi) |
22217 |
++ BUG(); |
22218 |
++ |
22219 |
++ vxdprintk(VXD_CBIT(nid, 5), |
22220 |
++ "nx_migrate_task(%p,%p[#%d.%d.%d])", |
22221 |
++ p, nxi, nxi->nx_id, |
22222 |
++ atomic_read(&nxi->nx_usecnt), |
22223 |
++ atomic_read(&nxi->nx_tasks)); |
22224 |
++ |
22225 |
++ if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) && |
22226 |
++ !nx_info_flags(nxi, NXF_STATE_SETUP, 0)) |
22227 |
++ return -EACCES; |
22228 |
++ |
22229 |
++ if (nx_info_state(nxi, NXS_SHUTDOWN)) |
22230 |
++ return -EFAULT; |
22231 |
++ |
22232 |
++ /* maybe disallow this completely? */ |
22233 |
++ old_nxi = task_get_nx_info(p); |
22234 |
++ if (old_nxi == nxi) |
22235 |
++ goto out; |
22236 |
++ |
22237 |
++ task_lock(p); |
22238 |
++ if (old_nxi) |
22239 |
++ clr_nx_info(&p->nx_info); |
22240 |
++ claim_nx_info(nxi, p); |
22241 |
++ set_nx_info(&p->nx_info, nxi); |
22242 |
++ p->nid = nxi->nx_id; |
22243 |
++ task_unlock(p); |
22244 |
++ |
22245 |
++ vxdprintk(VXD_CBIT(nid, 5), |
22246 |
++ "moved task %p into nxi:%p[#%d]", |
22247 |
++ p, nxi, nxi->nx_id); |
22248 |
++ |
22249 |
++ if (old_nxi) |
22250 |
++ release_nx_info(old_nxi, p); |
22251 |
++ ret = 0; |
22252 |
++out: |
22253 |
++ put_nx_info(old_nxi); |
22254 |
++ return ret; |
22255 |
++} |
22256 |
++ |
22257 |
++ |
22258 |
++void nx_set_persistent(struct nx_info *nxi) |
22259 |
++{ |
22260 |
++ vxdprintk(VXD_CBIT(nid, 6), |
22261 |
++ "nx_set_persistent(%p[#%d])", nxi, nxi->nx_id); |
22262 |
++ |
22263 |
++ get_nx_info(nxi); |
22264 |
++ claim_nx_info(nxi, NULL); |
22265 |
++} |
22266 |
++ |
22267 |
++void nx_clear_persistent(struct nx_info *nxi) |
22268 |
++{ |
22269 |
++ vxdprintk(VXD_CBIT(nid, 6), |
22270 |
++ "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id); |
22271 |
++ |
22272 |
++ release_nx_info(nxi, NULL); |
22273 |
++ put_nx_info(nxi); |
22274 |
++} |
22275 |
++ |
22276 |
++void nx_update_persistent(struct nx_info *nxi) |
22277 |
++{ |
22278 |
++ if (nx_info_flags(nxi, NXF_PERSISTENT, 0)) |
22279 |
++ nx_set_persistent(nxi); |
22280 |
++ else |
22281 |
++ nx_clear_persistent(nxi); |
22282 |
++} |
22283 |
++ |
22284 |
++/* vserver syscall commands below here */ |
22285 |
++ |
22286 |
++/* taks nid and nx_info functions */ |
22287 |
++ |
22288 |
++#include <asm/uaccess.h> |
22289 |
++ |
22290 |
++ |
22291 |
++int vc_task_nid(uint32_t id) |
22292 |
++{ |
22293 |
++ nid_t nid; |
22294 |
++ |
22295 |
++ if (id) { |
22296 |
++ struct task_struct *tsk; |
22297 |
++ |
22298 |
++ read_lock(&tasklist_lock); |
22299 |
++ tsk = find_task_by_real_pid(id); |
22300 |
++ nid = (tsk) ? tsk->nid : -ESRCH; |
22301 |
++ read_unlock(&tasklist_lock); |
22302 |
++ } else |
22303 |
++ nid = nx_current_nid(); |
22304 |
++ return nid; |
22305 |
++} |
22306 |
++ |
22307 |
++ |
22308 |
++int vc_nx_info(struct nx_info *nxi, void __user *data) |
22309 |
++{ |
22310 |
++ struct vcmd_nx_info_v0 vc_data; |
22311 |
++ |
22312 |
++ vc_data.nid = nxi->nx_id; |
22313 |
++ |
22314 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
22315 |
++ return -EFAULT; |
22316 |
++ return 0; |
22317 |
++} |
22318 |
++ |
22319 |
++ |
22320 |
++/* network functions */ |
22321 |
++ |
22322 |
++int vc_net_create(uint32_t nid, void __user *data) |
22323 |
++{ |
22324 |
++ struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET }; |
22325 |
++ struct nx_info *new_nxi; |
22326 |
++ int ret; |
22327 |
++ |
22328 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
22329 |
++ return -EFAULT; |
22330 |
++ |
22331 |
++ if ((nid > MAX_S_CONTEXT) || (nid < 2)) |
22332 |
++ return -EINVAL; |
22333 |
++ |
22334 |
++ new_nxi = __create_nx_info(nid); |
22335 |
++ if (IS_ERR(new_nxi)) |
22336 |
++ return PTR_ERR(new_nxi); |
22337 |
++ |
22338 |
++ /* initial flags */ |
22339 |
++ new_nxi->nx_flags = vc_data.flagword; |
22340 |
++ |
22341 |
++ ret = -ENOEXEC; |
22342 |
++ if (vs_net_change(new_nxi, VSC_NETUP)) |
22343 |
++ goto out; |
22344 |
++ |
22345 |
++ ret = nx_migrate_task(current, new_nxi); |
22346 |
++ if (ret) |
22347 |
++ goto out; |
22348 |
++ |
22349 |
++ /* return context id on success */ |
22350 |
++ ret = new_nxi->nx_id; |
22351 |
++ |
22352 |
++ /* get a reference for persistent contexts */ |
22353 |
++ if ((vc_data.flagword & NXF_PERSISTENT)) |
22354 |
++ nx_set_persistent(new_nxi); |
22355 |
++out: |
22356 |
++ release_nx_info(new_nxi, NULL); |
22357 |
++ put_nx_info(new_nxi); |
22358 |
++ return ret; |
22359 |
++} |
22360 |
++ |
22361 |
++ |
22362 |
++int vc_net_migrate(struct nx_info *nxi, void __user *data) |
22363 |
++{ |
22364 |
++ return nx_migrate_task(current, nxi); |
22365 |
++} |
22366 |
++ |
22367 |
++ |
22368 |
++ |
22369 |
++int do_add_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask, |
22370 |
++ uint16_t type, uint16_t flags) |
22371 |
++{ |
22372 |
++ struct nx_addr_v4 *nxa = &nxi->v4; |
22373 |
++ |
22374 |
++ if (NX_IPV4(nxi)) { |
22375 |
++ /* locate last entry */ |
22376 |
++ for (; nxa->next; nxa = nxa->next); |
22377 |
++ nxa->next = __alloc_nx_addr_v4(); |
22378 |
++ nxa = nxa->next; |
22379 |
++ |
22380 |
++ if (IS_ERR(nxa)) |
22381 |
++ return PTR_ERR(nxa); |
22382 |
++ } |
22383 |
++ |
22384 |
++ if (nxi->v4.next) |
22385 |
++ /* remove single ip for ip list */ |
22386 |
++ nxi->nx_flags &= ~NXF_SINGLE_IP; |
22387 |
++ |
22388 |
++ nxa->ip[0].s_addr = ip; |
22389 |
++ nxa->ip[1].s_addr = ip2; |
22390 |
++ nxa->mask.s_addr = mask; |
22391 |
++ nxa->type = type; |
22392 |
++ nxa->flags = flags; |
22393 |
++ return 0; |
22394 |
++} |
22395 |
++ |
22396 |
++ |
22397 |
++int vc_net_add(struct nx_info *nxi, void __user *data) |
22398 |
++{ |
22399 |
++ struct vcmd_net_addr_v0 vc_data; |
22400 |
++ int index, ret = 0; |
22401 |
++ |
22402 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
22403 |
++ return -EFAULT; |
22404 |
++ |
22405 |
++ switch (vc_data.type) { |
22406 |
++ case NXA_TYPE_IPV4: |
22407 |
++ if ((vc_data.count < 1) || (vc_data.count > 4)) |
22408 |
++ return -EINVAL; |
22409 |
++ |
22410 |
++ index = 0; |
22411 |
++ while (index < vc_data.count) { |
22412 |
++ ret = do_add_v4_addr(nxi, vc_data.ip[index].s_addr, 0, |
22413 |
++ vc_data.mask[index].s_addr, NXA_TYPE_ADDR, 0); |
22414 |
++ if (ret) |
22415 |
++ return ret; |
22416 |
++ index++; |
22417 |
++ } |
22418 |
++ ret = index; |
22419 |
++ break; |
22420 |
++ |
22421 |
++ case NXA_TYPE_IPV4|NXA_MOD_BCAST: |
22422 |
++ nxi->v4_bcast = vc_data.ip[0]; |
22423 |
++ ret = 1; |
22424 |
++ break; |
22425 |
++ |
22426 |
++ case NXA_TYPE_IPV4|NXA_MOD_LBACK: |
22427 |
++ nxi->v4_lback = vc_data.ip[0]; |
22428 |
++ ret = 1; |
22429 |
++ break; |
22430 |
++ |
22431 |
++ default: |
22432 |
++ ret = -EINVAL; |
22433 |
++ break; |
22434 |
++ } |
22435 |
++ return ret; |
22436 |
++} |
22437 |
++ |
22438 |
++int vc_net_remove(struct nx_info *nxi, void __user *data) |
22439 |
++{ |
22440 |
++ struct vcmd_net_addr_v0 vc_data; |
22441 |
++ |
22442 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
22443 |
++ return -EFAULT; |
22444 |
++ |
22445 |
++ switch (vc_data.type) { |
22446 |
++ case NXA_TYPE_ANY: |
22447 |
++ __dealloc_nx_addr_v4_all(xchg(&nxi->v4.next, NULL)); |
22448 |
++ memset(&nxi->v4, 0, sizeof(nxi->v4)); |
22449 |
++ break; |
22450 |
++ |
22451 |
++ default: |
22452 |
++ return -EINVAL; |
22453 |
++ } |
22454 |
++ return 0; |
22455 |
++} |
22456 |
++ |
22457 |
++ |
22458 |
++int vc_net_add_ipv4(struct nx_info *nxi, void __user *data) |
22459 |
++{ |
22460 |
++ struct vcmd_net_addr_ipv4_v1 vc_data; |
22461 |
++ |
22462 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
22463 |
++ return -EFAULT; |
22464 |
++ |
22465 |
++ switch (vc_data.type) { |
22466 |
++ case NXA_TYPE_ADDR: |
22467 |
++ case NXA_TYPE_RANGE: |
22468 |
++ case NXA_TYPE_MASK: |
22469 |
++ return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0, |
22470 |
++ vc_data.mask.s_addr, vc_data.type, vc_data.flags); |
22471 |
++ |
22472 |
++ case NXA_TYPE_ADDR | NXA_MOD_BCAST: |
22473 |
++ nxi->v4_bcast = vc_data.ip; |
22474 |
++ break; |
22475 |
++ |
22476 |
++ case NXA_TYPE_ADDR | NXA_MOD_LBACK: |
22477 |
++ nxi->v4_lback = vc_data.ip; |
22478 |
++ break; |
22479 |
++ |
22480 |
++ default: |
22481 |
++ return -EINVAL; |
22482 |
++ } |
22483 |
++ return 0; |
22484 |
++} |
22485 |
++ |
22486 |
++int vc_net_remove_ipv4(struct nx_info *nxi, void __user *data) |
22487 |
++{ |
22488 |
++ struct vcmd_net_addr_ipv4_v1 vc_data; |
22489 |
++ |
22490 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
22491 |
++ return -EFAULT; |
22492 |
++ |
22493 |
++ switch (vc_data.type) { |
22494 |
++/* case NXA_TYPE_ADDR: |
22495 |
++ break; */ |
22496 |
++ |
22497 |
++ case NXA_TYPE_ANY: |
22498 |
++ __dealloc_nx_addr_v4_all(xchg(&nxi->v4.next, NULL)); |
22499 |
++ memset(&nxi->v4, 0, sizeof(nxi->v4)); |
22500 |
++ break; |
22501 |
++ |
22502 |
++ default: |
22503 |
++ return -EINVAL; |
22504 |
++ } |
22505 |
++ return 0; |
22506 |
++} |
22507 |
++ |
22508 |
++ |
22509 |
++#ifdef CONFIG_IPV6 |
22510 |
++ |
22511 |
++int do_add_v6_addr(struct nx_info *nxi, |
22512 |
++ struct in6_addr *ip, struct in6_addr *mask, |
22513 |
++ uint32_t prefix, uint16_t type, uint16_t flags) |
22514 |
++{ |
22515 |
++ struct nx_addr_v6 *nxa = &nxi->v6; |
22516 |
++ |
22517 |
++ if (NX_IPV6(nxi)) { |
22518 |
++ /* locate last entry */ |
22519 |
++ for (; nxa->next; nxa = nxa->next); |
22520 |
++ nxa->next = __alloc_nx_addr_v6(); |
22521 |
++ nxa = nxa->next; |
22522 |
++ |
22523 |
++ if (IS_ERR(nxa)) |
22524 |
++ return PTR_ERR(nxa); |
22525 |
++ } |
22526 |
++ |
22527 |
++ nxa->ip = *ip; |
22528 |
++ nxa->mask = *mask; |
22529 |
++ nxa->prefix = prefix; |
22530 |
++ nxa->type = type; |
22531 |
++ nxa->flags = flags; |
22532 |
++ return 0; |
22533 |
++} |
22534 |
++ |
22535 |
++ |
22536 |
++int vc_net_add_ipv6(struct nx_info *nxi, void __user *data) |
22537 |
++{ |
22538 |
++ struct vcmd_net_addr_ipv6_v1 vc_data; |
22539 |
++ |
22540 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
22541 |
++ return -EFAULT; |
22542 |
++ |
22543 |
++ switch (vc_data.type) { |
22544 |
++ case NXA_TYPE_ADDR: |
22545 |
++ case NXA_TYPE_MASK: |
22546 |
++ return do_add_v6_addr(nxi, &vc_data.ip, &vc_data.mask, |
22547 |
++ vc_data.prefix, vc_data.type, vc_data.flags); |
22548 |
++ default: |
22549 |
++ return -EINVAL; |
22550 |
++ } |
22551 |
++ return 0; |
22552 |
++} |
22553 |
++ |
22554 |
++int vc_net_remove_ipv6(struct nx_info *nxi, void __user *data) |
22555 |
++{ |
22556 |
++ struct vcmd_net_addr_ipv6_v1 vc_data; |
22557 |
++ |
22558 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
22559 |
++ return -EFAULT; |
22560 |
++ |
22561 |
++ switch (vc_data.type) { |
22562 |
++ case NXA_TYPE_ANY: |
22563 |
++ __dealloc_nx_addr_v6_all(xchg(&nxi->v6.next, NULL)); |
22564 |
++ memset(&nxi->v6, 0, sizeof(nxi->v6)); |
22565 |
++ break; |
22566 |
++ |
22567 |
++ default: |
22568 |
++ return -EINVAL; |
22569 |
++ } |
22570 |
++ return 0; |
22571 |
++} |
22572 |
++ |
22573 |
++#endif /* CONFIG_IPV6 */ |
22574 |
++ |
22575 |
++ |
22576 |
++int vc_get_nflags(struct nx_info *nxi, void __user *data) |
22577 |
++{ |
22578 |
++ struct vcmd_net_flags_v0 vc_data; |
22579 |
++ |
22580 |
++ vc_data.flagword = nxi->nx_flags; |
22581 |
++ |
22582 |
++ /* special STATE flag handling */ |
22583 |
++ vc_data.mask = vs_mask_flags(~0ULL, nxi->nx_flags, NXF_ONE_TIME); |
22584 |
++ |
22585 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
22586 |
++ return -EFAULT; |
22587 |
++ return 0; |
22588 |
++} |
22589 |
++ |
22590 |
++int vc_set_nflags(struct nx_info *nxi, void __user *data) |
22591 |
++{ |
22592 |
++ struct vcmd_net_flags_v0 vc_data; |
22593 |
++ uint64_t mask, trigger; |
22594 |
++ |
22595 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
22596 |
++ return -EFAULT; |
22597 |
++ |
22598 |
++ /* special STATE flag handling */ |
22599 |
++ mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME); |
22600 |
++ trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword); |
22601 |
++ |
22602 |
++ nxi->nx_flags = vs_mask_flags(nxi->nx_flags, |
22603 |
++ vc_data.flagword, mask); |
22604 |
++ if (trigger & NXF_PERSISTENT) |
22605 |
++ nx_update_persistent(nxi); |
22606 |
++ |
22607 |
++ return 0; |
22608 |
++} |
22609 |
++ |
22610 |
++int vc_get_ncaps(struct nx_info *nxi, void __user *data) |
22611 |
++{ |
22612 |
++ struct vcmd_net_caps_v0 vc_data; |
22613 |
++ |
22614 |
++ vc_data.ncaps = nxi->nx_ncaps; |
22615 |
++ vc_data.cmask = ~0ULL; |
22616 |
++ |
22617 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
22618 |
++ return -EFAULT; |
22619 |
++ return 0; |
22620 |
++} |
22621 |
++ |
22622 |
++int vc_set_ncaps(struct nx_info *nxi, void __user *data) |
22623 |
++{ |
22624 |
++ struct vcmd_net_caps_v0 vc_data; |
22625 |
++ |
22626 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
22627 |
++ return -EFAULT; |
22628 |
++ |
22629 |
++ nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps, |
22630 |
++ vc_data.ncaps, vc_data.cmask); |
22631 |
++ return 0; |
22632 |
++} |
22633 |
++ |
22634 |
++ |
22635 |
++#include <linux/module.h> |
22636 |
++ |
22637 |
++module_init(init_network); |
22638 |
++ |
22639 |
++EXPORT_SYMBOL_GPL(free_nx_info); |
22640 |
++EXPORT_SYMBOL_GPL(unhash_nx_info); |
22641 |
++ |
22642 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/proc.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/proc.c |
22643 |
+--- linux-2.6.29.4/kernel/vserver/proc.c 1970-01-01 01:00:00.000000000 +0100 |
22644 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/proc.c 2009-05-23 22:57:16.000000000 +0200 |
22645 |
+@@ -0,0 +1,1096 @@ |
22646 |
++/* |
22647 |
++ * linux/kernel/vserver/proc.c |
22648 |
++ * |
22649 |
++ * Virtual Context Support |
22650 |
++ * |
22651 |
++ * Copyright (C) 2003-2007 Herbert Pötzl |
22652 |
++ * |
22653 |
++ * V0.01 basic structure |
22654 |
++ * V0.02 adaptation vs1.3.0 |
22655 |
++ * V0.03 proc permissions |
22656 |
++ * V0.04 locking/generic |
22657 |
++ * V0.05 next generation procfs |
22658 |
++ * V0.06 inode validation |
22659 |
++ * V0.07 generic rewrite vid |
22660 |
++ * V0.08 remove inode type |
22661 |
++ * |
22662 |
++ */ |
22663 |
++ |
22664 |
++#include <linux/proc_fs.h> |
22665 |
++#include <asm/unistd.h> |
22666 |
++ |
22667 |
++#include <linux/vs_context.h> |
22668 |
++#include <linux/vs_network.h> |
22669 |
++#include <linux/vs_cvirt.h> |
22670 |
++ |
22671 |
++#include <linux/in.h> |
22672 |
++#include <linux/inetdevice.h> |
22673 |
++#include <linux/vs_inet.h> |
22674 |
++#include <linux/vs_inet6.h> |
22675 |
++ |
22676 |
++#include <linux/vserver/global.h> |
22677 |
++ |
22678 |
++#include "cvirt_proc.h" |
22679 |
++#include "cacct_proc.h" |
22680 |
++#include "limit_proc.h" |
22681 |
++#include "sched_proc.h" |
22682 |
++#include "vci_config.h" |
22683 |
++ |
22684 |
++ |
22685 |
++static inline char *print_cap_t(char *buffer, kernel_cap_t *c) |
22686 |
++{ |
22687 |
++ unsigned __capi; |
22688 |
++ |
22689 |
++ CAP_FOR_EACH_U32(__capi) { |
22690 |
++ buffer += sprintf(buffer, "%08x", |
22691 |
++ c->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]); |
22692 |
++ } |
22693 |
++ return buffer; |
22694 |
++} |
22695 |
++ |
22696 |
++ |
22697 |
++static struct proc_dir_entry *proc_virtual; |
22698 |
++ |
22699 |
++static struct proc_dir_entry *proc_virtnet; |
22700 |
++ |
22701 |
++ |
22702 |
++/* first the actual feeds */ |
22703 |
++ |
22704 |
++ |
22705 |
++static int proc_vci(char *buffer) |
22706 |
++{ |
22707 |
++ return sprintf(buffer, |
22708 |
++ "VCIVersion:\t%04x:%04x\n" |
22709 |
++ "VCISyscall:\t%d\n" |
22710 |
++ "VCIKernel:\t%08x\n", |
22711 |
++ VCI_VERSION >> 16, |
22712 |
++ VCI_VERSION & 0xFFFF, |
22713 |
++ __NR_vserver, |
22714 |
++ vci_kernel_config()); |
22715 |
++} |
22716 |
++ |
22717 |
++static int proc_virtual_info(char *buffer) |
22718 |
++{ |
22719 |
++ return proc_vci(buffer); |
22720 |
++} |
22721 |
++ |
22722 |
++static int proc_virtual_status(char *buffer) |
22723 |
++{ |
22724 |
++ return sprintf(buffer, |
22725 |
++ "#CTotal:\t%d\n" |
22726 |
++ "#CActive:\t%d\n" |
22727 |
++ "#NSProxy:\t%d\t%d %d %d %d %d %d\n" |
22728 |
++ "#InitTask:\t%d\t%d %d\n", |
22729 |
++ atomic_read(&vx_global_ctotal), |
22730 |
++ atomic_read(&vx_global_cactive), |
22731 |
++ atomic_read(&vs_global_nsproxy), |
22732 |
++ atomic_read(&vs_global_fs), |
22733 |
++ atomic_read(&vs_global_mnt_ns), |
22734 |
++ atomic_read(&vs_global_uts_ns), |
22735 |
++ atomic_read(&vs_global_ipc_ns), |
22736 |
++ atomic_read(&vs_global_user_ns), |
22737 |
++ atomic_read(&vs_global_pid_ns), |
22738 |
++ atomic_read(&init_task.usage), |
22739 |
++ atomic_read(&init_task.nsproxy->count), |
22740 |
++ init_task.fs->users); |
22741 |
++} |
22742 |
++ |
22743 |
++ |
22744 |
++int proc_vxi_info(struct vx_info *vxi, char *buffer) |
22745 |
++{ |
22746 |
++ int length; |
22747 |
++ |
22748 |
++ length = sprintf(buffer, |
22749 |
++ "ID:\t%d\n" |
22750 |
++ "Info:\t%p\n" |
22751 |
++ "Init:\t%d\n" |
22752 |
++ "OOM:\t%lld\n", |
22753 |
++ vxi->vx_id, |
22754 |
++ vxi, |
22755 |
++ vxi->vx_initpid, |
22756 |
++ vxi->vx_badness_bias); |
22757 |
++ return length; |
22758 |
++} |
22759 |
++ |
22760 |
++int proc_vxi_status(struct vx_info *vxi, char *buffer) |
22761 |
++{ |
22762 |
++ char *orig = buffer; |
22763 |
++ |
22764 |
++ buffer += sprintf(buffer, |
22765 |
++ "UseCnt:\t%d\n" |
22766 |
++ "Tasks:\t%d\n" |
22767 |
++ "Flags:\t%016llx\n", |
22768 |
++ atomic_read(&vxi->vx_usecnt), |
22769 |
++ atomic_read(&vxi->vx_tasks), |
22770 |
++ (unsigned long long)vxi->vx_flags); |
22771 |
++ |
22772 |
++ buffer += sprintf(buffer, "BCaps:\t"); |
22773 |
++ buffer = print_cap_t(buffer, &vxi->vx_bcaps); |
22774 |
++ buffer += sprintf(buffer, "\n"); |
22775 |
++ |
22776 |
++ buffer += sprintf(buffer, |
22777 |
++ "CCaps:\t%016llx\n" |
22778 |
++ "Spaces:\t%08lx %08lx\n", |
22779 |
++ (unsigned long long)vxi->vx_ccaps, |
22780 |
++ vxi->vx_nsmask[0], vxi->vx_nsmask[1]); |
22781 |
++ return buffer - orig; |
22782 |
++} |
22783 |
++ |
22784 |
++int proc_vxi_limit(struct vx_info *vxi, char *buffer) |
22785 |
++{ |
22786 |
++ return vx_info_proc_limit(&vxi->limit, buffer); |
22787 |
++} |
22788 |
++ |
22789 |
++int proc_vxi_sched(struct vx_info *vxi, char *buffer) |
22790 |
++{ |
22791 |
++ int cpu, length; |
22792 |
++ |
22793 |
++ length = vx_info_proc_sched(&vxi->sched, buffer); |
22794 |
++ for_each_online_cpu(cpu) { |
22795 |
++ length += vx_info_proc_sched_pc( |
22796 |
++ &vx_per_cpu(vxi, sched_pc, cpu), |
22797 |
++ buffer + length, cpu); |
22798 |
++ } |
22799 |
++ return length; |
22800 |
++} |
22801 |
++ |
22802 |
++int proc_vxi_nsproxy0(struct vx_info *vxi, char *buffer) |
22803 |
++{ |
22804 |
++ return vx_info_proc_nsproxy(vxi->vx_nsproxy[0], buffer); |
22805 |
++} |
22806 |
++ |
22807 |
++int proc_vxi_nsproxy1(struct vx_info *vxi, char *buffer) |
22808 |
++{ |
22809 |
++ return vx_info_proc_nsproxy(vxi->vx_nsproxy[1], buffer); |
22810 |
++} |
22811 |
++ |
22812 |
++int proc_vxi_cvirt(struct vx_info *vxi, char *buffer) |
22813 |
++{ |
22814 |
++ int cpu, length; |
22815 |
++ |
22816 |
++ vx_update_load(vxi); |
22817 |
++ length = vx_info_proc_cvirt(&vxi->cvirt, buffer); |
22818 |
++ for_each_online_cpu(cpu) { |
22819 |
++ length += vx_info_proc_cvirt_pc( |
22820 |
++ &vx_per_cpu(vxi, cvirt_pc, cpu), |
22821 |
++ buffer + length, cpu); |
22822 |
++ } |
22823 |
++ return length; |
22824 |
++} |
22825 |
++ |
22826 |
++int proc_vxi_cacct(struct vx_info *vxi, char *buffer) |
22827 |
++{ |
22828 |
++ return vx_info_proc_cacct(&vxi->cacct, buffer); |
22829 |
++} |
22830 |
++ |
22831 |
++ |
22832 |
++static int proc_virtnet_info(char *buffer) |
22833 |
++{ |
22834 |
++ return proc_vci(buffer); |
22835 |
++} |
22836 |
++ |
22837 |
++static int proc_virtnet_status(char *buffer) |
22838 |
++{ |
22839 |
++ return sprintf(buffer, |
22840 |
++ "#CTotal:\t%d\n" |
22841 |
++ "#CActive:\t%d\n", |
22842 |
++ atomic_read(&nx_global_ctotal), |
22843 |
++ atomic_read(&nx_global_cactive)); |
22844 |
++} |
22845 |
++ |
22846 |
++int proc_nxi_info(struct nx_info *nxi, char *buffer) |
22847 |
++{ |
22848 |
++ struct nx_addr_v4 *v4a; |
22849 |
++#ifdef CONFIG_IPV6 |
22850 |
++ struct nx_addr_v6 *v6a; |
22851 |
++#endif |
22852 |
++ int length, i; |
22853 |
++ |
22854 |
++ length = sprintf(buffer, |
22855 |
++ "ID:\t%d\n" |
22856 |
++ "Info:\t%p\n" |
22857 |
++ "Bcast:\t" NIPQUAD_FMT "\n" |
22858 |
++ "Lback:\t" NIPQUAD_FMT "\n", |
22859 |
++ nxi->nx_id, |
22860 |
++ nxi, |
22861 |
++ NIPQUAD(nxi->v4_bcast.s_addr), |
22862 |
++ NIPQUAD(nxi->v4_lback.s_addr)); |
22863 |
++ |
22864 |
++ if (!NX_IPV4(nxi)) |
22865 |
++ goto skip_v4; |
22866 |
++ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next) |
22867 |
++ length += sprintf(buffer + length, "%d:\t" NXAV4_FMT "\n", |
22868 |
++ i, NXAV4(v4a)); |
22869 |
++skip_v4: |
22870 |
++#ifdef CONFIG_IPV6 |
22871 |
++ if (!NX_IPV6(nxi)) |
22872 |
++ goto skip_v6; |
22873 |
++ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next) |
22874 |
++ length += sprintf(buffer + length, "%d:\t" NXAV6_FMT "\n", |
22875 |
++ i, NXAV6(v6a)); |
22876 |
++skip_v6: |
22877 |
++#endif |
22878 |
++ return length; |
22879 |
++} |
22880 |
++ |
22881 |
++int proc_nxi_status(struct nx_info *nxi, char *buffer) |
22882 |
++{ |
22883 |
++ int length; |
22884 |
++ |
22885 |
++ length = sprintf(buffer, |
22886 |
++ "UseCnt:\t%d\n" |
22887 |
++ "Tasks:\t%d\n" |
22888 |
++ "Flags:\t%016llx\n" |
22889 |
++ "NCaps:\t%016llx\n", |
22890 |
++ atomic_read(&nxi->nx_usecnt), |
22891 |
++ atomic_read(&nxi->nx_tasks), |
22892 |
++ (unsigned long long)nxi->nx_flags, |
22893 |
++ (unsigned long long)nxi->nx_ncaps); |
22894 |
++ return length; |
22895 |
++} |
22896 |
++ |
22897 |
++ |
22898 |
++ |
22899 |
++/* here the inode helpers */ |
22900 |
++ |
22901 |
++struct vs_entry { |
22902 |
++ int len; |
22903 |
++ char *name; |
22904 |
++ mode_t mode; |
22905 |
++ struct inode_operations *iop; |
22906 |
++ struct file_operations *fop; |
22907 |
++ union proc_op op; |
22908 |
++}; |
22909 |
++ |
22910 |
++static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p) |
22911 |
++{ |
22912 |
++ struct inode *inode = new_inode(sb); |
22913 |
++ |
22914 |
++ if (!inode) |
22915 |
++ goto out; |
22916 |
++ |
22917 |
++ inode->i_mode = p->mode; |
22918 |
++ if (p->iop) |
22919 |
++ inode->i_op = p->iop; |
22920 |
++ if (p->fop) |
22921 |
++ inode->i_fop = p->fop; |
22922 |
++ |
22923 |
++ inode->i_nlink = (p->mode & S_IFDIR) ? 2 : 1; |
22924 |
++ inode->i_flags |= S_IMMUTABLE; |
22925 |
++ |
22926 |
++ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
22927 |
++ |
22928 |
++ inode->i_uid = 0; |
22929 |
++ inode->i_gid = 0; |
22930 |
++ inode->i_tag = 0; |
22931 |
++out: |
22932 |
++ return inode; |
22933 |
++} |
22934 |
++ |
22935 |
++static struct dentry *vs_proc_instantiate(struct inode *dir, |
22936 |
++ struct dentry *dentry, int id, void *ptr) |
22937 |
++{ |
22938 |
++ struct vs_entry *p = ptr; |
22939 |
++ struct inode *inode = vs_proc_make_inode(dir->i_sb, p); |
22940 |
++ struct dentry *error = ERR_PTR(-EINVAL); |
22941 |
++ |
22942 |
++ if (!inode) |
22943 |
++ goto out; |
22944 |
++ |
22945 |
++ PROC_I(inode)->op = p->op; |
22946 |
++ PROC_I(inode)->fd = id; |
22947 |
++ d_add(dentry, inode); |
22948 |
++ error = NULL; |
22949 |
++out: |
22950 |
++ return error; |
22951 |
++} |
22952 |
++ |
22953 |
++/* Lookups */ |
22954 |
++ |
22955 |
++typedef struct dentry *instantiate_t(struct inode *, struct dentry *, int, void *); |
22956 |
++ |
22957 |
++/* |
22958 |
++ * Fill a directory entry. |
22959 |
++ * |
22960 |
++ * If possible create the dcache entry and derive our inode number and |
22961 |
++ * file type from dcache entry. |
22962 |
++ * |
22963 |
++ * Since all of the proc inode numbers are dynamically generated, the inode |
22964 |
++ * numbers do not exist until the inode is cache. This means creating the |
22965 |
++ * the dcache entry in readdir is necessary to keep the inode numbers |
22966 |
++ * reported by readdir in sync with the inode numbers reported |
22967 |
++ * by stat. |
22968 |
++ */ |
22969 |
++static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir, |
22970 |
++ char *name, int len, instantiate_t instantiate, int id, void *ptr) |
22971 |
++{ |
22972 |
++ struct dentry *child, *dir = filp->f_dentry; |
22973 |
++ struct inode *inode; |
22974 |
++ struct qstr qname; |
22975 |
++ ino_t ino = 0; |
22976 |
++ unsigned type = DT_UNKNOWN; |
22977 |
++ |
22978 |
++ qname.name = name; |
22979 |
++ qname.len = len; |
22980 |
++ qname.hash = full_name_hash(name, len); |
22981 |
++ |
22982 |
++ child = d_lookup(dir, &qname); |
22983 |
++ if (!child) { |
22984 |
++ struct dentry *new; |
22985 |
++ new = d_alloc(dir, &qname); |
22986 |
++ if (new) { |
22987 |
++ child = instantiate(dir->d_inode, new, id, ptr); |
22988 |
++ if (child) |
22989 |
++ dput(new); |
22990 |
++ else |
22991 |
++ child = new; |
22992 |
++ } |
22993 |
++ } |
22994 |
++ if (!child || IS_ERR(child) || !child->d_inode) |
22995 |
++ goto end_instantiate; |
22996 |
++ inode = child->d_inode; |
22997 |
++ if (inode) { |
22998 |
++ ino = inode->i_ino; |
22999 |
++ type = inode->i_mode >> 12; |
23000 |
++ } |
23001 |
++ dput(child); |
23002 |
++end_instantiate: |
23003 |
++ if (!ino) |
23004 |
++ ino = find_inode_number(dir, &qname); |
23005 |
++ if (!ino) |
23006 |
++ ino = 1; |
23007 |
++ return filldir(dirent, name, len, filp->f_pos, ino, type); |
23008 |
++} |
23009 |
++ |
23010 |
++ |
23011 |
++ |
23012 |
++/* get and revalidate vx_info/xid */ |
23013 |
++ |
23014 |
++static inline |
23015 |
++struct vx_info *get_proc_vx_info(struct inode *inode) |
23016 |
++{ |
23017 |
++ return lookup_vx_info(PROC_I(inode)->fd); |
23018 |
++} |
23019 |
++ |
23020 |
++static int proc_xid_revalidate(struct dentry *dentry, struct nameidata *nd) |
23021 |
++{ |
23022 |
++ struct inode *inode = dentry->d_inode; |
23023 |
++ xid_t xid = PROC_I(inode)->fd; |
23024 |
++ |
23025 |
++ if (!xid || xid_is_hashed(xid)) |
23026 |
++ return 1; |
23027 |
++ d_drop(dentry); |
23028 |
++ return 0; |
23029 |
++} |
23030 |
++ |
23031 |
++ |
23032 |
++/* get and revalidate nx_info/nid */ |
23033 |
++ |
23034 |
++static int proc_nid_revalidate(struct dentry *dentry, struct nameidata *nd) |
23035 |
++{ |
23036 |
++ struct inode *inode = dentry->d_inode; |
23037 |
++ nid_t nid = PROC_I(inode)->fd; |
23038 |
++ |
23039 |
++ if (!nid || nid_is_hashed(nid)) |
23040 |
++ return 1; |
23041 |
++ d_drop(dentry); |
23042 |
++ return 0; |
23043 |
++} |
23044 |
++ |
23045 |
++ |
23046 |
++ |
23047 |
++#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024) |
23048 |
++ |
23049 |
++static ssize_t proc_vs_info_read(struct file *file, char __user *buf, |
23050 |
++ size_t count, loff_t *ppos) |
23051 |
++{ |
23052 |
++ struct inode *inode = file->f_dentry->d_inode; |
23053 |
++ unsigned long page; |
23054 |
++ ssize_t length = 0; |
23055 |
++ |
23056 |
++ if (count > PROC_BLOCK_SIZE) |
23057 |
++ count = PROC_BLOCK_SIZE; |
23058 |
++ |
23059 |
++ /* fade that out as soon as stable */ |
23060 |
++ WARN_ON(PROC_I(inode)->fd); |
23061 |
++ |
23062 |
++ if (!(page = __get_free_page(GFP_KERNEL))) |
23063 |
++ return -ENOMEM; |
23064 |
++ |
23065 |
++ BUG_ON(!PROC_I(inode)->op.proc_vs_read); |
23066 |
++ length = PROC_I(inode)->op.proc_vs_read((char *)page); |
23067 |
++ |
23068 |
++ if (length >= 0) |
23069 |
++ length = simple_read_from_buffer(buf, count, ppos, |
23070 |
++ (char *)page, length); |
23071 |
++ |
23072 |
++ free_page(page); |
23073 |
++ return length; |
23074 |
++} |
23075 |
++ |
23076 |
++static ssize_t proc_vx_info_read(struct file *file, char __user *buf, |
23077 |
++ size_t count, loff_t *ppos) |
23078 |
++{ |
23079 |
++ struct inode *inode = file->f_dentry->d_inode; |
23080 |
++ struct vx_info *vxi = NULL; |
23081 |
++ xid_t xid = PROC_I(inode)->fd; |
23082 |
++ unsigned long page; |
23083 |
++ ssize_t length = 0; |
23084 |
++ |
23085 |
++ if (count > PROC_BLOCK_SIZE) |
23086 |
++ count = PROC_BLOCK_SIZE; |
23087 |
++ |
23088 |
++ /* fade that out as soon as stable */ |
23089 |
++ WARN_ON(!xid); |
23090 |
++ vxi = lookup_vx_info(xid); |
23091 |
++ if (!vxi) |
23092 |
++ goto out; |
23093 |
++ |
23094 |
++ length = -ENOMEM; |
23095 |
++ if (!(page = __get_free_page(GFP_KERNEL))) |
23096 |
++ goto out_put; |
23097 |
++ |
23098 |
++ BUG_ON(!PROC_I(inode)->op.proc_vxi_read); |
23099 |
++ length = PROC_I(inode)->op.proc_vxi_read(vxi, (char *)page); |
23100 |
++ |
23101 |
++ if (length >= 0) |
23102 |
++ length = simple_read_from_buffer(buf, count, ppos, |
23103 |
++ (char *)page, length); |
23104 |
++ |
23105 |
++ free_page(page); |
23106 |
++out_put: |
23107 |
++ put_vx_info(vxi); |
23108 |
++out: |
23109 |
++ return length; |
23110 |
++} |
23111 |
++ |
23112 |
++static ssize_t proc_nx_info_read(struct file *file, char __user *buf, |
23113 |
++ size_t count, loff_t *ppos) |
23114 |
++{ |
23115 |
++ struct inode *inode = file->f_dentry->d_inode; |
23116 |
++ struct nx_info *nxi = NULL; |
23117 |
++ nid_t nid = PROC_I(inode)->fd; |
23118 |
++ unsigned long page; |
23119 |
++ ssize_t length = 0; |
23120 |
++ |
23121 |
++ if (count > PROC_BLOCK_SIZE) |
23122 |
++ count = PROC_BLOCK_SIZE; |
23123 |
++ |
23124 |
++ /* fade that out as soon as stable */ |
23125 |
++ WARN_ON(!nid); |
23126 |
++ nxi = lookup_nx_info(nid); |
23127 |
++ if (!nxi) |
23128 |
++ goto out; |
23129 |
++ |
23130 |
++ length = -ENOMEM; |
23131 |
++ if (!(page = __get_free_page(GFP_KERNEL))) |
23132 |
++ goto out_put; |
23133 |
++ |
23134 |
++ BUG_ON(!PROC_I(inode)->op.proc_nxi_read); |
23135 |
++ length = PROC_I(inode)->op.proc_nxi_read(nxi, (char *)page); |
23136 |
++ |
23137 |
++ if (length >= 0) |
23138 |
++ length = simple_read_from_buffer(buf, count, ppos, |
23139 |
++ (char *)page, length); |
23140 |
++ |
23141 |
++ free_page(page); |
23142 |
++out_put: |
23143 |
++ put_nx_info(nxi); |
23144 |
++out: |
23145 |
++ return length; |
23146 |
++} |
23147 |
++ |
23148 |
++ |
23149 |
++ |
23150 |
++/* here comes the lower level */ |
23151 |
++ |
23152 |
++ |
23153 |
++#define NOD(NAME, MODE, IOP, FOP, OP) { \ |
23154 |
++ .len = sizeof(NAME) - 1, \ |
23155 |
++ .name = (NAME), \ |
23156 |
++ .mode = MODE, \ |
23157 |
++ .iop = IOP, \ |
23158 |
++ .fop = FOP, \ |
23159 |
++ .op = OP, \ |
23160 |
++} |
23161 |
++ |
23162 |
++ |
23163 |
++#define DIR(NAME, MODE, OTYPE) \ |
23164 |
++ NOD(NAME, (S_IFDIR | (MODE)), \ |
23165 |
++ &proc_ ## OTYPE ## _inode_operations, \ |
23166 |
++ &proc_ ## OTYPE ## _file_operations, { } ) |
23167 |
++ |
23168 |
++#define INF(NAME, MODE, OTYPE) \ |
23169 |
++ NOD(NAME, (S_IFREG | (MODE)), NULL, \ |
23170 |
++ &proc_vs_info_file_operations, \ |
23171 |
++ { .proc_vs_read = &proc_##OTYPE } ) |
23172 |
++ |
23173 |
++#define VINF(NAME, MODE, OTYPE) \ |
23174 |
++ NOD(NAME, (S_IFREG | (MODE)), NULL, \ |
23175 |
++ &proc_vx_info_file_operations, \ |
23176 |
++ { .proc_vxi_read = &proc_##OTYPE } ) |
23177 |
++ |
23178 |
++#define NINF(NAME, MODE, OTYPE) \ |
23179 |
++ NOD(NAME, (S_IFREG | (MODE)), NULL, \ |
23180 |
++ &proc_nx_info_file_operations, \ |
23181 |
++ { .proc_nxi_read = &proc_##OTYPE } ) |
23182 |
++ |
23183 |
++ |
23184 |
++static struct file_operations proc_vs_info_file_operations = { |
23185 |
++ .read = proc_vs_info_read, |
23186 |
++}; |
23187 |
++ |
23188 |
++static struct file_operations proc_vx_info_file_operations = { |
23189 |
++ .read = proc_vx_info_read, |
23190 |
++}; |
23191 |
++ |
23192 |
++static struct dentry_operations proc_xid_dentry_operations = { |
23193 |
++ .d_revalidate = proc_xid_revalidate, |
23194 |
++}; |
23195 |
++ |
23196 |
++static struct vs_entry vx_base_stuff[] = { |
23197 |
++ VINF("info", S_IRUGO, vxi_info), |
23198 |
++ VINF("status", S_IRUGO, vxi_status), |
23199 |
++ VINF("limit", S_IRUGO, vxi_limit), |
23200 |
++ VINF("sched", S_IRUGO, vxi_sched), |
23201 |
++ VINF("nsproxy", S_IRUGO, vxi_nsproxy0), |
23202 |
++ VINF("nsproxy1",S_IRUGO, vxi_nsproxy1), |
23203 |
++ VINF("cvirt", S_IRUGO, vxi_cvirt), |
23204 |
++ VINF("cacct", S_IRUGO, vxi_cacct), |
23205 |
++ {} |
23206 |
++}; |
23207 |
++ |
23208 |
++ |
23209 |
++ |
23210 |
++ |
23211 |
++static struct dentry *proc_xid_instantiate(struct inode *dir, |
23212 |
++ struct dentry *dentry, int id, void *ptr) |
23213 |
++{ |
23214 |
++ dentry->d_op = &proc_xid_dentry_operations; |
23215 |
++ return vs_proc_instantiate(dir, dentry, id, ptr); |
23216 |
++} |
23217 |
++ |
23218 |
++static struct dentry *proc_xid_lookup(struct inode *dir, |
23219 |
++ struct dentry *dentry, struct nameidata *nd) |
23220 |
++{ |
23221 |
++ struct vs_entry *p = vx_base_stuff; |
23222 |
++ struct dentry *error = ERR_PTR(-ENOENT); |
23223 |
++ |
23224 |
++ for (; p->name; p++) { |
23225 |
++ if (p->len != dentry->d_name.len) |
23226 |
++ continue; |
23227 |
++ if (!memcmp(dentry->d_name.name, p->name, p->len)) |
23228 |
++ break; |
23229 |
++ } |
23230 |
++ if (!p->name) |
23231 |
++ goto out; |
23232 |
++ |
23233 |
++ error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p); |
23234 |
++out: |
23235 |
++ return error; |
23236 |
++} |
23237 |
++ |
23238 |
++static int proc_xid_readdir(struct file *filp, |
23239 |
++ void *dirent, filldir_t filldir) |
23240 |
++{ |
23241 |
++ struct dentry *dentry = filp->f_dentry; |
23242 |
++ struct inode *inode = dentry->d_inode; |
23243 |
++ struct vs_entry *p = vx_base_stuff; |
23244 |
++ int size = sizeof(vx_base_stuff) / sizeof(struct vs_entry); |
23245 |
++ int pos, index; |
23246 |
++ u64 ino; |
23247 |
++ |
23248 |
++ pos = filp->f_pos; |
23249 |
++ switch (pos) { |
23250 |
++ case 0: |
23251 |
++ ino = inode->i_ino; |
23252 |
++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0) |
23253 |
++ goto out; |
23254 |
++ pos++; |
23255 |
++ /* fall through */ |
23256 |
++ case 1: |
23257 |
++ ino = parent_ino(dentry); |
23258 |
++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0) |
23259 |
++ goto out; |
23260 |
++ pos++; |
23261 |
++ /* fall through */ |
23262 |
++ default: |
23263 |
++ index = pos - 2; |
23264 |
++ if (index >= size) |
23265 |
++ goto out; |
23266 |
++ for (p += index; p->name; p++) { |
23267 |
++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len, |
23268 |
++ vs_proc_instantiate, PROC_I(inode)->fd, p)) |
23269 |
++ goto out; |
23270 |
++ pos++; |
23271 |
++ } |
23272 |
++ } |
23273 |
++out: |
23274 |
++ filp->f_pos = pos; |
23275 |
++ return 1; |
23276 |
++} |
23277 |
++ |
23278 |
++ |
23279 |
++ |
23280 |
++static struct file_operations proc_nx_info_file_operations = { |
23281 |
++ .read = proc_nx_info_read, |
23282 |
++}; |
23283 |
++ |
23284 |
++static struct dentry_operations proc_nid_dentry_operations = { |
23285 |
++ .d_revalidate = proc_nid_revalidate, |
23286 |
++}; |
23287 |
++ |
23288 |
++static struct vs_entry nx_base_stuff[] = { |
23289 |
++ NINF("info", S_IRUGO, nxi_info), |
23290 |
++ NINF("status", S_IRUGO, nxi_status), |
23291 |
++ {} |
23292 |
++}; |
23293 |
++ |
23294 |
++ |
23295 |
++static struct dentry *proc_nid_instantiate(struct inode *dir, |
23296 |
++ struct dentry *dentry, int id, void *ptr) |
23297 |
++{ |
23298 |
++ dentry->d_op = &proc_nid_dentry_operations; |
23299 |
++ return vs_proc_instantiate(dir, dentry, id, ptr); |
23300 |
++} |
23301 |
++ |
23302 |
++static struct dentry *proc_nid_lookup(struct inode *dir, |
23303 |
++ struct dentry *dentry, struct nameidata *nd) |
23304 |
++{ |
23305 |
++ struct vs_entry *p = nx_base_stuff; |
23306 |
++ struct dentry *error = ERR_PTR(-ENOENT); |
23307 |
++ |
23308 |
++ for (; p->name; p++) { |
23309 |
++ if (p->len != dentry->d_name.len) |
23310 |
++ continue; |
23311 |
++ if (!memcmp(dentry->d_name.name, p->name, p->len)) |
23312 |
++ break; |
23313 |
++ } |
23314 |
++ if (!p->name) |
23315 |
++ goto out; |
23316 |
++ |
23317 |
++ error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p); |
23318 |
++out: |
23319 |
++ return error; |
23320 |
++} |
23321 |
++ |
23322 |
++static int proc_nid_readdir(struct file *filp, |
23323 |
++ void *dirent, filldir_t filldir) |
23324 |
++{ |
23325 |
++ struct dentry *dentry = filp->f_dentry; |
23326 |
++ struct inode *inode = dentry->d_inode; |
23327 |
++ struct vs_entry *p = nx_base_stuff; |
23328 |
++ int size = sizeof(nx_base_stuff) / sizeof(struct vs_entry); |
23329 |
++ int pos, index; |
23330 |
++ u64 ino; |
23331 |
++ |
23332 |
++ pos = filp->f_pos; |
23333 |
++ switch (pos) { |
23334 |
++ case 0: |
23335 |
++ ino = inode->i_ino; |
23336 |
++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0) |
23337 |
++ goto out; |
23338 |
++ pos++; |
23339 |
++ /* fall through */ |
23340 |
++ case 1: |
23341 |
++ ino = parent_ino(dentry); |
23342 |
++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0) |
23343 |
++ goto out; |
23344 |
++ pos++; |
23345 |
++ /* fall through */ |
23346 |
++ default: |
23347 |
++ index = pos - 2; |
23348 |
++ if (index >= size) |
23349 |
++ goto out; |
23350 |
++ for (p += index; p->name; p++) { |
23351 |
++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len, |
23352 |
++ vs_proc_instantiate, PROC_I(inode)->fd, p)) |
23353 |
++ goto out; |
23354 |
++ pos++; |
23355 |
++ } |
23356 |
++ } |
23357 |
++out: |
23358 |
++ filp->f_pos = pos; |
23359 |
++ return 1; |
23360 |
++} |
23361 |
++ |
23362 |
++ |
23363 |
++#define MAX_MULBY10 ((~0U - 9) / 10) |
23364 |
++ |
23365 |
++static inline int atovid(const char *str, int len) |
23366 |
++{ |
23367 |
++ int vid, c; |
23368 |
++ |
23369 |
++ vid = 0; |
23370 |
++ while (len-- > 0) { |
23371 |
++ c = *str - '0'; |
23372 |
++ str++; |
23373 |
++ if (c > 9) |
23374 |
++ return -1; |
23375 |
++ if (vid >= MAX_MULBY10) |
23376 |
++ return -1; |
23377 |
++ vid *= 10; |
23378 |
++ vid += c; |
23379 |
++ if (!vid) |
23380 |
++ return -1; |
23381 |
++ } |
23382 |
++ return vid; |
23383 |
++} |
23384 |
++ |
23385 |
++/* now the upper level (virtual) */ |
23386 |
++ |
23387 |
++ |
23388 |
++static struct file_operations proc_xid_file_operations = { |
23389 |
++ .read = generic_read_dir, |
23390 |
++ .readdir = proc_xid_readdir, |
23391 |
++}; |
23392 |
++ |
23393 |
++static struct inode_operations proc_xid_inode_operations = { |
23394 |
++ .lookup = proc_xid_lookup, |
23395 |
++}; |
23396 |
++ |
23397 |
++static struct vs_entry vx_virtual_stuff[] = { |
23398 |
++ INF("info", S_IRUGO, virtual_info), |
23399 |
++ INF("status", S_IRUGO, virtual_status), |
23400 |
++ DIR(NULL, S_IRUGO | S_IXUGO, xid), |
23401 |
++}; |
23402 |
++ |
23403 |
++ |
23404 |
++static struct dentry *proc_virtual_lookup(struct inode *dir, |
23405 |
++ struct dentry *dentry, struct nameidata *nd) |
23406 |
++{ |
23407 |
++ struct vs_entry *p = vx_virtual_stuff; |
23408 |
++ struct dentry *error = ERR_PTR(-ENOENT); |
23409 |
++ int id = 0; |
23410 |
++ |
23411 |
++ for (; p->name; p++) { |
23412 |
++ if (p->len != dentry->d_name.len) |
23413 |
++ continue; |
23414 |
++ if (!memcmp(dentry->d_name.name, p->name, p->len)) |
23415 |
++ break; |
23416 |
++ } |
23417 |
++ if (p->name) |
23418 |
++ goto instantiate; |
23419 |
++ |
23420 |
++ id = atovid(dentry->d_name.name, dentry->d_name.len); |
23421 |
++ if ((id < 0) || !xid_is_hashed(id)) |
23422 |
++ goto out; |
23423 |
++ |
23424 |
++instantiate: |
23425 |
++ error = proc_xid_instantiate(dir, dentry, id, p); |
23426 |
++out: |
23427 |
++ return error; |
23428 |
++} |
23429 |
++ |
23430 |
++static struct file_operations proc_nid_file_operations = { |
23431 |
++ .read = generic_read_dir, |
23432 |
++ .readdir = proc_nid_readdir, |
23433 |
++}; |
23434 |
++ |
23435 |
++static struct inode_operations proc_nid_inode_operations = { |
23436 |
++ .lookup = proc_nid_lookup, |
23437 |
++}; |
23438 |
++ |
23439 |
++static struct vs_entry nx_virtnet_stuff[] = { |
23440 |
++ INF("info", S_IRUGO, virtnet_info), |
23441 |
++ INF("status", S_IRUGO, virtnet_status), |
23442 |
++ DIR(NULL, S_IRUGO | S_IXUGO, nid), |
23443 |
++}; |
23444 |
++ |
23445 |
++ |
23446 |
++static struct dentry *proc_virtnet_lookup(struct inode *dir, |
23447 |
++ struct dentry *dentry, struct nameidata *nd) |
23448 |
++{ |
23449 |
++ struct vs_entry *p = nx_virtnet_stuff; |
23450 |
++ struct dentry *error = ERR_PTR(-ENOENT); |
23451 |
++ int id = 0; |
23452 |
++ |
23453 |
++ for (; p->name; p++) { |
23454 |
++ if (p->len != dentry->d_name.len) |
23455 |
++ continue; |
23456 |
++ if (!memcmp(dentry->d_name.name, p->name, p->len)) |
23457 |
++ break; |
23458 |
++ } |
23459 |
++ if (p->name) |
23460 |
++ goto instantiate; |
23461 |
++ |
23462 |
++ id = atovid(dentry->d_name.name, dentry->d_name.len); |
23463 |
++ if ((id < 0) || !nid_is_hashed(id)) |
23464 |
++ goto out; |
23465 |
++ |
23466 |
++instantiate: |
23467 |
++ error = proc_nid_instantiate(dir, dentry, id, p); |
23468 |
++out: |
23469 |
++ return error; |
23470 |
++} |
23471 |
++ |
23472 |
++ |
23473 |
++#define PROC_MAXVIDS 32 |
23474 |
++ |
23475 |
++int proc_virtual_readdir(struct file *filp, |
23476 |
++ void *dirent, filldir_t filldir) |
23477 |
++{ |
23478 |
++ struct dentry *dentry = filp->f_dentry; |
23479 |
++ struct inode *inode = dentry->d_inode; |
23480 |
++ struct vs_entry *p = vx_virtual_stuff; |
23481 |
++ int size = sizeof(vx_virtual_stuff) / sizeof(struct vs_entry); |
23482 |
++ int pos, index; |
23483 |
++ unsigned int xid_array[PROC_MAXVIDS]; |
23484 |
++ char buf[PROC_NUMBUF]; |
23485 |
++ unsigned int nr_xids, i; |
23486 |
++ u64 ino; |
23487 |
++ |
23488 |
++ pos = filp->f_pos; |
23489 |
++ switch (pos) { |
23490 |
++ case 0: |
23491 |
++ ino = inode->i_ino; |
23492 |
++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0) |
23493 |
++ goto out; |
23494 |
++ pos++; |
23495 |
++ /* fall through */ |
23496 |
++ case 1: |
23497 |
++ ino = parent_ino(dentry); |
23498 |
++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0) |
23499 |
++ goto out; |
23500 |
++ pos++; |
23501 |
++ /* fall through */ |
23502 |
++ default: |
23503 |
++ index = pos - 2; |
23504 |
++ if (index >= size) |
23505 |
++ goto entries; |
23506 |
++ for (p += index; p->name; p++) { |
23507 |
++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len, |
23508 |
++ vs_proc_instantiate, 0, p)) |
23509 |
++ goto out; |
23510 |
++ pos++; |
23511 |
++ } |
23512 |
++ entries: |
23513 |
++ index = pos - size; |
23514 |
++ p = &vx_virtual_stuff[size - 1]; |
23515 |
++ nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS); |
23516 |
++ for (i = 0; i < nr_xids; i++) { |
23517 |
++ int n, xid = xid_array[i]; |
23518 |
++ unsigned int j = PROC_NUMBUF; |
23519 |
++ |
23520 |
++ n = xid; |
23521 |
++ do |
23522 |
++ buf[--j] = '0' + (n % 10); |
23523 |
++ while (n /= 10); |
23524 |
++ |
23525 |
++ if (proc_fill_cache(filp, dirent, filldir, |
23526 |
++ buf + j, PROC_NUMBUF - j, |
23527 |
++ vs_proc_instantiate, xid, p)) |
23528 |
++ goto out; |
23529 |
++ pos++; |
23530 |
++ } |
23531 |
++ } |
23532 |
++out: |
23533 |
++ filp->f_pos = pos; |
23534 |
++ return 0; |
23535 |
++} |
23536 |
++ |
23537 |
++static int proc_virtual_getattr(struct vfsmount *mnt, |
23538 |
++ struct dentry *dentry, struct kstat *stat) |
23539 |
++{ |
23540 |
++ struct inode *inode = dentry->d_inode; |
23541 |
++ |
23542 |
++ generic_fillattr(inode, stat); |
23543 |
++ stat->nlink = 2 + atomic_read(&vx_global_cactive); |
23544 |
++ return 0; |
23545 |
++} |
23546 |
++ |
23547 |
++static struct file_operations proc_virtual_dir_operations = { |
23548 |
++ .read = generic_read_dir, |
23549 |
++ .readdir = proc_virtual_readdir, |
23550 |
++}; |
23551 |
++ |
23552 |
++static struct inode_operations proc_virtual_dir_inode_operations = { |
23553 |
++ .getattr = proc_virtual_getattr, |
23554 |
++ .lookup = proc_virtual_lookup, |
23555 |
++}; |
23556 |
++ |
23557 |
++ |
23558 |
++ |
23559 |
++ |
23560 |
++ |
23561 |
++int proc_virtnet_readdir(struct file *filp, |
23562 |
++ void *dirent, filldir_t filldir) |
23563 |
++{ |
23564 |
++ struct dentry *dentry = filp->f_dentry; |
23565 |
++ struct inode *inode = dentry->d_inode; |
23566 |
++ struct vs_entry *p = nx_virtnet_stuff; |
23567 |
++ int size = sizeof(nx_virtnet_stuff) / sizeof(struct vs_entry); |
23568 |
++ int pos, index; |
23569 |
++ unsigned int nid_array[PROC_MAXVIDS]; |
23570 |
++ char buf[PROC_NUMBUF]; |
23571 |
++ unsigned int nr_nids, i; |
23572 |
++ u64 ino; |
23573 |
++ |
23574 |
++ pos = filp->f_pos; |
23575 |
++ switch (pos) { |
23576 |
++ case 0: |
23577 |
++ ino = inode->i_ino; |
23578 |
++ if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0) |
23579 |
++ goto out; |
23580 |
++ pos++; |
23581 |
++ /* fall through */ |
23582 |
++ case 1: |
23583 |
++ ino = parent_ino(dentry); |
23584 |
++ if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0) |
23585 |
++ goto out; |
23586 |
++ pos++; |
23587 |
++ /* fall through */ |
23588 |
++ default: |
23589 |
++ index = pos - 2; |
23590 |
++ if (index >= size) |
23591 |
++ goto entries; |
23592 |
++ for (p += index; p->name; p++) { |
23593 |
++ if (proc_fill_cache(filp, dirent, filldir, p->name, p->len, |
23594 |
++ vs_proc_instantiate, 0, p)) |
23595 |
++ goto out; |
23596 |
++ pos++; |
23597 |
++ } |
23598 |
++ entries: |
23599 |
++ index = pos - size; |
23600 |
++ p = &nx_virtnet_stuff[size - 1]; |
23601 |
++ nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS); |
23602 |
++ for (i = 0; i < nr_nids; i++) { |
23603 |
++ int n, nid = nid_array[i]; |
23604 |
++ unsigned int j = PROC_NUMBUF; |
23605 |
++ |
23606 |
++ n = nid; |
23607 |
++ do |
23608 |
++ buf[--j] = '0' + (n % 10); |
23609 |
++ while (n /= 10); |
23610 |
++ |
23611 |
++ if (proc_fill_cache(filp, dirent, filldir, |
23612 |
++ buf + j, PROC_NUMBUF - j, |
23613 |
++ vs_proc_instantiate, nid, p)) |
23614 |
++ goto out; |
23615 |
++ pos++; |
23616 |
++ } |
23617 |
++ } |
23618 |
++out: |
23619 |
++ filp->f_pos = pos; |
23620 |
++ return 0; |
23621 |
++} |
23622 |
++ |
23623 |
++static int proc_virtnet_getattr(struct vfsmount *mnt, |
23624 |
++ struct dentry *dentry, struct kstat *stat) |
23625 |
++{ |
23626 |
++ struct inode *inode = dentry->d_inode; |
23627 |
++ |
23628 |
++ generic_fillattr(inode, stat); |
23629 |
++ stat->nlink = 2 + atomic_read(&nx_global_cactive); |
23630 |
++ return 0; |
23631 |
++} |
23632 |
++ |
23633 |
++static struct file_operations proc_virtnet_dir_operations = { |
23634 |
++ .read = generic_read_dir, |
23635 |
++ .readdir = proc_virtnet_readdir, |
23636 |
++}; |
23637 |
++ |
23638 |
++static struct inode_operations proc_virtnet_dir_inode_operations = { |
23639 |
++ .getattr = proc_virtnet_getattr, |
23640 |
++ .lookup = proc_virtnet_lookup, |
23641 |
++}; |
23642 |
++ |
23643 |
++ |
23644 |
++ |
23645 |
++void proc_vx_init(void) |
23646 |
++{ |
23647 |
++ struct proc_dir_entry *ent; |
23648 |
++ |
23649 |
++ ent = proc_mkdir("virtual", 0); |
23650 |
++ if (ent) { |
23651 |
++ ent->proc_fops = &proc_virtual_dir_operations; |
23652 |
++ ent->proc_iops = &proc_virtual_dir_inode_operations; |
23653 |
++ } |
23654 |
++ proc_virtual = ent; |
23655 |
++ |
23656 |
++ ent = proc_mkdir("virtnet", 0); |
23657 |
++ if (ent) { |
23658 |
++ ent->proc_fops = &proc_virtnet_dir_operations; |
23659 |
++ ent->proc_iops = &proc_virtnet_dir_inode_operations; |
23660 |
++ } |
23661 |
++ proc_virtnet = ent; |
23662 |
++} |
23663 |
++ |
23664 |
++ |
23665 |
++ |
23666 |
++ |
23667 |
++/* per pid info */ |
23668 |
++ |
23669 |
++ |
23670 |
++int proc_pid_vx_info(struct task_struct *p, char *buffer) |
23671 |
++{ |
23672 |
++ struct vx_info *vxi; |
23673 |
++ char *orig = buffer; |
23674 |
++ |
23675 |
++ buffer += sprintf(buffer, "XID:\t%d\n", vx_task_xid(p)); |
23676 |
++ |
23677 |
++ vxi = task_get_vx_info(p); |
23678 |
++ if (!vxi) |
23679 |
++ goto out; |
23680 |
++ |
23681 |
++ buffer += sprintf(buffer, "BCaps:\t"); |
23682 |
++ buffer = print_cap_t(buffer, &vxi->vx_bcaps); |
23683 |
++ buffer += sprintf(buffer, "\n"); |
23684 |
++ buffer += sprintf(buffer, "CCaps:\t%016llx\n", |
23685 |
++ (unsigned long long)vxi->vx_ccaps); |
23686 |
++ buffer += sprintf(buffer, "CFlags:\t%016llx\n", |
23687 |
++ (unsigned long long)vxi->vx_flags); |
23688 |
++ buffer += sprintf(buffer, "CIPid:\t%d\n", vxi->vx_initpid); |
23689 |
++ |
23690 |
++ put_vx_info(vxi); |
23691 |
++out: |
23692 |
++ return buffer - orig; |
23693 |
++} |
23694 |
++ |
23695 |
++ |
23696 |
++int proc_pid_nx_info(struct task_struct *p, char *buffer) |
23697 |
++{ |
23698 |
++ struct nx_info *nxi; |
23699 |
++ struct nx_addr_v4 *v4a; |
23700 |
++#ifdef CONFIG_IPV6 |
23701 |
++ struct nx_addr_v6 *v6a; |
23702 |
++#endif |
23703 |
++ char *orig = buffer; |
23704 |
++ int i; |
23705 |
++ |
23706 |
++ buffer += sprintf(buffer, "NID:\t%d\n", nx_task_nid(p)); |
23707 |
++ |
23708 |
++ nxi = task_get_nx_info(p); |
23709 |
++ if (!nxi) |
23710 |
++ goto out; |
23711 |
++ |
23712 |
++ buffer += sprintf(buffer, "NCaps:\t%016llx\n", |
23713 |
++ (unsigned long long)nxi->nx_ncaps); |
23714 |
++ buffer += sprintf(buffer, "NFlags:\t%016llx\n", |
23715 |
++ (unsigned long long)nxi->nx_flags); |
23716 |
++ |
23717 |
++ buffer += sprintf(buffer, |
23718 |
++ "V4Root[bcast]:\t" NIPQUAD_FMT "\n", |
23719 |
++ NIPQUAD(nxi->v4_bcast.s_addr)); |
23720 |
++ buffer += sprintf (buffer, |
23721 |
++ "V4Root[lback]:\t" NIPQUAD_FMT "\n", |
23722 |
++ NIPQUAD(nxi->v4_lback.s_addr)); |
23723 |
++ if (!NX_IPV4(nxi)) |
23724 |
++ goto skip_v4; |
23725 |
++ for (i = 0, v4a = &nxi->v4; v4a; i++, v4a = v4a->next) |
23726 |
++ buffer += sprintf(buffer, "V4Root[%d]:\t" NXAV4_FMT "\n", |
23727 |
++ i, NXAV4(v4a)); |
23728 |
++skip_v4: |
23729 |
++#ifdef CONFIG_IPV6 |
23730 |
++ if (!NX_IPV6(nxi)) |
23731 |
++ goto skip_v6; |
23732 |
++ for (i = 0, v6a = &nxi->v6; v6a; i++, v6a = v6a->next) |
23733 |
++ buffer += sprintf(buffer, "V6Root[%d]:\t" NXAV6_FMT "\n", |
23734 |
++ i, NXAV6(v6a)); |
23735 |
++skip_v6: |
23736 |
++#endif |
23737 |
++ put_nx_info(nxi); |
23738 |
++out: |
23739 |
++ return buffer - orig; |
23740 |
++} |
23741 |
++ |
23742 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/sched.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/sched.c |
23743 |
+--- linux-2.6.29.4/kernel/vserver/sched.c 1970-01-01 01:00:00.000000000 +0100 |
23744 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/sched.c 2009-02-22 22:54:26.000000000 +0100 |
23745 |
+@@ -0,0 +1,414 @@ |
23746 |
++/* |
23747 |
++ * linux/kernel/vserver/sched.c |
23748 |
++ * |
23749 |
++ * Virtual Server: Scheduler Support |
23750 |
++ * |
23751 |
++ * Copyright (C) 2004-2007 Herbert Pötzl |
23752 |
++ * |
23753 |
++ * V0.01 adapted Sam Vilains version to 2.6.3 |
23754 |
++ * V0.02 removed legacy interface |
23755 |
++ * V0.03 changed vcmds to vxi arg |
23756 |
++ * V0.04 removed older and legacy interfaces |
23757 |
++ * |
23758 |
++ */ |
23759 |
++ |
23760 |
++#include <linux/vs_context.h> |
23761 |
++#include <linux/vs_sched.h> |
23762 |
++#include <linux/vserver/sched_cmd.h> |
23763 |
++ |
23764 |
++#include <asm/uaccess.h> |
23765 |
++ |
23766 |
++ |
23767 |
++#define vxd_check_range(val, min, max) do { \ |
23768 |
++ vxlprintk((val < min) || (val > max), \ |
23769 |
++ "check_range(%ld,%ld,%ld)", \ |
23770 |
++ (long)val, (long)min, (long)max, \ |
23771 |
++ __FILE__, __LINE__); \ |
23772 |
++ } while (0) |
23773 |
++ |
23774 |
++ |
23775 |
++void vx_update_sched_param(struct _vx_sched *sched, |
23776 |
++ struct _vx_sched_pc *sched_pc) |
23777 |
++{ |
23778 |
++ unsigned int set_mask = sched->update_mask; |
23779 |
++ |
23780 |
++ if (set_mask & VXSM_FILL_RATE) |
23781 |
++ sched_pc->fill_rate[0] = sched->fill_rate[0]; |
23782 |
++ if (set_mask & VXSM_INTERVAL) |
23783 |
++ sched_pc->interval[0] = sched->interval[0]; |
23784 |
++ if (set_mask & VXSM_FILL_RATE2) |
23785 |
++ sched_pc->fill_rate[1] = sched->fill_rate[1]; |
23786 |
++ if (set_mask & VXSM_INTERVAL2) |
23787 |
++ sched_pc->interval[1] = sched->interval[1]; |
23788 |
++ if (set_mask & VXSM_TOKENS) |
23789 |
++ sched_pc->tokens = sched->tokens; |
23790 |
++ if (set_mask & VXSM_TOKENS_MIN) |
23791 |
++ sched_pc->tokens_min = sched->tokens_min; |
23792 |
++ if (set_mask & VXSM_TOKENS_MAX) |
23793 |
++ sched_pc->tokens_max = sched->tokens_max; |
23794 |
++ if (set_mask & VXSM_PRIO_BIAS) |
23795 |
++ sched_pc->prio_bias = sched->prio_bias; |
23796 |
++ |
23797 |
++ if (set_mask & VXSM_IDLE_TIME) |
23798 |
++ sched_pc->flags |= VXSF_IDLE_TIME; |
23799 |
++ else |
23800 |
++ sched_pc->flags &= ~VXSF_IDLE_TIME; |
23801 |
++ |
23802 |
++ /* reset time */ |
23803 |
++ sched_pc->norm_time = jiffies; |
23804 |
++} |
23805 |
++ |
23806 |
++ |
23807 |
++/* |
23808 |
++ * recalculate the context's scheduling tokens |
23809 |
++ * |
23810 |
++ * ret > 0 : number of tokens available |
23811 |
++ * ret < 0 : on hold, check delta_min[] |
23812 |
++ * -1 only jiffies |
23813 |
++ * -2 also idle time |
23814 |
++ * |
23815 |
++ */ |
23816 |
++int vx_tokens_recalc(struct _vx_sched_pc *sched_pc, |
23817 |
++ unsigned long *norm_time, unsigned long *idle_time, int delta_min[2]) |
23818 |
++{ |
23819 |
++ long delta; |
23820 |
++ long tokens = 0; |
23821 |
++ int flags = sched_pc->flags; |
23822 |
++ |
23823 |
++ /* how much time did pass? */ |
23824 |
++ delta = *norm_time - sched_pc->norm_time; |
23825 |
++ // printk("@ %ld, %ld, %ld\n", *norm_time, sched_pc->norm_time, jiffies); |
23826 |
++ vxd_check_range(delta, 0, INT_MAX); |
23827 |
++ |
23828 |
++ if (delta >= sched_pc->interval[0]) { |
23829 |
++ long tokens, integral; |
23830 |
++ |
23831 |
++ /* calc integral token part */ |
23832 |
++ tokens = delta / sched_pc->interval[0]; |
23833 |
++ integral = tokens * sched_pc->interval[0]; |
23834 |
++ tokens *= sched_pc->fill_rate[0]; |
23835 |
++#ifdef CONFIG_VSERVER_HARDCPU |
23836 |
++ delta_min[0] = delta - integral; |
23837 |
++ vxd_check_range(delta_min[0], 0, sched_pc->interval[0]); |
23838 |
++#endif |
23839 |
++ /* advance time */ |
23840 |
++ sched_pc->norm_time += delta; |
23841 |
++ |
23842 |
++ /* add tokens */ |
23843 |
++ sched_pc->tokens += tokens; |
23844 |
++ sched_pc->token_time += tokens; |
23845 |
++ } else |
23846 |
++ delta_min[0] = delta; |
23847 |
++ |
23848 |
++#ifdef CONFIG_VSERVER_IDLETIME |
23849 |
++ if (!(flags & VXSF_IDLE_TIME)) |
23850 |
++ goto skip_idle; |
23851 |
++ |
23852 |
++ /* how much was the idle skip? */ |
23853 |
++ delta = *idle_time - sched_pc->idle_time; |
23854 |
++ vxd_check_range(delta, 0, INT_MAX); |
23855 |
++ |
23856 |
++ if (delta >= sched_pc->interval[1]) { |
23857 |
++ long tokens, integral; |
23858 |
++ |
23859 |
++ /* calc fair share token part */ |
23860 |
++ tokens = delta / sched_pc->interval[1]; |
23861 |
++ integral = tokens * sched_pc->interval[1]; |
23862 |
++ tokens *= sched_pc->fill_rate[1]; |
23863 |
++ delta_min[1] = delta - integral; |
23864 |
++ vxd_check_range(delta_min[1], 0, sched_pc->interval[1]); |
23865 |
++ |
23866 |
++ /* advance idle time */ |
23867 |
++ sched_pc->idle_time += integral; |
23868 |
++ |
23869 |
++ /* add tokens */ |
23870 |
++ sched_pc->tokens += tokens; |
23871 |
++ sched_pc->token_time += tokens; |
23872 |
++ } else |
23873 |
++ delta_min[1] = delta; |
23874 |
++skip_idle: |
23875 |
++#endif |
23876 |
++ |
23877 |
++ /* clip at maximum */ |
23878 |
++ if (sched_pc->tokens > sched_pc->tokens_max) |
23879 |
++ sched_pc->tokens = sched_pc->tokens_max; |
23880 |
++ tokens = sched_pc->tokens; |
23881 |
++ |
23882 |
++ if ((flags & VXSF_ONHOLD)) { |
23883 |
++ /* can we unhold? */ |
23884 |
++ if (tokens >= sched_pc->tokens_min) { |
23885 |
++ flags &= ~VXSF_ONHOLD; |
23886 |
++ sched_pc->hold_ticks += |
23887 |
++ *norm_time - sched_pc->onhold; |
23888 |
++ } else |
23889 |
++ goto on_hold; |
23890 |
++ } else { |
23891 |
++ /* put on hold? */ |
23892 |
++ if (tokens <= 0) { |
23893 |
++ flags |= VXSF_ONHOLD; |
23894 |
++ sched_pc->onhold = *norm_time; |
23895 |
++ goto on_hold; |
23896 |
++ } |
23897 |
++ } |
23898 |
++ sched_pc->flags = flags; |
23899 |
++ return tokens; |
23900 |
++ |
23901 |
++on_hold: |
23902 |
++ tokens = sched_pc->tokens_min - tokens; |
23903 |
++ sched_pc->flags = flags; |
23904 |
++ // BUG_ON(tokens < 0); probably doesn't hold anymore |
23905 |
++ |
23906 |
++#ifdef CONFIG_VSERVER_HARDCPU |
23907 |
++ /* next interval? */ |
23908 |
++ if (!sched_pc->fill_rate[0]) |
23909 |
++ delta_min[0] = HZ; |
23910 |
++ else if (tokens > sched_pc->fill_rate[0]) |
23911 |
++ delta_min[0] += sched_pc->interval[0] * |
23912 |
++ tokens / sched_pc->fill_rate[0]; |
23913 |
++ else |
23914 |
++ delta_min[0] = sched_pc->interval[0] - delta_min[0]; |
23915 |
++ vxd_check_range(delta_min[0], 0, INT_MAX); |
23916 |
++ |
23917 |
++#ifdef CONFIG_VSERVER_IDLETIME |
23918 |
++ if (!(flags & VXSF_IDLE_TIME)) |
23919 |
++ return -1; |
23920 |
++ |
23921 |
++ /* next interval? */ |
23922 |
++ if (!sched_pc->fill_rate[1]) |
23923 |
++ delta_min[1] = HZ; |
23924 |
++ else if (tokens > sched_pc->fill_rate[1]) |
23925 |
++ delta_min[1] += sched_pc->interval[1] * |
23926 |
++ tokens / sched_pc->fill_rate[1]; |
23927 |
++ else |
23928 |
++ delta_min[1] = sched_pc->interval[1] - delta_min[1]; |
23929 |
++ vxd_check_range(delta_min[1], 0, INT_MAX); |
23930 |
++ |
23931 |
++ return -2; |
23932 |
++#else |
23933 |
++ return -1; |
23934 |
++#endif /* CONFIG_VSERVER_IDLETIME */ |
23935 |
++#else |
23936 |
++ return 0; |
23937 |
++#endif /* CONFIG_VSERVER_HARDCPU */ |
23938 |
++} |
23939 |
++ |
23940 |
++static inline unsigned long msec_to_ticks(unsigned long msec) |
23941 |
++{ |
23942 |
++ return msecs_to_jiffies(msec); |
23943 |
++} |
23944 |
++ |
23945 |
++static inline unsigned long ticks_to_msec(unsigned long ticks) |
23946 |
++{ |
23947 |
++ return jiffies_to_msecs(ticks); |
23948 |
++} |
23949 |
++ |
23950 |
++static inline unsigned long ticks_to_usec(unsigned long ticks) |
23951 |
++{ |
23952 |
++ return jiffies_to_usecs(ticks); |
23953 |
++} |
23954 |
++ |
23955 |
++ |
23956 |
++static int do_set_sched(struct vx_info *vxi, struct vcmd_sched_v5 *data) |
23957 |
++{ |
23958 |
++ unsigned int set_mask = data->mask; |
23959 |
++ unsigned int update_mask; |
23960 |
++ int i, cpu; |
23961 |
++ |
23962 |
++ /* Sanity check data values */ |
23963 |
++ if (data->tokens_max <= 0) |
23964 |
++ data->tokens_max = HZ; |
23965 |
++ if (data->tokens_min < 0) |
23966 |
++ data->tokens_min = HZ / 3; |
23967 |
++ if (data->tokens_min >= data->tokens_max) |
23968 |
++ data->tokens_min = data->tokens_max; |
23969 |
++ |
23970 |
++ if (data->prio_bias > MAX_PRIO_BIAS) |
23971 |
++ data->prio_bias = MAX_PRIO_BIAS; |
23972 |
++ if (data->prio_bias < MIN_PRIO_BIAS) |
23973 |
++ data->prio_bias = MIN_PRIO_BIAS; |
23974 |
++ |
23975 |
++ spin_lock(&vxi->sched.tokens_lock); |
23976 |
++ |
23977 |
++ /* sync up on delayed updates */ |
23978 |
++ for_each_cpu_mask(cpu, vxi->sched.update) |
23979 |
++ vx_update_sched_param(&vxi->sched, |
23980 |
++ &vx_per_cpu(vxi, sched_pc, cpu)); |
23981 |
++ |
23982 |
++ if (set_mask & VXSM_FILL_RATE) |
23983 |
++ vxi->sched.fill_rate[0] = data->fill_rate[0]; |
23984 |
++ if (set_mask & VXSM_FILL_RATE2) |
23985 |
++ vxi->sched.fill_rate[1] = data->fill_rate[1]; |
23986 |
++ if (set_mask & VXSM_INTERVAL) |
23987 |
++ vxi->sched.interval[0] = (set_mask & VXSM_MSEC) ? |
23988 |
++ msec_to_ticks(data->interval[0]) : data->interval[0]; |
23989 |
++ if (set_mask & VXSM_INTERVAL2) |
23990 |
++ vxi->sched.interval[1] = (set_mask & VXSM_MSEC) ? |
23991 |
++ msec_to_ticks(data->interval[1]) : data->interval[1]; |
23992 |
++ if (set_mask & VXSM_TOKENS) |
23993 |
++ vxi->sched.tokens = data->tokens; |
23994 |
++ if (set_mask & VXSM_TOKENS_MIN) |
23995 |
++ vxi->sched.tokens_min = data->tokens_min; |
23996 |
++ if (set_mask & VXSM_TOKENS_MAX) |
23997 |
++ vxi->sched.tokens_max = data->tokens_max; |
23998 |
++ if (set_mask & VXSM_PRIO_BIAS) |
23999 |
++ vxi->sched.prio_bias = data->prio_bias; |
24000 |
++ |
24001 |
++ /* Sanity check rate/interval */ |
24002 |
++ for (i = 0; i < 2; i++) { |
24003 |
++ if (data->fill_rate[i] < 0) |
24004 |
++ data->fill_rate[i] = 0; |
24005 |
++ if (data->interval[i] <= 0) |
24006 |
++ data->interval[i] = HZ; |
24007 |
++ } |
24008 |
++ |
24009 |
++ update_mask = vxi->sched.update_mask & VXSM_SET_MASK; |
24010 |
++ update_mask |= (set_mask & (VXSM_SET_MASK | VXSM_IDLE_TIME)); |
24011 |
++ vxi->sched.update_mask = update_mask; |
24012 |
++ |
24013 |
++#ifdef CONFIG_SMP |
24014 |
++ rmb(); |
24015 |
++ if (set_mask & VXSM_CPU_ID) { |
24016 |
++ vxi->sched.update = cpumask_of_cpu(data->cpu_id); |
24017 |
++ cpus_and(vxi->sched.update, cpu_online_map, |
24018 |
++ vxi->sched.update); |
24019 |
++ } else |
24020 |
++ vxi->sched.update = cpu_online_map; |
24021 |
++ |
24022 |
++ /* forced reload? */ |
24023 |
++ if (set_mask & VXSM_FORCE) { |
24024 |
++ for_each_cpu_mask(cpu, vxi->sched.update) |
24025 |
++ vx_update_sched_param(&vxi->sched, |
24026 |
++ &vx_per_cpu(vxi, sched_pc, cpu)); |
24027 |
++ vxi->sched.update = CPU_MASK_NONE; |
24028 |
++ } |
24029 |
++#else |
24030 |
++ /* on UP we update immediately */ |
24031 |
++ vx_update_sched_param(&vxi->sched, |
24032 |
++ &vx_per_cpu(vxi, sched_pc, 0)); |
24033 |
++#endif |
24034 |
++ |
24035 |
++ spin_unlock(&vxi->sched.tokens_lock); |
24036 |
++ return 0; |
24037 |
++} |
24038 |
++ |
24039 |
++ |
24040 |
++#define COPY_IDS(C) C(cpu_id); C(bucket_id) |
24041 |
++#define COPY_PRI(C) C(prio_bias) |
24042 |
++#define COPY_TOK(C) C(tokens); C(tokens_min); C(tokens_max) |
24043 |
++#define COPY_FRI(C) C(fill_rate[0]); C(interval[0]); \ |
24044 |
++ C(fill_rate[1]); C(interval[1]); |
24045 |
++ |
24046 |
++#define COPY_VALUE(name) vc_data.name = data->name |
24047 |
++ |
24048 |
++static int do_set_sched_v4(struct vx_info *vxi, struct vcmd_set_sched_v4 *data) |
24049 |
++{ |
24050 |
++ struct vcmd_sched_v5 vc_data; |
24051 |
++ |
24052 |
++ vc_data.mask = data->set_mask; |
24053 |
++ COPY_IDS(COPY_VALUE); |
24054 |
++ COPY_PRI(COPY_VALUE); |
24055 |
++ COPY_TOK(COPY_VALUE); |
24056 |
++ vc_data.fill_rate[0] = vc_data.fill_rate[1] = data->fill_rate; |
24057 |
++ vc_data.interval[0] = vc_data.interval[1] = data->interval; |
24058 |
++ return do_set_sched(vxi, &vc_data); |
24059 |
++} |
24060 |
++ |
24061 |
++int vc_set_sched_v4(struct vx_info *vxi, void __user *data) |
24062 |
++{ |
24063 |
++ struct vcmd_set_sched_v4 vc_data; |
24064 |
++ |
24065 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
24066 |
++ return -EFAULT; |
24067 |
++ |
24068 |
++ return do_set_sched_v4(vxi, &vc_data); |
24069 |
++} |
24070 |
++ |
24071 |
++ /* latest interface is v5 */ |
24072 |
++ |
24073 |
++int vc_set_sched(struct vx_info *vxi, void __user *data) |
24074 |
++{ |
24075 |
++ struct vcmd_sched_v5 vc_data; |
24076 |
++ |
24077 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
24078 |
++ return -EFAULT; |
24079 |
++ |
24080 |
++ return do_set_sched(vxi, &vc_data); |
24081 |
++} |
24082 |
++ |
24083 |
++ |
24084 |
++#define COPY_PRI(C) C(prio_bias) |
24085 |
++#define COPY_TOK(C) C(tokens); C(tokens_min); C(tokens_max) |
24086 |
++#define COPY_FRI(C) C(fill_rate[0]); C(interval[0]); \ |
24087 |
++ C(fill_rate[1]); C(interval[1]); |
24088 |
++ |
24089 |
++#define COPY_VALUE(name) vc_data.name = data->name |
24090 |
++ |
24091 |
++ |
24092 |
++int vc_get_sched(struct vx_info *vxi, void __user *data) |
24093 |
++{ |
24094 |
++ struct vcmd_sched_v5 vc_data; |
24095 |
++ |
24096 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
24097 |
++ return -EFAULT; |
24098 |
++ |
24099 |
++ if (vc_data.mask & VXSM_CPU_ID) { |
24100 |
++ int cpu = vc_data.cpu_id; |
24101 |
++ struct _vx_sched_pc *data; |
24102 |
++ |
24103 |
++ if (!cpu_possible(cpu)) |
24104 |
++ return -EINVAL; |
24105 |
++ |
24106 |
++ data = &vx_per_cpu(vxi, sched_pc, cpu); |
24107 |
++ COPY_TOK(COPY_VALUE); |
24108 |
++ COPY_PRI(COPY_VALUE); |
24109 |
++ COPY_FRI(COPY_VALUE); |
24110 |
++ |
24111 |
++ if (data->flags & VXSF_IDLE_TIME) |
24112 |
++ vc_data.mask |= VXSM_IDLE_TIME; |
24113 |
++ } else { |
24114 |
++ struct _vx_sched *data = &vxi->sched; |
24115 |
++ |
24116 |
++ COPY_TOK(COPY_VALUE); |
24117 |
++ COPY_PRI(COPY_VALUE); |
24118 |
++ COPY_FRI(COPY_VALUE); |
24119 |
++ } |
24120 |
++ |
24121 |
++ if (vc_data.mask & VXSM_MSEC) { |
24122 |
++ vc_data.interval[0] = ticks_to_msec(vc_data.interval[0]); |
24123 |
++ vc_data.interval[1] = ticks_to_msec(vc_data.interval[1]); |
24124 |
++ } |
24125 |
++ |
24126 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
24127 |
++ return -EFAULT; |
24128 |
++ return 0; |
24129 |
++} |
24130 |
++ |
24131 |
++ |
24132 |
++int vc_sched_info(struct vx_info *vxi, void __user *data) |
24133 |
++{ |
24134 |
++ struct vcmd_sched_info vc_data; |
24135 |
++ int cpu; |
24136 |
++ |
24137 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
24138 |
++ return -EFAULT; |
24139 |
++ |
24140 |
++ cpu = vc_data.cpu_id; |
24141 |
++ if (!cpu_possible(cpu)) |
24142 |
++ return -EINVAL; |
24143 |
++ |
24144 |
++ if (vxi) { |
24145 |
++ struct _vx_sched_pc *sched_pc = |
24146 |
++ &vx_per_cpu(vxi, sched_pc, cpu); |
24147 |
++ |
24148 |
++ vc_data.user_msec = ticks_to_msec(sched_pc->user_ticks); |
24149 |
++ vc_data.sys_msec = ticks_to_msec(sched_pc->sys_ticks); |
24150 |
++ vc_data.hold_msec = ticks_to_msec(sched_pc->hold_ticks); |
24151 |
++ vc_data.vavavoom = sched_pc->vavavoom; |
24152 |
++ } |
24153 |
++ vc_data.token_usec = ticks_to_usec(1); |
24154 |
++ |
24155 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
24156 |
++ return -EFAULT; |
24157 |
++ return 0; |
24158 |
++} |
24159 |
++ |
24160 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/sched_init.h linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/sched_init.h |
24161 |
+--- linux-2.6.29.4/kernel/vserver/sched_init.h 1970-01-01 01:00:00.000000000 +0100 |
24162 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/sched_init.h 2009-02-22 22:54:26.000000000 +0100 |
24163 |
+@@ -0,0 +1,50 @@ |
24164 |
++ |
24165 |
++static inline void vx_info_init_sched(struct _vx_sched *sched) |
24166 |
++{ |
24167 |
++ static struct lock_class_key tokens_lock_key; |
24168 |
++ |
24169 |
++ /* scheduling; hard code starting values as constants */ |
24170 |
++ sched->fill_rate[0] = 1; |
24171 |
++ sched->interval[0] = 4; |
24172 |
++ sched->fill_rate[1] = 1; |
24173 |
++ sched->interval[1] = 8; |
24174 |
++ sched->tokens = HZ >> 2; |
24175 |
++ sched->tokens_min = HZ >> 4; |
24176 |
++ sched->tokens_max = HZ >> 1; |
24177 |
++ sched->tokens_lock = SPIN_LOCK_UNLOCKED; |
24178 |
++ sched->prio_bias = 0; |
24179 |
++ |
24180 |
++ lockdep_set_class(&sched->tokens_lock, &tokens_lock_key); |
24181 |
++} |
24182 |
++ |
24183 |
++static inline |
24184 |
++void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu) |
24185 |
++{ |
24186 |
++ sched_pc->fill_rate[0] = 1; |
24187 |
++ sched_pc->interval[0] = 4; |
24188 |
++ sched_pc->fill_rate[1] = 1; |
24189 |
++ sched_pc->interval[1] = 8; |
24190 |
++ sched_pc->tokens = HZ >> 2; |
24191 |
++ sched_pc->tokens_min = HZ >> 4; |
24192 |
++ sched_pc->tokens_max = HZ >> 1; |
24193 |
++ sched_pc->prio_bias = 0; |
24194 |
++ sched_pc->vavavoom = 0; |
24195 |
++ sched_pc->token_time = 0; |
24196 |
++ sched_pc->idle_time = 0; |
24197 |
++ sched_pc->norm_time = jiffies; |
24198 |
++ |
24199 |
++ sched_pc->user_ticks = 0; |
24200 |
++ sched_pc->sys_ticks = 0; |
24201 |
++ sched_pc->hold_ticks = 0; |
24202 |
++} |
24203 |
++ |
24204 |
++static inline void vx_info_exit_sched(struct _vx_sched *sched) |
24205 |
++{ |
24206 |
++ return; |
24207 |
++} |
24208 |
++ |
24209 |
++static inline |
24210 |
++void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu) |
24211 |
++{ |
24212 |
++ return; |
24213 |
++} |
24214 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/sched_proc.h linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/sched_proc.h |
24215 |
+--- linux-2.6.29.4/kernel/vserver/sched_proc.h 1970-01-01 01:00:00.000000000 +0100 |
24216 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/sched_proc.h 2009-02-22 22:54:26.000000000 +0100 |
24217 |
+@@ -0,0 +1,57 @@ |
24218 |
++#ifndef _VX_SCHED_PROC_H |
24219 |
++#define _VX_SCHED_PROC_H |
24220 |
++ |
24221 |
++ |
24222 |
++static inline |
24223 |
++int vx_info_proc_sched(struct _vx_sched *sched, char *buffer) |
24224 |
++{ |
24225 |
++ int length = 0; |
24226 |
++ |
24227 |
++ length += sprintf(buffer, |
24228 |
++ "FillRate:\t%8d,%d\n" |
24229 |
++ "Interval:\t%8d,%d\n" |
24230 |
++ "TokensMin:\t%8d\n" |
24231 |
++ "TokensMax:\t%8d\n" |
24232 |
++ "PrioBias:\t%8d\n", |
24233 |
++ sched->fill_rate[0], |
24234 |
++ sched->fill_rate[1], |
24235 |
++ sched->interval[0], |
24236 |
++ sched->interval[1], |
24237 |
++ sched->tokens_min, |
24238 |
++ sched->tokens_max, |
24239 |
++ sched->prio_bias); |
24240 |
++ return length; |
24241 |
++} |
24242 |
++ |
24243 |
++static inline |
24244 |
++int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc, |
24245 |
++ char *buffer, int cpu) |
24246 |
++{ |
24247 |
++ int length = 0; |
24248 |
++ |
24249 |
++ length += sprintf(buffer + length, |
24250 |
++ "cpu %d: %lld %lld %lld %ld %ld", cpu, |
24251 |
++ (unsigned long long)sched_pc->user_ticks, |
24252 |
++ (unsigned long long)sched_pc->sys_ticks, |
24253 |
++ (unsigned long long)sched_pc->hold_ticks, |
24254 |
++ sched_pc->token_time, |
24255 |
++ sched_pc->idle_time); |
24256 |
++ length += sprintf(buffer + length, |
24257 |
++ " %c%c %d %d %d %d/%d %d/%d", |
24258 |
++ (sched_pc->flags & VXSF_ONHOLD) ? 'H' : 'R', |
24259 |
++ (sched_pc->flags & VXSF_IDLE_TIME) ? 'I' : '-', |
24260 |
++ sched_pc->tokens, |
24261 |
++ sched_pc->tokens_min, |
24262 |
++ sched_pc->tokens_max, |
24263 |
++ sched_pc->fill_rate[0], |
24264 |
++ sched_pc->interval[0], |
24265 |
++ sched_pc->fill_rate[1], |
24266 |
++ sched_pc->interval[1]); |
24267 |
++ length += sprintf(buffer + length, |
24268 |
++ " %d %d\n", |
24269 |
++ sched_pc->prio_bias, |
24270 |
++ sched_pc->vavavoom); |
24271 |
++ return length; |
24272 |
++} |
24273 |
++ |
24274 |
++#endif /* _VX_SCHED_PROC_H */ |
24275 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/signal.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/signal.c |
24276 |
+--- linux-2.6.29.4/kernel/vserver/signal.c 1970-01-01 01:00:00.000000000 +0100 |
24277 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/signal.c 2009-02-22 22:54:26.000000000 +0100 |
24278 |
+@@ -0,0 +1,132 @@ |
24279 |
++/* |
24280 |
++ * linux/kernel/vserver/signal.c |
24281 |
++ * |
24282 |
++ * Virtual Server: Signal Support |
24283 |
++ * |
24284 |
++ * Copyright (C) 2003-2007 Herbert Pötzl |
24285 |
++ * |
24286 |
++ * V0.01 broken out from vcontext V0.05 |
24287 |
++ * V0.02 changed vcmds to vxi arg |
24288 |
++ * V0.03 adjusted siginfo for kill |
24289 |
++ * |
24290 |
++ */ |
24291 |
++ |
24292 |
++#include <asm/uaccess.h> |
24293 |
++ |
24294 |
++#include <linux/vs_context.h> |
24295 |
++#include <linux/vs_pid.h> |
24296 |
++#include <linux/vserver/signal_cmd.h> |
24297 |
++ |
24298 |
++ |
24299 |
++int vx_info_kill(struct vx_info *vxi, int pid, int sig) |
24300 |
++{ |
24301 |
++ int retval, count = 0; |
24302 |
++ struct task_struct *p; |
24303 |
++ struct siginfo *sip = SEND_SIG_PRIV; |
24304 |
++ |
24305 |
++ retval = -ESRCH; |
24306 |
++ vxdprintk(VXD_CBIT(misc, 4), |
24307 |
++ "vx_info_kill(%p[#%d],%d,%d)*", |
24308 |
++ vxi, vxi->vx_id, pid, sig); |
24309 |
++ read_lock(&tasklist_lock); |
24310 |
++ switch (pid) { |
24311 |
++ case 0: |
24312 |
++ case -1: |
24313 |
++ for_each_process(p) { |
24314 |
++ int err = 0; |
24315 |
++ |
24316 |
++ if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 || |
24317 |
++ (pid && vxi->vx_initpid == p->pid)) |
24318 |
++ continue; |
24319 |
++ |
24320 |
++ err = group_send_sig_info(sig, sip, p); |
24321 |
++ ++count; |
24322 |
++ if (err != -EPERM) |
24323 |
++ retval = err; |
24324 |
++ } |
24325 |
++ break; |
24326 |
++ |
24327 |
++ case 1: |
24328 |
++ if (vxi->vx_initpid) { |
24329 |
++ pid = vxi->vx_initpid; |
24330 |
++ /* for now, only SIGINT to private init ... */ |
24331 |
++ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) && |
24332 |
++ /* ... as long as there are tasks left */ |
24333 |
++ (atomic_read(&vxi->vx_tasks) > 1)) |
24334 |
++ sig = SIGINT; |
24335 |
++ } |
24336 |
++ /* fallthrough */ |
24337 |
++ default: |
24338 |
++ p = find_task_by_real_pid(pid); |
24339 |
++ if (p) { |
24340 |
++ if (vx_task_xid(p) == vxi->vx_id) |
24341 |
++ retval = group_send_sig_info(sig, sip, p); |
24342 |
++ } |
24343 |
++ break; |
24344 |
++ } |
24345 |
++ read_unlock(&tasklist_lock); |
24346 |
++ vxdprintk(VXD_CBIT(misc, 4), |
24347 |
++ "vx_info_kill(%p[#%d],%d,%d,%ld) = %d", |
24348 |
++ vxi, vxi->vx_id, pid, sig, (long)sip, retval); |
24349 |
++ return retval; |
24350 |
++} |
24351 |
++ |
24352 |
++int vc_ctx_kill(struct vx_info *vxi, void __user *data) |
24353 |
++{ |
24354 |
++ struct vcmd_ctx_kill_v0 vc_data; |
24355 |
++ |
24356 |
++ if (copy_from_user(&vc_data, data, sizeof(vc_data))) |
24357 |
++ return -EFAULT; |
24358 |
++ |
24359 |
++ /* special check to allow guest shutdown */ |
24360 |
++ if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) && |
24361 |
++ /* forbid killall pid=0 when init is present */ |
24362 |
++ (((vc_data.pid < 1) && vxi->vx_initpid) || |
24363 |
++ (vc_data.pid > 1))) |
24364 |
++ return -EACCES; |
24365 |
++ |
24366 |
++ return vx_info_kill(vxi, vc_data.pid, vc_data.sig); |
24367 |
++} |
24368 |
++ |
24369 |
++ |
24370 |
++static int __wait_exit(struct vx_info *vxi) |
24371 |
++{ |
24372 |
++ DECLARE_WAITQUEUE(wait, current); |
24373 |
++ int ret = 0; |
24374 |
++ |
24375 |
++ add_wait_queue(&vxi->vx_wait, &wait); |
24376 |
++ set_current_state(TASK_INTERRUPTIBLE); |
24377 |
++ |
24378 |
++wait: |
24379 |
++ if (vx_info_state(vxi, |
24380 |
++ VXS_SHUTDOWN | VXS_HASHED | VXS_HELPER) == VXS_SHUTDOWN) |
24381 |
++ goto out; |
24382 |
++ if (signal_pending(current)) { |
24383 |
++ ret = -ERESTARTSYS; |
24384 |
++ goto out; |
24385 |
++ } |
24386 |
++ schedule(); |
24387 |
++ goto wait; |
24388 |
++ |
24389 |
++out: |
24390 |
++ set_current_state(TASK_RUNNING); |
24391 |
++ remove_wait_queue(&vxi->vx_wait, &wait); |
24392 |
++ return ret; |
24393 |
++} |
24394 |
++ |
24395 |
++ |
24396 |
++ |
24397 |
++int vc_wait_exit(struct vx_info *vxi, void __user *data) |
24398 |
++{ |
24399 |
++ struct vcmd_wait_exit_v0 vc_data; |
24400 |
++ int ret; |
24401 |
++ |
24402 |
++ ret = __wait_exit(vxi); |
24403 |
++ vc_data.reboot_cmd = vxi->reboot_cmd; |
24404 |
++ vc_data.exit_code = vxi->exit_code; |
24405 |
++ |
24406 |
++ if (copy_to_user(data, &vc_data, sizeof(vc_data))) |
24407 |
++ ret = -EFAULT; |
24408 |
++ return ret; |
24409 |
++} |
24410 |
++ |
24411 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/space.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/space.c |
24412 |
+--- linux-2.6.29.4/kernel/vserver/space.c 1970-01-01 01:00:00.000000000 +0100 |
24413 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/space.c 2009-05-29 18:59:49.000000000 +0200 |
24414 |
+@@ -0,0 +1,375 @@ |
24415 |
++/* |
24416 |
++ * linux/kernel/vserver/space.c |
24417 |
++ * |
24418 |
++ * Virtual Server: Context Space Support |
24419 |
++ * |
24420 |
++ * Copyright (C) 2003-2007 Herbert Pötzl |
24421 |
++ * |
24422 |
++ * V0.01 broken out from context.c 0.07 |
24423 |
++ * V0.02 added task locking for namespace |
24424 |
++ * V0.03 broken out vx_enter_namespace |
24425 |
++ * V0.04 added *space support and commands |
24426 |
++ * |
24427 |
++ */ |
24428 |
++ |
24429 |
++#include <linux/utsname.h> |
24430 |
++#include <linux/nsproxy.h> |
24431 |
++#include <linux/err.h> |
24432 |
++#include <asm/uaccess.h> |
24433 |
++ |
24434 |
++#include <linux/vs_context.h> |
24435 |
++#include <linux/vserver/space.h> |
24436 |
++#include <linux/vserver/space_cmd.h> |
24437 |
++ |
24438 |
++atomic_t vs_global_nsproxy = ATOMIC_INIT(0); |
24439 |
++atomic_t vs_global_fs = ATOMIC_INIT(0); |
24440 |
++atomic_t vs_global_mnt_ns = ATOMIC_INIT(0); |
24441 |
++atomic_t vs_global_uts_ns = ATOMIC_INIT(0); |
24442 |
++atomic_t vs_global_ipc_ns = ATOMIC_INIT(0); |
24443 |
++atomic_t vs_global_user_ns = ATOMIC_INIT(0); |
24444 |
++atomic_t vs_global_pid_ns = ATOMIC_INIT(0); |
24445 |
++ |
24446 |
++ |
24447 |
++/* namespace functions */ |
24448 |
++ |
24449 |
++#include <linux/mnt_namespace.h> |
24450 |
++#include <linux/user_namespace.h> |
24451 |
++#include <linux/pid_namespace.h> |
24452 |
++#include <linux/ipc_namespace.h> |
24453 |
++#include <net/net_namespace.h> |
24454 |
++ |
24455 |
++ |
24456 |
++static const struct vcmd_space_mask_v1 space_mask_v0 = { |
24457 |
++ .mask = CLONE_FS | |
24458 |
++ CLONE_NEWNS | |
24459 |
++ CLONE_NEWUTS | |
24460 |
++ CLONE_NEWIPC | |
24461 |
++ CLONE_NEWUSER | |
24462 |
++ 0 |
24463 |
++}; |
24464 |
++ |
24465 |
++static const struct vcmd_space_mask_v1 space_mask = { |
24466 |
++ .mask = CLONE_FS | |
24467 |
++ CLONE_NEWNS | |
24468 |
++ CLONE_NEWUTS | |
24469 |
++ CLONE_NEWIPC | |
24470 |
++ CLONE_NEWUSER | |
24471 |
++#ifdef CONFIG_PID_NS |
24472 |
++ CLONE_NEWPID | |
24473 |
++#endif |
24474 |
++#ifdef CONFIG_NET_NS |
24475 |
++ CLONE_NEWNET | |
24476 |
++#endif |
24477 |
++ 0 |
24478 |
++}; |
24479 |
++ |
24480 |
++static const struct vcmd_space_mask_v1 default_space_mask = { |
24481 |
++ .mask = CLONE_FS | |
24482 |
++ CLONE_NEWNS | |
24483 |
++ CLONE_NEWUTS | |
24484 |
++ CLONE_NEWIPC | |
24485 |
++ CLONE_NEWUSER | |
24486 |
++#ifdef CONFIG_PID_NS |
24487 |
++// CLONE_NEWPID | |
24488 |
++#endif |
24489 |
++ 0 |
24490 |
++}; |
24491 |
++ |
24492 |
++/* |
24493 |
++ * build a new nsproxy mix |
24494 |
++ * assumes that both proxies are 'const' |
24495 |
++ * does not touch nsproxy refcounts |
24496 |
++ * will hold a reference on the result. |
24497 |
++ */ |
24498 |
++ |
24499 |
++struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy, |
24500 |
++ struct nsproxy *new_nsproxy, unsigned long mask) |
24501 |
++{ |
24502 |
++ struct mnt_namespace *old_ns; |
24503 |
++ struct uts_namespace *old_uts; |
24504 |
++ struct ipc_namespace *old_ipc; |
24505 |
++#ifdef CONFIG_PID_NS |
24506 |
++ struct pid_namespace *old_pid; |
24507 |
++#endif |
24508 |
++#ifdef CONFIG_NET_NS |
24509 |
++ struct net *old_net; |
24510 |
++#endif |
24511 |
++ struct nsproxy *nsproxy; |
24512 |
++ |
24513 |
++ nsproxy = copy_nsproxy(old_nsproxy); |
24514 |
++ if (!nsproxy) |
24515 |
++ goto out; |
24516 |
++ |
24517 |
++ if (mask & CLONE_NEWNS) { |
24518 |
++ old_ns = nsproxy->mnt_ns; |
24519 |
++ nsproxy->mnt_ns = new_nsproxy->mnt_ns; |
24520 |
++ if (nsproxy->mnt_ns) |
24521 |
++ get_mnt_ns(nsproxy->mnt_ns); |
24522 |
++ } else |
24523 |
++ old_ns = NULL; |
24524 |
++ |
24525 |
++ if (mask & CLONE_NEWUTS) { |
24526 |
++ old_uts = nsproxy->uts_ns; |
24527 |
++ nsproxy->uts_ns = new_nsproxy->uts_ns; |
24528 |
++ if (nsproxy->uts_ns) |
24529 |
++ get_uts_ns(nsproxy->uts_ns); |
24530 |
++ } else |
24531 |
++ old_uts = NULL; |
24532 |
++ |
24533 |
++ if (mask & CLONE_NEWIPC) { |
24534 |
++ old_ipc = nsproxy->ipc_ns; |
24535 |
++ nsproxy->ipc_ns = new_nsproxy->ipc_ns; |
24536 |
++ if (nsproxy->ipc_ns) |
24537 |
++ get_ipc_ns(nsproxy->ipc_ns); |
24538 |
++ } else |
24539 |
++ old_ipc = NULL; |
24540 |
++ |
24541 |
++#ifdef CONFIG_PID_NS |
24542 |
++ if (mask & CLONE_NEWPID) { |
24543 |
++ old_pid = nsproxy->pid_ns; |
24544 |
++ nsproxy->pid_ns = new_nsproxy->pid_ns; |
24545 |
++ if (nsproxy->pid_ns) |
24546 |
++ get_pid_ns(nsproxy->pid_ns); |
24547 |
++ } else |
24548 |
++ old_pid = NULL; |
24549 |
++#endif |
24550 |
++#ifdef CONFIG_NET_NS |
24551 |
++ if (mask & CLONE_NEWNET) { |
24552 |
++ old_net = nsproxy->net_ns; |
24553 |
++ nsproxy->net_ns = new_nsproxy->net_ns; |
24554 |
++ if (nsproxy->net_ns) |
24555 |
++ get_net(nsproxy->net_ns); |
24556 |
++ } else |
24557 |
++ old_net = NULL; |
24558 |
++#endif |
24559 |
++ if (old_ns) |
24560 |
++ put_mnt_ns(old_ns); |
24561 |
++ if (old_uts) |
24562 |
++ put_uts_ns(old_uts); |
24563 |
++ if (old_ipc) |
24564 |
++ put_ipc_ns(old_ipc); |
24565 |
++#ifdef CONFIG_PID_NS |
24566 |
++ if (old_pid) |
24567 |
++ put_pid_ns(old_pid); |
24568 |
++#endif |
24569 |
++#ifdef CONFIG_NET_NS |
24570 |
++ if (old_net) |
24571 |
++ put_net(old_net); |
24572 |
++#endif |
24573 |
++out: |
24574 |
++ return nsproxy; |
24575 |
++} |
24576 |
++ |
24577 |
++ |
24578 |
++/* |
24579 |
++ * merge two nsproxy structs into a new one. |
24580 |
++ * will hold a reference on the result. |
24581 |
++ */ |
24582 |
++ |
24583 |
++static inline |
24584 |
++struct nsproxy *__vs_merge_nsproxy(struct nsproxy *old, |
24585 |
++ struct nsproxy *proxy, unsigned long mask) |
24586 |
++{ |
24587 |
++ struct nsproxy null_proxy = { .mnt_ns = NULL }; |
24588 |
++ |
24589 |
++ if (!proxy) |
24590 |
++ return NULL; |
24591 |
++ |
24592 |
++ if (mask) { |
24593 |
++ /* vs_mix_nsproxy returns with reference */ |
24594 |
++ return vs_mix_nsproxy(old ? old : &null_proxy, |
24595 |
++ proxy, mask); |
24596 |
++ } |
24597 |
++ get_nsproxy(proxy); |
24598 |
++ return proxy; |
24599 |
++} |
24600 |
++ |
24601 |
++ |
24602 |
++int vx_enter_space(struct vx_info *vxi, unsigned long mask, unsigned index) |
24603 |
++{ |
24604 |
++ struct nsproxy *proxy, *proxy_cur, *proxy_new; |
24605 |
++ struct fs_struct *fs_cur, *fs = NULL; |
24606 |
++ int ret, kill = 0; |
24607 |
++ |
24608 |
++ vxdprintk(VXD_CBIT(space, 8), "vx_enter_space(%p[#%u],0x%08lx,%d)", |
24609 |
++ vxi, vxi->vx_id, mask, index); |
24610 |
++ |
24611 |
++ if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0)) |
24612 |
++ return -EACCES; |
24613 |
++ |
24614 |
++ if (!mask) |
24615 |
++ mask = vxi->vx_nsmask[index]; |
24616 |
++ |
24617 |
++ if ((mask & vxi->vx_nsmask[index]) != mask) |
24618 |
++ return -EINVAL; |
24619 |
++ |
24620 |
++ if (mask & CLONE_FS) { |
24621 |
++ fs = copy_fs_struct(vxi->vx_fs[index]); |
24622 |
++ if (!fs) |
24623 |
++ return -ENOMEM; |
24624 |
++ } |
24625 |
++ proxy = vxi->vx_nsproxy[index]; |
24626 |
++ |
24627 |
++ vxdprintk(VXD_CBIT(space, 9), |
24628 |
++ "vx_enter_space(%p[#%u],0x%08lx,%d) -> (%p,%p)", |
24629 |
++ vxi, vxi->vx_id, mask, index, proxy, fs); |
24630 |
++ |
24631 |
++ task_lock(current); |
24632 |
++ fs_cur = current->fs; |
24633 |
++ |
24634 |
++ if (mask & CLONE_FS) { |
24635 |
++ write_lock(&fs_cur->lock); |
24636 |
++ current->fs = fs; |
24637 |
++ kill = !--fs_cur->users; |
24638 |
++ write_unlock(&fs_cur->lock); |
24639 |
++ } |
24640 |
++ |
24641 |
++ proxy_cur = current->nsproxy; |
24642 |
++ get_nsproxy(proxy_cur); |
24643 |
++ task_unlock(current); |
24644 |
++ |
24645 |
++ if (kill) |
24646 |
++ free_fs_struct(fs_cur); |
24647 |
++ |
24648 |
++ proxy_new = __vs_merge_nsproxy(proxy_cur, proxy, mask); |
24649 |
++ if (IS_ERR(proxy_new)) { |
24650 |
++ ret = PTR_ERR(proxy_new); |
24651 |
++ goto out_put; |
24652 |
++ } |
24653 |
++ |
24654 |
++ proxy_new = xchg(¤t->nsproxy, proxy_new); |
24655 |
++ ret = 0; |
24656 |
++ |
24657 |
++ if (proxy_new) |
24658 |
++ put_nsproxy(proxy_new); |
24659 |
++out_put: |
24660 |
++ if (proxy_cur) |
24661 |
++ put_nsproxy(proxy_cur); |
24662 |
++ return ret; |
24663 |
++} |
24664 |
++ |
24665 |
++ |
24666 |
++int vx_set_space(struct vx_info *vxi, unsigned long mask, unsigned index) |
24667 |
++{ |
24668 |
++ struct nsproxy *proxy_vxi, *proxy_cur, *proxy_new; |
24669 |
++ struct fs_struct *fs_vxi, *fs; |
24670 |
++ int ret, kill = 0; |
24671 |
++ |
24672 |
++ vxdprintk(VXD_CBIT(space, 8), "vx_set_space(%p[#%u],0x%08lx,%d)", |
24673 |
++ vxi, vxi->vx_id, mask, index); |
24674 |
++#if 0 |
24675 |
++ if (!mask) |
24676 |
++ mask = default_space_mask.mask; |
24677 |
++#endif |
24678 |
++ if ((mask & space_mask.mask) != mask) |
24679 |
++ return -EINVAL; |
24680 |
++ |
24681 |
++ proxy_vxi = vxi->vx_nsproxy[index]; |
24682 |
++ fs_vxi = vxi->vx_fs[index]; |
24683 |
++ |
24684 |
++ if (mask & CLONE_FS) { |
24685 |
++ fs = copy_fs_struct(current->fs); |
24686 |
++ if (!fs) |
24687 |
++ return -ENOMEM; |
24688 |
++ } |
24689 |
++ |
24690 |
++ task_lock(current); |
24691 |
++ |
24692 |
++ if (mask & CLONE_FS) { |
24693 |
++ write_lock(&fs_vxi->lock); |
24694 |
++ vxi->vx_fs[index] = fs; |
24695 |
++ kill = !--fs_vxi->users; |
24696 |
++ write_unlock(&fs_vxi->lock); |
24697 |
++ } |
24698 |
++ |
24699 |
++ proxy_cur = current->nsproxy; |
24700 |
++ get_nsproxy(proxy_cur); |
24701 |
++ task_unlock(current); |
24702 |
++ |
24703 |
++ if (kill) |
24704 |
++ free_fs_struct(fs_vxi); |
24705 |
++ |
24706 |
++ proxy_new = __vs_merge_nsproxy(proxy_vxi, proxy_cur, mask); |
24707 |
++ if (IS_ERR(proxy_new)) { |
24708 |
++ ret = PTR_ERR(proxy_new); |
24709 |
++ goto out_put; |
24710 |
++ } |
24711 |
++ |
24712 |
++ proxy_new = xchg(&vxi->vx_nsproxy[index], proxy_new); |
24713 |
++ vxi->vx_nsmask[index] |= mask; |
24714 |
++ ret = 0; |
24715 |
++ |
24716 |
++ if (proxy_new) |
24717 |
++ put_nsproxy(proxy_new); |
24718 |
++out_put: |
24719 |
++ if (proxy_cur) |
24720 |
++ put_nsproxy(proxy_cur); |
24721 |
++ return ret; |
24722 |
++} |
24723 |
++ |
24724 |
++ |
24725 |
++int vc_enter_space_v1(struct vx_info *vxi, void __user *data) |
24726 |
++{ |
24727 |
++ struct vcmd_space_mask_v1 vc_data = { .mask = 0 }; |
24728 |
++ |
24729 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
24730 |
++ return -EFAULT; |
24731 |
++ |
24732 |
++ return vx_enter_space(vxi, vc_data.mask, 0); |
24733 |
++} |
24734 |
++ |
24735 |
++int vc_enter_space(struct vx_info *vxi, void __user *data) |
24736 |
++{ |
24737 |
++ struct vcmd_space_mask_v2 vc_data = { .mask = 0 }; |
24738 |
++ |
24739 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
24740 |
++ return -EFAULT; |
24741 |
++ |
24742 |
++ if (vc_data.index >= VX_SPACES) |
24743 |
++ return -EINVAL; |
24744 |
++ |
24745 |
++ return vx_enter_space(vxi, vc_data.mask, vc_data.index); |
24746 |
++} |
24747 |
++ |
24748 |
++int vc_set_space_v1(struct vx_info *vxi, void __user *data) |
24749 |
++{ |
24750 |
++ struct vcmd_space_mask_v1 vc_data = { .mask = 0 }; |
24751 |
++ |
24752 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
24753 |
++ return -EFAULT; |
24754 |
++ |
24755 |
++ return vx_set_space(vxi, vc_data.mask, 0); |
24756 |
++} |
24757 |
++ |
24758 |
++int vc_set_space(struct vx_info *vxi, void __user *data) |
24759 |
++{ |
24760 |
++ struct vcmd_space_mask_v2 vc_data = { .mask = 0 }; |
24761 |
++ |
24762 |
++ if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) |
24763 |
++ return -EFAULT; |
24764 |
++ |
24765 |
++ if (vc_data.index >= VX_SPACES) |
24766 |
++ return -EINVAL; |
24767 |
++ |
24768 |
++ return vx_set_space(vxi, vc_data.mask, vc_data.index); |
24769 |
++} |
24770 |
++ |
24771 |
++int vc_get_space_mask(void __user *data, int type) |
24772 |
++{ |
24773 |
++ const struct vcmd_space_mask_v1 *mask; |
24774 |
++ |
24775 |
++ if (type == 0) |
24776 |
++ mask = &space_mask_v0; |
24777 |
++ else if (type == 1) |
24778 |
++ mask = &space_mask; |
24779 |
++ else |
24780 |
++ mask = &default_space_mask; |
24781 |
++ |
24782 |
++ vxdprintk(VXD_CBIT(space, 10), |
24783 |
++ "vc_get_space_mask(%d) = %08llx", type, mask->mask); |
24784 |
++ |
24785 |
++ if (copy_to_user(data, mask, sizeof(*mask))) |
24786 |
++ return -EFAULT; |
24787 |
++ return 0; |
24788 |
++} |
24789 |
++ |
24790 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/switch.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/switch.c |
24791 |
+--- linux-2.6.29.4/kernel/vserver/switch.c 1970-01-01 01:00:00.000000000 +0100 |
24792 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/switch.c 2009-03-24 14:59:18.000000000 +0100 |
24793 |
+@@ -0,0 +1,543 @@ |
24794 |
++/* |
24795 |
++ * linux/kernel/vserver/switch.c |
24796 |
++ * |
24797 |
++ * Virtual Server: Syscall Switch |
24798 |
++ * |
24799 |
++ * Copyright (C) 2003-2007 Herbert Pötzl |
24800 |
++ * |
24801 |
++ * V0.01 syscall switch |
24802 |
++ * V0.02 added signal to context |
24803 |
++ * V0.03 added rlimit functions |
24804 |
++ * V0.04 added iattr, task/xid functions |
24805 |
++ * V0.05 added debug/history stuff |
24806 |
++ * V0.06 added compat32 layer |
24807 |
++ * V0.07 vcmd args and perms |
24808 |
++ * V0.08 added status commands |
24809 |
++ * V0.09 added tag commands |
24810 |
++ * V0.10 added oom bias |
24811 |
++ * V0.11 added device commands |
24812 |
++ * |
24813 |
++ */ |
24814 |
++ |
24815 |
++#include <linux/vs_context.h> |
24816 |
++#include <linux/vs_network.h> |
24817 |
++#include <linux/vserver/switch.h> |
24818 |
++ |
24819 |
++#include "vci_config.h" |
24820 |
++ |
24821 |
++ |
24822 |
++static inline |
24823 |
++int vc_get_version(uint32_t id) |
24824 |
++{ |
24825 |
++ return VCI_VERSION; |
24826 |
++} |
24827 |
++ |
24828 |
++static inline |
24829 |
++int vc_get_vci(uint32_t id) |
24830 |
++{ |
24831 |
++ return vci_kernel_config(); |
24832 |
++} |
24833 |
++ |
24834 |
++#include <linux/vserver/context_cmd.h> |
24835 |
++#include <linux/vserver/cvirt_cmd.h> |
24836 |
++#include <linux/vserver/cacct_cmd.h> |
24837 |
++#include <linux/vserver/limit_cmd.h> |
24838 |
++#include <linux/vserver/network_cmd.h> |
24839 |
++#include <linux/vserver/sched_cmd.h> |
24840 |
++#include <linux/vserver/debug_cmd.h> |
24841 |
++#include <linux/vserver/inode_cmd.h> |
24842 |
++#include <linux/vserver/dlimit_cmd.h> |
24843 |
++#include <linux/vserver/signal_cmd.h> |
24844 |
++#include <linux/vserver/space_cmd.h> |
24845 |
++#include <linux/vserver/tag_cmd.h> |
24846 |
++#include <linux/vserver/device_cmd.h> |
24847 |
++ |
24848 |
++#include <linux/vserver/inode.h> |
24849 |
++#include <linux/vserver/dlimit.h> |
24850 |
++ |
24851 |
++ |
24852 |
++#ifdef CONFIG_COMPAT |
24853 |
++#define __COMPAT(name, id, data, compat) \ |
24854 |
++ (compat) ? name ## _x32(id, data) : name(id, data) |
24855 |
++#define __COMPAT_NO_ID(name, data, compat) \ |
24856 |
++ (compat) ? name ## _x32(data) : name(data) |
24857 |
++#else |
24858 |
++#define __COMPAT(name, id, data, compat) \ |
24859 |
++ name(id, data) |
24860 |
++#define __COMPAT_NO_ID(name, data, compat) \ |
24861 |
++ name(data) |
24862 |
++#endif |
24863 |
++ |
24864 |
++ |
24865 |
++static inline |
24866 |
++long do_vcmd(uint32_t cmd, uint32_t id, |
24867 |
++ struct vx_info *vxi, struct nx_info *nxi, |
24868 |
++ void __user *data, int compat) |
24869 |
++{ |
24870 |
++ switch (cmd) { |
24871 |
++ |
24872 |
++ case VCMD_get_version: |
24873 |
++ return vc_get_version(id); |
24874 |
++ case VCMD_get_vci: |
24875 |
++ return vc_get_vci(id); |
24876 |
++ |
24877 |
++ case VCMD_task_xid: |
24878 |
++ return vc_task_xid(id); |
24879 |
++ case VCMD_vx_info: |
24880 |
++ return vc_vx_info(vxi, data); |
24881 |
++ |
24882 |
++ case VCMD_task_nid: |
24883 |
++ return vc_task_nid(id); |
24884 |
++ case VCMD_nx_info: |
24885 |
++ return vc_nx_info(nxi, data); |
24886 |
++ |
24887 |
++ case VCMD_task_tag: |
24888 |
++ return vc_task_tag(id); |
24889 |
++ |
24890 |
++ case VCMD_set_space_v1: |
24891 |
++ return vc_set_space_v1(vxi, data); |
24892 |
++ /* this is version 2 */ |
24893 |
++ case VCMD_set_space: |
24894 |
++ return vc_set_space(vxi, data); |
24895 |
++ |
24896 |
++ case VCMD_get_space_mask_v0: |
24897 |
++ return vc_get_space_mask(data, 0); |
24898 |
++ /* this is version 1 */ |
24899 |
++ case VCMD_get_space_mask: |
24900 |
++ return vc_get_space_mask(data, 1); |
24901 |
++ |
24902 |
++ case VCMD_get_space_default: |
24903 |
++ return vc_get_space_mask(data, -1); |
24904 |
++ |
24905 |
++#ifdef CONFIG_IA32_EMULATION |
24906 |
++ case VCMD_get_rlimit: |
24907 |
++ return __COMPAT(vc_get_rlimit, vxi, data, compat); |
24908 |
++ case VCMD_set_rlimit: |
24909 |
++ return __COMPAT(vc_set_rlimit, vxi, data, compat); |
24910 |
++#else |
24911 |
++ case VCMD_get_rlimit: |
24912 |
++ return vc_get_rlimit(vxi, data); |
24913 |
++ case VCMD_set_rlimit: |
24914 |
++ return vc_set_rlimit(vxi, data); |
24915 |
++#endif |
24916 |
++ case VCMD_get_rlimit_mask: |
24917 |
++ return vc_get_rlimit_mask(id, data); |
24918 |
++ case VCMD_reset_minmax: |
24919 |
++ return vc_reset_minmax(vxi, data); |
24920 |
++ |
24921 |
++ case VCMD_get_vhi_name: |
24922 |
++ return vc_get_vhi_name(vxi, data); |
24923 |
++ case VCMD_set_vhi_name: |
24924 |
++ return vc_set_vhi_name(vxi, data); |
24925 |
++ |
24926 |
++ case VCMD_ctx_stat: |
24927 |
++ return vc_ctx_stat(vxi, data); |
24928 |
++ case VCMD_virt_stat: |
24929 |
++ return vc_virt_stat(vxi, data); |
24930 |
++ case VCMD_sock_stat: |
24931 |
++ return vc_sock_stat(vxi, data); |
24932 |
++ case VCMD_rlimit_stat: |
24933 |
++ return vc_rlimit_stat(vxi, data); |
24934 |
++ |
24935 |
++ case VCMD_set_cflags: |
24936 |
++ return vc_set_cflags(vxi, data); |
24937 |
++ case VCMD_get_cflags: |
24938 |
++ return vc_get_cflags(vxi, data); |
24939 |
++ |
24940 |
++ /* this is version 1 */ |
24941 |
++ case VCMD_set_ccaps: |
24942 |
++ return vc_set_ccaps(vxi, data); |
24943 |
++ /* this is version 1 */ |
24944 |
++ case VCMD_get_ccaps: |
24945 |
++ return vc_get_ccaps(vxi, data); |
24946 |
++ case VCMD_set_bcaps: |
24947 |
++ return vc_set_bcaps(vxi, data); |
24948 |
++ case VCMD_get_bcaps: |
24949 |
++ return vc_get_bcaps(vxi, data); |
24950 |
++ |
24951 |
++ case VCMD_set_badness: |
24952 |
++ return vc_set_badness(vxi, data); |
24953 |
++ case VCMD_get_badness: |
24954 |
++ return vc_get_badness(vxi, data); |
24955 |
++ |
24956 |
++ case VCMD_set_nflags: |
24957 |
++ return vc_set_nflags(nxi, data); |
24958 |
++ case VCMD_get_nflags: |
24959 |
++ return vc_get_nflags(nxi, data); |
24960 |
++ |
24961 |
++ case VCMD_set_ncaps: |
24962 |
++ return vc_set_ncaps(nxi, data); |
24963 |
++ case VCMD_get_ncaps: |
24964 |
++ return vc_get_ncaps(nxi, data); |
24965 |
++ |
24966 |
++ case VCMD_set_sched_v4: |
24967 |
++ return vc_set_sched_v4(vxi, data); |
24968 |
++ /* this is version 5 */ |
24969 |
++ case VCMD_set_sched: |
24970 |
++ return vc_set_sched(vxi, data); |
24971 |
++ case VCMD_get_sched: |
24972 |
++ return vc_get_sched(vxi, data); |
24973 |
++ case VCMD_sched_info: |
24974 |
++ return vc_sched_info(vxi, data); |
24975 |
++ |
24976 |
++ case VCMD_add_dlimit: |
24977 |
++ return __COMPAT(vc_add_dlimit, id, data, compat); |
24978 |
++ case VCMD_rem_dlimit: |
24979 |
++ return __COMPAT(vc_rem_dlimit, id, data, compat); |
24980 |
++ case VCMD_set_dlimit: |
24981 |
++ return __COMPAT(vc_set_dlimit, id, data, compat); |
24982 |
++ case VCMD_get_dlimit: |
24983 |
++ return __COMPAT(vc_get_dlimit, id, data, compat); |
24984 |
++ |
24985 |
++ case VCMD_ctx_kill: |
24986 |
++ return vc_ctx_kill(vxi, data); |
24987 |
++ |
24988 |
++ case VCMD_wait_exit: |
24989 |
++ return vc_wait_exit(vxi, data); |
24990 |
++ |
24991 |
++ case VCMD_get_iattr: |
24992 |
++ return __COMPAT_NO_ID(vc_get_iattr, data, compat); |
24993 |
++ case VCMD_set_iattr: |
24994 |
++ return __COMPAT_NO_ID(vc_set_iattr, data, compat); |
24995 |
++ |
24996 |
++ case VCMD_fget_iattr: |
24997 |
++ return vc_fget_iattr(id, data); |
24998 |
++ case VCMD_fset_iattr: |
24999 |
++ return vc_fset_iattr(id, data); |
25000 |
++ |
25001 |
++ case VCMD_enter_space_v0: |
25002 |
++ return vc_enter_space_v1(vxi, NULL); |
25003 |
++ case VCMD_enter_space_v1: |
25004 |
++ return vc_enter_space_v1(vxi, data); |
25005 |
++ /* this is version 2 */ |
25006 |
++ case VCMD_enter_space: |
25007 |
++ return vc_enter_space(vxi, data); |
25008 |
++ |
25009 |
++ case VCMD_ctx_create_v0: |
25010 |
++ return vc_ctx_create(id, NULL); |
25011 |
++ case VCMD_ctx_create: |
25012 |
++ return vc_ctx_create(id, data); |
25013 |
++ case VCMD_ctx_migrate_v0: |
25014 |
++ return vc_ctx_migrate(vxi, NULL); |
25015 |
++ case VCMD_ctx_migrate: |
25016 |
++ return vc_ctx_migrate(vxi, data); |
25017 |
++ |
25018 |
++ case VCMD_net_create_v0: |
25019 |
++ return vc_net_create(id, NULL); |
25020 |
++ case VCMD_net_create: |
25021 |
++ return vc_net_create(id, data); |
25022 |
++ case VCMD_net_migrate: |
25023 |
++ return vc_net_migrate(nxi, data); |
25024 |
++ |
25025 |
++ case VCMD_tag_migrate: |
25026 |
++ return vc_tag_migrate(id); |
25027 |
++ |
25028 |
++ case VCMD_net_add: |
25029 |
++ return vc_net_add(nxi, data); |
25030 |
++ case VCMD_net_remove: |
25031 |
++ return vc_net_remove(nxi, data); |
25032 |
++ |
25033 |
++ case VCMD_net_add_ipv4: |
25034 |
++ return vc_net_add_ipv4(nxi, data); |
25035 |
++ case VCMD_net_remove_ipv4: |
25036 |
++ return vc_net_remove_ipv4(nxi, data); |
25037 |
++#ifdef CONFIG_IPV6 |
25038 |
++ case VCMD_net_add_ipv6: |
25039 |
++ return vc_net_add_ipv6(nxi, data); |
25040 |
++ case VCMD_net_remove_ipv6: |
25041 |
++ return vc_net_remove_ipv6(nxi, data); |
25042 |
++#endif |
25043 |
++/* case VCMD_add_match_ipv4: |
25044 |
++ return vc_add_match_ipv4(nxi, data); |
25045 |
++ case VCMD_get_match_ipv4: |
25046 |
++ return vc_get_match_ipv4(nxi, data); |
25047 |
++#ifdef CONFIG_IPV6 |
25048 |
++ case VCMD_add_match_ipv6: |
25049 |
++ return vc_add_match_ipv6(nxi, data); |
25050 |
++ case VCMD_get_match_ipv6: |
25051 |
++ return vc_get_match_ipv6(nxi, data); |
25052 |
++#endif */ |
25053 |
++ |
25054 |
++#ifdef CONFIG_VSERVER_DEVICE |
25055 |
++ case VCMD_set_mapping: |
25056 |
++ return __COMPAT(vc_set_mapping, vxi, data, compat); |
25057 |
++ case VCMD_unset_mapping: |
25058 |
++ return __COMPAT(vc_unset_mapping, vxi, data, compat); |
25059 |
++#endif |
25060 |
++#ifdef CONFIG_VSERVER_HISTORY |
25061 |
++ case VCMD_dump_history: |
25062 |
++ return vc_dump_history(id); |
25063 |
++ case VCMD_read_history: |
25064 |
++ return __COMPAT(vc_read_history, id, data, compat); |
25065 |
++#endif |
25066 |
++#ifdef CONFIG_VSERVER_MONITOR |
25067 |
++ case VCMD_read_monitor: |
25068 |
++ return __COMPAT(vc_read_monitor, id, data, compat); |
25069 |
++#endif |
25070 |
++ default: |
25071 |
++ vxwprintk_task(1, "unimplemented VCMD_%02d_%d[%d]", |
25072 |
++ VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd)); |
25073 |
++ } |
25074 |
++ return -ENOSYS; |
25075 |
++} |
25076 |
++ |
25077 |
++ |
25078 |
++#define __VCMD(vcmd, _perm, _args, _flags) \ |
25079 |
++ case VCMD_ ## vcmd: perm = _perm; \ |
25080 |
++ args = _args; flags = _flags; break |
25081 |
++ |
25082 |
++ |
25083 |
++#define VCA_NONE 0x00 |
25084 |
++#define VCA_VXI 0x01 |
25085 |
++#define VCA_NXI 0x02 |
25086 |
++ |
25087 |
++#define VCF_NONE 0x00 |
25088 |
++#define VCF_INFO 0x01 |
25089 |
++#define VCF_ADMIN 0x02 |
25090 |
++#define VCF_ARES 0x06 /* includes admin */ |
25091 |
++#define VCF_SETUP 0x08 |
25092 |
++ |
25093 |
++#define VCF_ZIDOK 0x10 /* zero id okay */ |
25094 |
++ |
25095 |
++ |
25096 |
++static inline |
25097 |
++long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat) |
25098 |
++{ |
25099 |
++ long ret; |
25100 |
++ int permit = -1, state = 0; |
25101 |
++ int perm = -1, args = 0, flags = 0; |
25102 |
++ struct vx_info *vxi = NULL; |
25103 |
++ struct nx_info *nxi = NULL; |
25104 |
++ |
25105 |
++ switch (cmd) { |
25106 |
++ /* unpriviledged commands */ |
25107 |
++ __VCMD(get_version, 0, VCA_NONE, 0); |
25108 |
++ __VCMD(get_vci, 0, VCA_NONE, 0); |
25109 |
++ __VCMD(get_rlimit_mask, 0, VCA_NONE, 0); |
25110 |
++ __VCMD(get_space_mask_v0,0, VCA_NONE, 0); |
25111 |
++ __VCMD(get_space_mask, 0, VCA_NONE, 0); |
25112 |
++ __VCMD(get_space_default,0, VCA_NONE, 0); |
25113 |
++ |
25114 |
++ /* info commands */ |
25115 |
++ __VCMD(task_xid, 2, VCA_NONE, 0); |
25116 |
++ __VCMD(reset_minmax, 2, VCA_VXI, 0); |
25117 |
++ __VCMD(vx_info, 3, VCA_VXI, VCF_INFO); |
25118 |
++ __VCMD(get_bcaps, 3, VCA_VXI, VCF_INFO); |
25119 |
++ __VCMD(get_ccaps, 3, VCA_VXI, VCF_INFO); |
25120 |
++ __VCMD(get_cflags, 3, VCA_VXI, VCF_INFO); |
25121 |
++ __VCMD(get_badness, 3, VCA_VXI, VCF_INFO); |
25122 |
++ __VCMD(get_vhi_name, 3, VCA_VXI, VCF_INFO); |
25123 |
++ __VCMD(get_rlimit, 3, VCA_VXI, VCF_INFO); |
25124 |
++ |
25125 |
++ __VCMD(ctx_stat, 3, VCA_VXI, VCF_INFO); |
25126 |
++ __VCMD(virt_stat, 3, VCA_VXI, VCF_INFO); |
25127 |
++ __VCMD(sock_stat, 3, VCA_VXI, VCF_INFO); |
25128 |
++ __VCMD(rlimit_stat, 3, VCA_VXI, VCF_INFO); |
25129 |
++ |
25130 |
++ __VCMD(task_nid, 2, VCA_NONE, 0); |
25131 |
++ __VCMD(nx_info, 3, VCA_NXI, VCF_INFO); |
25132 |
++ __VCMD(get_ncaps, 3, VCA_NXI, VCF_INFO); |
25133 |
++ __VCMD(get_nflags, 3, VCA_NXI, VCF_INFO); |
25134 |
++ |
25135 |
++ __VCMD(task_tag, 2, VCA_NONE, 0); |
25136 |
++ |
25137 |
++ __VCMD(get_iattr, 2, VCA_NONE, 0); |
25138 |
++ __VCMD(fget_iattr, 2, VCA_NONE, 0); |
25139 |
++ __VCMD(get_dlimit, 3, VCA_NONE, VCF_INFO); |
25140 |
++ __VCMD(get_sched, 3, VCA_VXI, VCF_INFO); |
25141 |
++ __VCMD(sched_info, 3, VCA_VXI, VCF_INFO | VCF_ZIDOK); |
25142 |
++ |
25143 |
++ /* lower admin commands */ |
25144 |
++ __VCMD(wait_exit, 4, VCA_VXI, VCF_INFO); |
25145 |
++ __VCMD(ctx_create_v0, 5, VCA_NONE, 0); |
25146 |
++ __VCMD(ctx_create, 5, VCA_NONE, 0); |
25147 |
++ __VCMD(ctx_migrate_v0, 5, VCA_VXI, VCF_ADMIN); |
25148 |
++ __VCMD(ctx_migrate, 5, VCA_VXI, VCF_ADMIN); |
25149 |
++ __VCMD(enter_space_v0, 5, VCA_VXI, VCF_ADMIN); |
25150 |
++ __VCMD(enter_space_v1, 5, VCA_VXI, VCF_ADMIN); |
25151 |
++ __VCMD(enter_space, 5, VCA_VXI, VCF_ADMIN); |
25152 |
++ |
25153 |
++ __VCMD(net_create_v0, 5, VCA_NONE, 0); |
25154 |
++ __VCMD(net_create, 5, VCA_NONE, 0); |
25155 |
++ __VCMD(net_migrate, 5, VCA_NXI, VCF_ADMIN); |
25156 |
++ |
25157 |
++ __VCMD(tag_migrate, 5, VCA_NONE, VCF_ADMIN); |
25158 |
++ |
25159 |
++ /* higher admin commands */ |
25160 |
++ __VCMD(ctx_kill, 6, VCA_VXI, VCF_ARES); |
25161 |
++ __VCMD(set_space_v1, 7, VCA_VXI, VCF_ARES | VCF_SETUP); |
25162 |
++ __VCMD(set_space, 7, VCA_VXI, VCF_ARES | VCF_SETUP); |
25163 |
++ |
25164 |
++ __VCMD(set_ccaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP); |
25165 |
++ __VCMD(set_bcaps, 7, VCA_VXI, VCF_ARES | VCF_SETUP); |
25166 |
++ __VCMD(set_cflags, 7, VCA_VXI, VCF_ARES | VCF_SETUP); |
25167 |
++ __VCMD(set_badness, 7, VCA_VXI, VCF_ARES | VCF_SETUP); |
25168 |
++ |
25169 |
++ __VCMD(set_vhi_name, 7, VCA_VXI, VCF_ARES | VCF_SETUP); |
25170 |
++ __VCMD(set_rlimit, 7, VCA_VXI, VCF_ARES | VCF_SETUP); |
25171 |
++ __VCMD(set_sched, 7, VCA_VXI, VCF_ARES | VCF_SETUP); |
25172 |
++ __VCMD(set_sched_v4, 7, VCA_VXI, VCF_ARES | VCF_SETUP); |
25173 |
++ |
25174 |
++ __VCMD(set_ncaps, 7, VCA_NXI, VCF_ARES | VCF_SETUP); |
25175 |
++ __VCMD(set_nflags, 7, VCA_NXI, VCF_ARES | VCF_SETUP); |
25176 |
++ __VCMD(net_add, 8, VCA_NXI, VCF_ARES | VCF_SETUP); |
25177 |
++ __VCMD(net_remove, 8, VCA_NXI, VCF_ARES | VCF_SETUP); |
25178 |
++ __VCMD(net_add_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP); |
25179 |
++ __VCMD(net_remove_ipv4, 8, VCA_NXI, VCF_ARES | VCF_SETUP); |
25180 |
++#ifdef CONFIG_IPV6 |
25181 |
++ __VCMD(net_add_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP); |
25182 |
++ __VCMD(net_remove_ipv6, 8, VCA_NXI, VCF_ARES | VCF_SETUP); |
25183 |
++#endif |
25184 |
++ __VCMD(set_iattr, 7, VCA_NONE, 0); |
25185 |
++ __VCMD(fset_iattr, 7, VCA_NONE, 0); |
25186 |
++ __VCMD(set_dlimit, 7, VCA_NONE, VCF_ARES); |
25187 |
++ __VCMD(add_dlimit, 8, VCA_NONE, VCF_ARES); |
25188 |
++ __VCMD(rem_dlimit, 8, VCA_NONE, VCF_ARES); |
25189 |
++ |
25190 |
++#ifdef CONFIG_VSERVER_DEVICE |
25191 |
++ __VCMD(set_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK); |
25192 |
++ __VCMD(unset_mapping, 8, VCA_VXI, VCF_ARES|VCF_ZIDOK); |
25193 |
++#endif |
25194 |
++ /* debug level admin commands */ |
25195 |
++#ifdef CONFIG_VSERVER_HISTORY |
25196 |
++ __VCMD(dump_history, 9, VCA_NONE, 0); |
25197 |
++ __VCMD(read_history, 9, VCA_NONE, 0); |
25198 |
++#endif |
25199 |
++#ifdef CONFIG_VSERVER_MONITOR |
25200 |
++ __VCMD(read_monitor, 9, VCA_NONE, 0); |
25201 |
++#endif |
25202 |
++ |
25203 |
++ default: |
25204 |
++ perm = -1; |
25205 |
++ } |
25206 |
++ |
25207 |
++ vxdprintk(VXD_CBIT(switch, 0), |
25208 |
++ "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]", |
25209 |
++ VC_CATEGORY(cmd), VC_COMMAND(cmd), |
25210 |
++ VC_VERSION(cmd), id, data, compat, |
25211 |
++ perm, args, flags); |
25212 |
++ |
25213 |
++ ret = -ENOSYS; |
25214 |
++ if (perm < 0) |
25215 |
++ goto out; |
25216 |
++ |
25217 |
++ state = 1; |
25218 |
++ if (!capable(CAP_CONTEXT)) |
25219 |
++ goto out; |
25220 |
++ |
25221 |
++ state = 2; |
25222 |
++ /* moved here from the individual commands */ |
25223 |
++ ret = -EPERM; |
25224 |
++ if ((perm > 1) && !capable(CAP_SYS_ADMIN)) |
25225 |
++ goto out; |
25226 |
++ |
25227 |
++ state = 3; |
25228 |
++ /* vcmd involves resource management */ |
25229 |
++ ret = -EPERM; |
25230 |
++ if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE)) |
25231 |
++ goto out; |
25232 |
++ |
25233 |
++ state = 4; |
25234 |
++ /* various legacy exceptions */ |
25235 |
++ switch (cmd) { |
25236 |
++ /* will go away when spectator is a cap */ |
25237 |
++ case VCMD_ctx_migrate_v0: |
25238 |
++ case VCMD_ctx_migrate: |
25239 |
++ if (id == 1) { |
25240 |
++ current->xid = 1; |
25241 |
++ ret = 1; |
25242 |
++ goto out; |
25243 |
++ } |
25244 |
++ break; |
25245 |
++ |
25246 |
++ /* will go away when spectator is a cap */ |
25247 |
++ case VCMD_net_migrate: |
25248 |
++ if (id == 1) { |
25249 |
++ current->nid = 1; |
25250 |
++ ret = 1; |
25251 |
++ goto out; |
25252 |
++ } |
25253 |
++ break; |
25254 |
++ } |
25255 |
++ |
25256 |
++ /* vcmds are fine by default */ |
25257 |
++ permit = 1; |
25258 |
++ |
25259 |
++ /* admin type vcmds require admin ... */ |
25260 |
++ if (flags & VCF_ADMIN) |
25261 |
++ permit = vx_check(0, VS_ADMIN) ? 1 : 0; |
25262 |
++ |
25263 |
++ /* ... but setup type vcmds override that */ |
25264 |
++ if (!permit && (flags & VCF_SETUP)) |
25265 |
++ permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0; |
25266 |
++ |
25267 |
++ state = 5; |
25268 |
++ ret = -EPERM; |
25269 |
++ if (!permit) |
25270 |
++ goto out; |
25271 |
++ |
25272 |
++ state = 6; |
25273 |
++ if (!id && (flags & VCF_ZIDOK)) |
25274 |
++ goto skip_id; |
25275 |
++ |
25276 |
++ ret = -ESRCH; |
25277 |
++ if (args & VCA_VXI) { |
25278 |
++ vxi = lookup_vx_info(id); |
25279 |
++ if (!vxi) |
25280 |
++ goto out; |
25281 |
++ |
25282 |
++ if ((flags & VCF_ADMIN) && |
25283 |
++ /* special case kill for shutdown */ |
25284 |
++ (cmd != VCMD_ctx_kill) && |
25285 |
++ /* can context be administrated? */ |
25286 |
++ !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) { |
25287 |
++ ret = -EACCES; |
25288 |
++ goto out_vxi; |
25289 |
++ } |
25290 |
++ } |
25291 |
++ state = 7; |
25292 |
++ if (args & VCA_NXI) { |
25293 |
++ nxi = lookup_nx_info(id); |
25294 |
++ if (!nxi) |
25295 |
++ goto out_vxi; |
25296 |
++ |
25297 |
++ if ((flags & VCF_ADMIN) && |
25298 |
++ /* can context be administrated? */ |
25299 |
++ !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) { |
25300 |
++ ret = -EACCES; |
25301 |
++ goto out_nxi; |
25302 |
++ } |
25303 |
++ } |
25304 |
++skip_id: |
25305 |
++ state = 8; |
25306 |
++ ret = do_vcmd(cmd, id, vxi, nxi, data, compat); |
25307 |
++ |
25308 |
++out_nxi: |
25309 |
++ if ((args & VCA_NXI) && nxi) |
25310 |
++ put_nx_info(nxi); |
25311 |
++out_vxi: |
25312 |
++ if ((args & VCA_VXI) && vxi) |
25313 |
++ put_vx_info(vxi); |
25314 |
++out: |
25315 |
++ vxdprintk(VXD_CBIT(switch, 1), |
25316 |
++ "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]", |
25317 |
++ VC_CATEGORY(cmd), VC_COMMAND(cmd), |
25318 |
++ VC_VERSION(cmd), ret, ret, state, permit); |
25319 |
++ return ret; |
25320 |
++} |
25321 |
++ |
25322 |
++asmlinkage long |
25323 |
++sys_vserver(uint32_t cmd, uint32_t id, void __user *data) |
25324 |
++{ |
25325 |
++ return do_vserver(cmd, id, data, 0); |
25326 |
++} |
25327 |
++ |
25328 |
++#ifdef CONFIG_COMPAT |
25329 |
++ |
25330 |
++asmlinkage long |
25331 |
++sys32_vserver(uint32_t cmd, uint32_t id, void __user *data) |
25332 |
++{ |
25333 |
++ return do_vserver(cmd, id, data, 1); |
25334 |
++} |
25335 |
++ |
25336 |
++#endif /* CONFIG_COMPAT */ |
25337 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/sysctl.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/sysctl.c |
25338 |
+--- linux-2.6.29.4/kernel/vserver/sysctl.c 1970-01-01 01:00:00.000000000 +0100 |
25339 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/sysctl.c 2009-02-22 22:54:26.000000000 +0100 |
25340 |
+@@ -0,0 +1,244 @@ |
25341 |
++/* |
25342 |
++ * kernel/vserver/sysctl.c |
25343 |
++ * |
25344 |
++ * Virtual Context Support |
25345 |
++ * |
25346 |
++ * Copyright (C) 2004-2007 Herbert Pötzl |
25347 |
++ * |
25348 |
++ * V0.01 basic structure |
25349 |
++ * |
25350 |
++ */ |
25351 |
++ |
25352 |
++#include <linux/module.h> |
25353 |
++#include <linux/ctype.h> |
25354 |
++#include <linux/sysctl.h> |
25355 |
++#include <linux/parser.h> |
25356 |
++#include <asm/uaccess.h> |
25357 |
++ |
25358 |
++ |
25359 |
++enum { |
25360 |
++ CTL_DEBUG_ERROR = 0, |
25361 |
++ CTL_DEBUG_SWITCH = 1, |
25362 |
++ CTL_DEBUG_XID, |
25363 |
++ CTL_DEBUG_NID, |
25364 |
++ CTL_DEBUG_TAG, |
25365 |
++ CTL_DEBUG_NET, |
25366 |
++ CTL_DEBUG_LIMIT, |
25367 |
++ CTL_DEBUG_CRES, |
25368 |
++ CTL_DEBUG_DLIM, |
25369 |
++ CTL_DEBUG_QUOTA, |
25370 |
++ CTL_DEBUG_CVIRT, |
25371 |
++ CTL_DEBUG_SPACE, |
25372 |
++ CTL_DEBUG_MISC, |
25373 |
++}; |
25374 |
++ |
25375 |
++ |
25376 |
++unsigned int vx_debug_switch = 0; |
25377 |
++unsigned int vx_debug_xid = 0; |
25378 |
++unsigned int vx_debug_nid = 0; |
25379 |
++unsigned int vx_debug_tag = 0; |
25380 |
++unsigned int vx_debug_net = 0; |
25381 |
++unsigned int vx_debug_limit = 0; |
25382 |
++unsigned int vx_debug_cres = 0; |
25383 |
++unsigned int vx_debug_dlim = 0; |
25384 |
++unsigned int vx_debug_quota = 0; |
25385 |
++unsigned int vx_debug_cvirt = 0; |
25386 |
++unsigned int vx_debug_space = 0; |
25387 |
++unsigned int vx_debug_misc = 0; |
25388 |
++ |
25389 |
++ |
25390 |
++static struct ctl_table_header *vserver_table_header; |
25391 |
++static ctl_table vserver_root_table[]; |
25392 |
++ |
25393 |
++ |
25394 |
++void vserver_register_sysctl(void) |
25395 |
++{ |
25396 |
++ if (!vserver_table_header) { |
25397 |
++ vserver_table_header = register_sysctl_table(vserver_root_table); |
25398 |
++ } |
25399 |
++ |
25400 |
++} |
25401 |
++ |
25402 |
++void vserver_unregister_sysctl(void) |
25403 |
++{ |
25404 |
++ if (vserver_table_header) { |
25405 |
++ unregister_sysctl_table(vserver_table_header); |
25406 |
++ vserver_table_header = NULL; |
25407 |
++ } |
25408 |
++} |
25409 |
++ |
25410 |
++ |
25411 |
++static int proc_dodebug(ctl_table *table, int write, |
25412 |
++ struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) |
25413 |
++{ |
25414 |
++ char tmpbuf[20], *p, c; |
25415 |
++ unsigned int value; |
25416 |
++ size_t left, len; |
25417 |
++ |
25418 |
++ if ((*ppos && !write) || !*lenp) { |
25419 |
++ *lenp = 0; |
25420 |
++ return 0; |
25421 |
++ } |
25422 |
++ |
25423 |
++ left = *lenp; |
25424 |
++ |
25425 |
++ if (write) { |
25426 |
++ if (!access_ok(VERIFY_READ, buffer, left)) |
25427 |
++ return -EFAULT; |
25428 |
++ p = (char *)buffer; |
25429 |
++ while (left && __get_user(c, p) >= 0 && isspace(c)) |
25430 |
++ left--, p++; |
25431 |
++ if (!left) |
25432 |
++ goto done; |
25433 |
++ |
25434 |
++ if (left > sizeof(tmpbuf) - 1) |
25435 |
++ return -EINVAL; |
25436 |
++ if (copy_from_user(tmpbuf, p, left)) |
25437 |
++ return -EFAULT; |
25438 |
++ tmpbuf[left] = '\0'; |
25439 |
++ |
25440 |
++ for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--) |
25441 |
++ value = 10 * value + (*p - '0'); |
25442 |
++ if (*p && !isspace(*p)) |
25443 |
++ return -EINVAL; |
25444 |
++ while (left && isspace(*p)) |
25445 |
++ left--, p++; |
25446 |
++ *(unsigned int *)table->data = value; |
25447 |
++ } else { |
25448 |
++ if (!access_ok(VERIFY_WRITE, buffer, left)) |
25449 |
++ return -EFAULT; |
25450 |
++ len = sprintf(tmpbuf, "%d", *(unsigned int *)table->data); |
25451 |
++ if (len > left) |
25452 |
++ len = left; |
25453 |
++ if (__copy_to_user(buffer, tmpbuf, len)) |
25454 |
++ return -EFAULT; |
25455 |
++ if ((left -= len) > 0) { |
25456 |
++ if (put_user('\n', (char *)buffer + len)) |
25457 |
++ return -EFAULT; |
25458 |
++ left--; |
25459 |
++ } |
25460 |
++ } |
25461 |
++ |
25462 |
++done: |
25463 |
++ *lenp -= left; |
25464 |
++ *ppos += *lenp; |
25465 |
++ return 0; |
25466 |
++} |
25467 |
++ |
25468 |
++static int zero; |
25469 |
++ |
25470 |
++#define CTL_ENTRY(ctl, name) \ |
25471 |
++ { \ |
25472 |
++ .ctl_name = ctl, \ |
25473 |
++ .procname = #name, \ |
25474 |
++ .data = &vx_ ## name, \ |
25475 |
++ .maxlen = sizeof(int), \ |
25476 |
++ .mode = 0644, \ |
25477 |
++ .proc_handler = &proc_dodebug, \ |
25478 |
++ .strategy = &sysctl_intvec, \ |
25479 |
++ .extra1 = &zero, \ |
25480 |
++ } |
25481 |
++ |
25482 |
++static ctl_table vserver_debug_table[] = { |
25483 |
++ CTL_ENTRY(CTL_DEBUG_SWITCH, debug_switch), |
25484 |
++ CTL_ENTRY(CTL_DEBUG_XID, debug_xid), |
25485 |
++ CTL_ENTRY(CTL_DEBUG_NID, debug_nid), |
25486 |
++ CTL_ENTRY(CTL_DEBUG_TAG, debug_tag), |
25487 |
++ CTL_ENTRY(CTL_DEBUG_NET, debug_net), |
25488 |
++ CTL_ENTRY(CTL_DEBUG_LIMIT, debug_limit), |
25489 |
++ CTL_ENTRY(CTL_DEBUG_CRES, debug_cres), |
25490 |
++ CTL_ENTRY(CTL_DEBUG_DLIM, debug_dlim), |
25491 |
++ CTL_ENTRY(CTL_DEBUG_QUOTA, debug_quota), |
25492 |
++ CTL_ENTRY(CTL_DEBUG_CVIRT, debug_cvirt), |
25493 |
++ CTL_ENTRY(CTL_DEBUG_SPACE, debug_space), |
25494 |
++ CTL_ENTRY(CTL_DEBUG_MISC, debug_misc), |
25495 |
++ { .ctl_name = 0 } |
25496 |
++}; |
25497 |
++ |
25498 |
++static ctl_table vserver_root_table[] = { |
25499 |
++ { |
25500 |
++ .ctl_name = CTL_VSERVER, |
25501 |
++ .procname = "vserver", |
25502 |
++ .mode = 0555, |
25503 |
++ .child = vserver_debug_table |
25504 |
++ }, |
25505 |
++ { .ctl_name = 0 } |
25506 |
++}; |
25507 |
++ |
25508 |
++ |
25509 |
++static match_table_t tokens = { |
25510 |
++ { CTL_DEBUG_SWITCH, "switch=%x" }, |
25511 |
++ { CTL_DEBUG_XID, "xid=%x" }, |
25512 |
++ { CTL_DEBUG_NID, "nid=%x" }, |
25513 |
++ { CTL_DEBUG_TAG, "tag=%x" }, |
25514 |
++ { CTL_DEBUG_NET, "net=%x" }, |
25515 |
++ { CTL_DEBUG_LIMIT, "limit=%x" }, |
25516 |
++ { CTL_DEBUG_CRES, "cres=%x" }, |
25517 |
++ { CTL_DEBUG_DLIM, "dlim=%x" }, |
25518 |
++ { CTL_DEBUG_QUOTA, "quota=%x" }, |
25519 |
++ { CTL_DEBUG_CVIRT, "cvirt=%x" }, |
25520 |
++ { CTL_DEBUG_SPACE, "space=%x" }, |
25521 |
++ { CTL_DEBUG_MISC, "misc=%x" }, |
25522 |
++ { CTL_DEBUG_ERROR, NULL } |
25523 |
++}; |
25524 |
++ |
25525 |
++#define HANDLE_CASE(id, name, val) \ |
25526 |
++ case CTL_DEBUG_ ## id: \ |
25527 |
++ vx_debug_ ## name = val; \ |
25528 |
++ printk("vs_debug_" #name "=0x%x\n", val); \ |
25529 |
++ break |
25530 |
++ |
25531 |
++ |
25532 |
++static int __init vs_debug_setup(char *str) |
25533 |
++{ |
25534 |
++ char *p; |
25535 |
++ int token; |
25536 |
++ |
25537 |
++ printk("vs_debug_setup(%s)\n", str); |
25538 |
++ while ((p = strsep(&str, ",")) != NULL) { |
25539 |
++ substring_t args[MAX_OPT_ARGS]; |
25540 |
++ unsigned int value; |
25541 |
++ |
25542 |
++ if (!*p) |
25543 |
++ continue; |
25544 |
++ |
25545 |
++ token = match_token(p, tokens, args); |
25546 |
++ value = (token > 0) ? simple_strtoul(args[0].from, NULL, 0) : 0; |
25547 |
++ |
25548 |
++ switch (token) { |
25549 |
++ HANDLE_CASE(SWITCH, switch, value); |
25550 |
++ HANDLE_CASE(XID, xid, value); |
25551 |
++ HANDLE_CASE(NID, nid, value); |
25552 |
++ HANDLE_CASE(TAG, tag, value); |
25553 |
++ HANDLE_CASE(NET, net, value); |
25554 |
++ HANDLE_CASE(LIMIT, limit, value); |
25555 |
++ HANDLE_CASE(CRES, cres, value); |
25556 |
++ HANDLE_CASE(DLIM, dlim, value); |
25557 |
++ HANDLE_CASE(QUOTA, quota, value); |
25558 |
++ HANDLE_CASE(CVIRT, cvirt, value); |
25559 |
++ HANDLE_CASE(SPACE, space, value); |
25560 |
++ HANDLE_CASE(MISC, misc, value); |
25561 |
++ default: |
25562 |
++ return -EINVAL; |
25563 |
++ break; |
25564 |
++ } |
25565 |
++ } |
25566 |
++ return 1; |
25567 |
++} |
25568 |
++ |
25569 |
++__setup("vsdebug=", vs_debug_setup); |
25570 |
++ |
25571 |
++ |
25572 |
++ |
25573 |
++EXPORT_SYMBOL_GPL(vx_debug_switch); |
25574 |
++EXPORT_SYMBOL_GPL(vx_debug_xid); |
25575 |
++EXPORT_SYMBOL_GPL(vx_debug_nid); |
25576 |
++EXPORT_SYMBOL_GPL(vx_debug_net); |
25577 |
++EXPORT_SYMBOL_GPL(vx_debug_limit); |
25578 |
++EXPORT_SYMBOL_GPL(vx_debug_cres); |
25579 |
++EXPORT_SYMBOL_GPL(vx_debug_dlim); |
25580 |
++EXPORT_SYMBOL_GPL(vx_debug_quota); |
25581 |
++EXPORT_SYMBOL_GPL(vx_debug_cvirt); |
25582 |
++EXPORT_SYMBOL_GPL(vx_debug_space); |
25583 |
++EXPORT_SYMBOL_GPL(vx_debug_misc); |
25584 |
++ |
25585 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/tag.c linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/tag.c |
25586 |
+--- linux-2.6.29.4/kernel/vserver/tag.c 1970-01-01 01:00:00.000000000 +0100 |
25587 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/tag.c 2009-02-22 22:54:26.000000000 +0100 |
25588 |
+@@ -0,0 +1,63 @@ |
25589 |
++/* |
25590 |
++ * linux/kernel/vserver/tag.c |
25591 |
++ * |
25592 |
++ * Virtual Server: Shallow Tag Space |
25593 |
++ * |
25594 |
++ * Copyright (C) 2007 Herbert Pötzl |
25595 |
++ * |
25596 |
++ * V0.01 basic implementation |
25597 |
++ * |
25598 |
++ */ |
25599 |
++ |
25600 |
++#include <linux/sched.h> |
25601 |
++#include <linux/vserver/debug.h> |
25602 |
++#include <linux/vs_pid.h> |
25603 |
++#include <linux/vs_tag.h> |
25604 |
++ |
25605 |
++#include <linux/vserver/tag_cmd.h> |
25606 |
++ |
25607 |
++ |
25608 |
++int dx_migrate_task(struct task_struct *p, tag_t tag) |
25609 |
++{ |
25610 |
++ if (!p) |
25611 |
++ BUG(); |
25612 |
++ |
25613 |
++ vxdprintk(VXD_CBIT(tag, 5), |
25614 |
++ "dx_migrate_task(%p[#%d],#%d)", p, p->tag, tag); |
25615 |
++ |
25616 |
++ task_lock(p); |
25617 |
++ p->tag = tag; |
25618 |
++ task_unlock(p); |
25619 |
++ |
25620 |
++ vxdprintk(VXD_CBIT(tag, 5), |
25621 |
++ "moved task %p into [#%d]", p, tag); |
25622 |
++ return 0; |
25623 |
++} |
25624 |
++ |
25625 |
++/* vserver syscall commands below here */ |
25626 |
++ |
25627 |
++/* taks xid and vx_info functions */ |
25628 |
++ |
25629 |
++ |
25630 |
++int vc_task_tag(uint32_t id) |
25631 |
++{ |
25632 |
++ tag_t tag; |
25633 |
++ |
25634 |
++ if (id) { |
25635 |
++ struct task_struct *tsk; |
25636 |
++ read_lock(&tasklist_lock); |
25637 |
++ tsk = find_task_by_real_pid(id); |
25638 |
++ tag = (tsk) ? tsk->tag : -ESRCH; |
25639 |
++ read_unlock(&tasklist_lock); |
25640 |
++ } else |
25641 |
++ tag = dx_current_tag(); |
25642 |
++ return tag; |
25643 |
++} |
25644 |
++ |
25645 |
++ |
25646 |
++int vc_tag_migrate(uint32_t tag) |
25647 |
++{ |
25648 |
++ return dx_migrate_task(current, tag & 0xFFFF); |
25649 |
++} |
25650 |
++ |
25651 |
++ |
25652 |
+diff -NurpP --minimal linux-2.6.29.4/kernel/vserver/vci_config.h linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/vci_config.h |
25653 |
+--- linux-2.6.29.4/kernel/vserver/vci_config.h 1970-01-01 01:00:00.000000000 +0100 |
25654 |
++++ linux-2.6.29.4-vs2.3.0.36.14/kernel/vserver/vci_config.h 2009-02-22 22:54:26.000000000 +0100 |
25655 |
+@@ -0,0 +1,81 @@ |
25656 |
++ |
25657 |
++/* interface version */ |
25658 |
++ |
25659 |
++#define VCI_VERSION 0x00020304 |
25660 |
++ |
25661 |
++ |
25662 |
++enum { |
25663 |
++ VCI_KCBIT_NO_DYNAMIC = 0, |
25664 |
++ |
25665 |
++ VCI_KCBIT_PROC_SECURE = 4, |
25666 |
++ VCI_KCBIT_HARDCPU = 5, |
25667 |
++ VCI_KCBIT_IDLELIMIT = 6, |
25668 |
++ VCI_KCBIT_IDLETIME = 7, |
25669 |
++ |
25670 |
++ VCI_KCBIT_COWBL = 8, |
25671 |
++ VCI_KCBIT_FULLCOWBL = 9, |
25672 |
++ VCI_KCBIT_SPACES = 10, |
25673 |
++ VCI_KCBIT_NETV2 = 11, |
25674 |
++ |
25675 |
++ VCI_KCBIT_DEBUG = 16, |
25676 |
++ VCI_KCBIT_HISTORY = 20, |
25677 |
++ VCI_KCBIT_TAGGED = 24, |
25678 |
++ VCI_KCBIT_PPTAG = 28, |
25679 |
++ |
25680 |
++ VCI_KCBIT_MORE = 31, |
25681 |
++}; |
25682 |
++ |
25683 |
++ |
25684 |
++static inline uint32_t vci_kernel_config(void) |
25685 |
++{ |
25686 |
++ return |
25687 |
++ (1 << VCI_KCBIT_NO_DYNAMIC) | |
25688 |
++ |
25689 |
++ /* configured features */ |
25690 |
++#ifdef CONFIG_VSERVER_PROC_SECURE |
25691 |
++ (1 << VCI_KCBIT_PROC_SECURE) | |
25692 |
++#endif |
25693 |
++#ifdef CONFIG_VSERVER_HARDCPU |
25694 |
++ (1 << VCI_KCBIT_HARDCPU) | |
25695 |
++#endif |
25696 |
++#ifdef CONFIG_VSERVER_IDLELIMIT |
25697 |
++ (1 << VCI_KCBIT_IDLELIMIT) | |
25698 |
++#endif |
25699 |
++#ifdef CONFIG_VSERVER_IDLETIME |
25700 |
++ (1 << VCI_KCBIT_IDLETIME) | |
25701 |
++#endif |
25702 |
++#ifdef CONFIG_VSERVER_COWBL |
25703 |
++ (1 << VCI_KCBIT_COWBL) | |
25704 |
++ (1 << VCI_KCBIT_FULLCOWBL) | |
25705 |
++#endif |
25706 |
++ (1 << VCI_KCBIT_SPACES) | |
25707 |
++ (1 << VCI_KCBIT_NETV2) | |
25708 |
++ |
25709 |
++ /* debug options */ |
25710 |
++#ifdef CONFIG_VSERVER_DEBUG |
25711 |
++ (1 << VCI_KCBIT_DEBUG) | |
25712 |
++#endif |
25713 |
++#ifdef CONFIG_VSERVER_HISTORY |
25714 |
++ (1 << VCI_KCBIT_HISTORY) | |
25715 |
++#endif |
25716 |
++ |
25717 |
++ /* inode context tagging */ |
25718 |
++#if defined(CONFIG_TAGGING_NONE) |
25719 |
++ (0 << VCI_KCBIT_TAGGED) | |
25720 |
++#elif defined(CONFIG_TAGGING_UID16) |
25721 |
++ (1 << VCI_KCBIT_TAGGED) | |
25722 |
++#elif defined(CONFIG_TAGGING_GID16) |
25723 |
++ (2 << VCI_KCBIT_TAGGED) | |
25724 |
++#elif defined(CONFIG_TAGGING_ID24) |
25725 |
++ (3 << VCI_KCBIT_TAGGED) | |
25726 |
++#elif defined(CONFIG_TAGGING_INTERN) |
25727 |
++ (4 << VCI_KCBIT_TAGGED) | |
25728 |
++#elif defined(CONFIG_TAGGING_RUNTIME) |
25729 |
++ (5 << VCI_KCBIT_TAGGED) | |
25730 |
++#else |
25731 |
++ (7 << VCI_KCBIT_TAGGED) | |
25732 |
++#endif |
25733 |
++ (1 << VCI_KCBIT_PPTAG) | |
25734 |
++ 0; |
25735 |
++} |
25736 |
++ |
25737 |
+diff -NurpP --minimal linux-2.6.29.4/Makefile linux-2.6.29.4-vs2.3.0.36.14/Makefile |
25738 |
+--- linux-2.6.29.4/Makefile 2009-05-23 23:16:50.000000000 +0200 |
25739 |
++++ linux-2.6.29.4-vs2.3.0.36.14/Makefile 2009-05-29 19:03:54.000000000 +0200 |
25740 |
+@@ -1,7 +1,7 @@ |
25741 |
+ VERSION = 2 |
25742 |
+ PATCHLEVEL = 6 |
25743 |
+ SUBLEVEL = 29 |
25744 |
+-EXTRAVERSION = |
25745 |
++EXTRAVERSION = -vs2.3.0.36.14-gentoo |
25746 |
+ NAME = Temporary Tasmanian Devil |
25747 |
+ |
25748 |
+ # *DOCUMENTATION* |
25749 |
+diff -NurpP --minimal linux-2.6.29.4/mm/filemap_xip.c linux-2.6.29.4-vs2.3.0.36.14/mm/filemap_xip.c |
25750 |
+--- linux-2.6.29.4/mm/filemap_xip.c 2009-05-23 23:16:53.000000000 +0200 |
25751 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/filemap_xip.c 2009-04-30 12:14:53.000000000 +0200 |
25752 |
+@@ -17,6 +17,7 @@ |
25753 |
+ #include <linux/sched.h> |
25754 |
+ #include <linux/seqlock.h> |
25755 |
+ #include <linux/mutex.h> |
25756 |
++#include <linux/vs_memory.h> |
25757 |
+ #include <asm/tlbflush.h> |
25758 |
+ #include <asm/io.h> |
25759 |
+ |
25760 |
+diff -NurpP --minimal linux-2.6.29.4/mm/fremap.c linux-2.6.29.4-vs2.3.0.36.14/mm/fremap.c |
25761 |
+--- linux-2.6.29.4/mm/fremap.c 2009-03-24 14:22:45.000000000 +0100 |
25762 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/fremap.c 2009-03-24 14:48:36.000000000 +0100 |
25763 |
+@@ -16,6 +16,7 @@ |
25764 |
+ #include <linux/module.h> |
25765 |
+ #include <linux/syscalls.h> |
25766 |
+ #include <linux/mmu_notifier.h> |
25767 |
++#include <linux/vs_memory.h> |
25768 |
+ |
25769 |
+ #include <asm/mmu_context.h> |
25770 |
+ #include <asm/cacheflush.h> |
25771 |
+diff -NurpP --minimal linux-2.6.29.4/mm/hugetlb.c linux-2.6.29.4-vs2.3.0.36.14/mm/hugetlb.c |
25772 |
+--- linux-2.6.29.4/mm/hugetlb.c 2009-03-24 14:22:45.000000000 +0100 |
25773 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/hugetlb.c 2009-03-24 14:48:36.000000000 +0100 |
25774 |
+@@ -24,6 +24,7 @@ |
25775 |
+ #include <asm/io.h> |
25776 |
+ |
25777 |
+ #include <linux/hugetlb.h> |
25778 |
++#include <linux/vs_memory.h> |
25779 |
+ #include "internal.h" |
25780 |
+ |
25781 |
+ const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; |
25782 |
+diff -NurpP --minimal linux-2.6.29.4/mm/memory.c linux-2.6.29.4-vs2.3.0.36.14/mm/memory.c |
25783 |
+--- linux-2.6.29.4/mm/memory.c 2009-05-23 23:16:53.000000000 +0200 |
25784 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/memory.c 2009-05-23 23:19:11.000000000 +0200 |
25785 |
+@@ -55,6 +55,7 @@ |
25786 |
+ #include <linux/kallsyms.h> |
25787 |
+ #include <linux/swapops.h> |
25788 |
+ #include <linux/elf.h> |
25789 |
++// #include <linux/vs_memory.h> |
25790 |
+ |
25791 |
+ #include <asm/pgalloc.h> |
25792 |
+ #include <asm/uaccess.h> |
25793 |
+@@ -612,6 +613,9 @@ static int copy_pte_range(struct mm_stru |
25794 |
+ int progress = 0; |
25795 |
+ int rss[2]; |
25796 |
+ |
25797 |
++ if (!vx_rss_avail(dst_mm, ((end - addr)/PAGE_SIZE + 1))) |
25798 |
++ return -ENOMEM; |
25799 |
++ |
25800 |
+ again: |
25801 |
+ rss[1] = rss[0] = 0; |
25802 |
+ dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl); |
25803 |
+@@ -2481,6 +2485,11 @@ static int do_swap_page(struct mm_struct |
25804 |
+ count_vm_event(PGMAJFAULT); |
25805 |
+ } |
25806 |
+ |
25807 |
++ if (!vx_rss_avail(mm, 1)) { |
25808 |
++ ret = VM_FAULT_OOM; |
25809 |
++ goto out; |
25810 |
++ } |
25811 |
++ |
25812 |
+ mark_page_accessed(page); |
25813 |
+ |
25814 |
+ lock_page(page); |
25815 |
+@@ -2572,6 +2581,8 @@ static int do_anonymous_page(struct mm_s |
25816 |
+ /* Allocate our own private page. */ |
25817 |
+ pte_unmap(page_table); |
25818 |
+ |
25819 |
++ if (!vx_rss_avail(mm, 1)) |
25820 |
++ goto oom; |
25821 |
+ if (unlikely(anon_vma_prepare(vma))) |
25822 |
+ goto oom; |
25823 |
+ page = alloc_zeroed_user_highpage_movable(vma, address); |
25824 |
+@@ -2855,6 +2866,7 @@ static inline int handle_pte_fault(struc |
25825 |
+ { |
25826 |
+ pte_t entry; |
25827 |
+ spinlock_t *ptl; |
25828 |
++ int ret = 0, type = VXPT_UNKNOWN; |
25829 |
+ |
25830 |
+ entry = *pte; |
25831 |
+ if (!pte_present(entry)) { |
25832 |
+@@ -2879,9 +2891,12 @@ static inline int handle_pte_fault(struc |
25833 |
+ if (unlikely(!pte_same(*pte, entry))) |
25834 |
+ goto unlock; |
25835 |
+ if (write_access) { |
25836 |
+- if (!pte_write(entry)) |
25837 |
+- return do_wp_page(mm, vma, address, |
25838 |
++ if (!pte_write(entry)) { |
25839 |
++ ret = do_wp_page(mm, vma, address, |
25840 |
+ pte, pmd, ptl, entry); |
25841 |
++ type = VXPT_WRITE; |
25842 |
++ goto out; |
25843 |
++ } |
25844 |
+ entry = pte_mkdirty(entry); |
25845 |
+ } |
25846 |
+ entry = pte_mkyoung(entry); |
25847 |
+@@ -2899,7 +2914,10 @@ static inline int handle_pte_fault(struc |
25848 |
+ } |
25849 |
+ unlock: |
25850 |
+ pte_unmap_unlock(pte, ptl); |
25851 |
+- return 0; |
25852 |
++ ret = 0; |
25853 |
++out: |
25854 |
++ vx_page_fault(mm, vma, type, ret); |
25855 |
++ return ret; |
25856 |
+ } |
25857 |
+ |
25858 |
+ /* |
25859 |
+diff -NurpP --minimal linux-2.6.29.4/mm/mlock.c linux-2.6.29.4-vs2.3.0.36.14/mm/mlock.c |
25860 |
+--- linux-2.6.29.4/mm/mlock.c 2009-03-24 14:22:45.000000000 +0100 |
25861 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/mlock.c 2009-03-28 05:08:26.000000000 +0100 |
25862 |
+@@ -18,6 +18,7 @@ |
25863 |
+ #include <linux/rmap.h> |
25864 |
+ #include <linux/mmzone.h> |
25865 |
+ #include <linux/hugetlb.h> |
25866 |
++#include <linux/vs_memory.h> |
25867 |
+ |
25868 |
+ #include "internal.h" |
25869 |
+ |
25870 |
+@@ -415,7 +416,7 @@ success: |
25871 |
+ nr_pages = (end - start) >> PAGE_SHIFT; |
25872 |
+ if (!lock) |
25873 |
+ nr_pages = -nr_pages; |
25874 |
+- mm->locked_vm += nr_pages; |
25875 |
++ vx_vmlocked_add(mm, nr_pages); |
25876 |
+ |
25877 |
+ /* |
25878 |
+ * vm_flags is protected by the mmap_sem held in write mode. |
25879 |
+@@ -492,7 +493,7 @@ static int do_mlock(unsigned long start, |
25880 |
+ |
25881 |
+ SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len) |
25882 |
+ { |
25883 |
+- unsigned long locked; |
25884 |
++ unsigned long locked, grow; |
25885 |
+ unsigned long lock_limit; |
25886 |
+ int error = -ENOMEM; |
25887 |
+ |
25888 |
+@@ -505,8 +506,10 @@ SYSCALL_DEFINE2(mlock, unsigned long, st |
25889 |
+ len = PAGE_ALIGN(len + (start & ~PAGE_MASK)); |
25890 |
+ start &= PAGE_MASK; |
25891 |
+ |
25892 |
+- locked = len >> PAGE_SHIFT; |
25893 |
+- locked += current->mm->locked_vm; |
25894 |
++ grow = len >> PAGE_SHIFT; |
25895 |
++ if (!vx_vmlocked_avail(current->mm, grow)) |
25896 |
++ goto out; |
25897 |
++ locked = current->mm->locked_vm + grow; |
25898 |
+ |
25899 |
+ lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; |
25900 |
+ lock_limit >>= PAGE_SHIFT; |
25901 |
+@@ -514,6 +517,7 @@ SYSCALL_DEFINE2(mlock, unsigned long, st |
25902 |
+ /* check against resource limits */ |
25903 |
+ if ((locked <= lock_limit) || capable(CAP_IPC_LOCK)) |
25904 |
+ error = do_mlock(start, len, 1); |
25905 |
++out: |
25906 |
+ up_write(¤t->mm->mmap_sem); |
25907 |
+ return error; |
25908 |
+ } |
25909 |
+@@ -575,6 +579,8 @@ SYSCALL_DEFINE1(mlockall, int, flags) |
25910 |
+ lock_limit >>= PAGE_SHIFT; |
25911 |
+ |
25912 |
+ ret = -ENOMEM; |
25913 |
++ if (!vx_vmlocked_avail(current->mm, current->mm->total_vm)) |
25914 |
++ goto out; |
25915 |
+ if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) || |
25916 |
+ capable(CAP_IPC_LOCK)) |
25917 |
+ ret = do_mlockall(flags); |
25918 |
+@@ -652,8 +658,10 @@ void *alloc_locked_buffer(size_t size) |
25919 |
+ if (!buffer) |
25920 |
+ goto out; |
25921 |
+ |
25922 |
+- current->mm->total_vm += pgsz; |
25923 |
+- current->mm->locked_vm += pgsz; |
25924 |
++ // current->mm->total_vm += pgsz; |
25925 |
++ vx_vmpages_add(current->mm, pgsz); |
25926 |
++ // current->mm->locked_vm += pgsz; |
25927 |
++ vx_vmlocked_add(current->mm, pgsz); |
25928 |
+ |
25929 |
+ out: |
25930 |
+ up_write(¤t->mm->mmap_sem); |
25931 |
+@@ -666,8 +674,10 @@ void release_locked_buffer(void *buffer, |
25932 |
+ |
25933 |
+ down_write(¤t->mm->mmap_sem); |
25934 |
+ |
25935 |
+- current->mm->total_vm -= pgsz; |
25936 |
+- current->mm->locked_vm -= pgsz; |
25937 |
++ // current->mm->total_vm -= pgsz; |
25938 |
++ vx_vmpages_sub(current->mm, pgsz); |
25939 |
++ // current->mm->locked_vm -= pgsz; |
25940 |
++ vx_vmlocked_sub(current->mm, pgsz); |
25941 |
+ |
25942 |
+ up_write(¤t->mm->mmap_sem); |
25943 |
+ } |
25944 |
+diff -NurpP --minimal linux-2.6.29.4/mm/mmap.c linux-2.6.29.4-vs2.3.0.36.14/mm/mmap.c |
25945 |
+--- linux-2.6.29.4/mm/mmap.c 2009-05-23 23:16:53.000000000 +0200 |
25946 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/mmap.c 2009-05-10 23:42:01.000000000 +0200 |
25947 |
+@@ -1215,7 +1215,8 @@ munmap_back: |
25948 |
+ if (correct_wcount) |
25949 |
+ atomic_inc(&inode->i_writecount); |
25950 |
+ out: |
25951 |
+- mm->total_vm += len >> PAGE_SHIFT; |
25952 |
++ // mm->total_vm += len >> PAGE_SHIFT; |
25953 |
++ vx_vmpages_add(mm, len >> PAGE_SHIFT); |
25954 |
+ vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); |
25955 |
+ if (vm_flags & VM_LOCKED) { |
25956 |
+ /* |
25957 |
+@@ -1224,7 +1225,8 @@ out: |
25958 |
+ long nr_pages = mlock_vma_pages_range(vma, addr, addr + len); |
25959 |
+ if (nr_pages < 0) |
25960 |
+ return nr_pages; /* vma gone! */ |
25961 |
+- mm->locked_vm += (len >> PAGE_SHIFT) - nr_pages; |
25962 |
++ // mm->locked_vm += (len >> PAGE_SHIFT) - nr_pages; |
25963 |
++ vx_vmlocked_add(mm, (len >> PAGE_SHIFT) - nr_pages); |
25964 |
+ } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK)) |
25965 |
+ make_pages_present(addr, addr + len); |
25966 |
+ return addr; |
25967 |
+@@ -1571,9 +1573,9 @@ static int acct_stack_growth(struct vm_a |
25968 |
+ return -ENOMEM; |
25969 |
+ |
25970 |
+ /* Ok, everything looks good - let it rip */ |
25971 |
+- mm->total_vm += grow; |
25972 |
++ vx_vmpages_add(mm, grow); |
25973 |
+ if (vma->vm_flags & VM_LOCKED) |
25974 |
+- mm->locked_vm += grow; |
25975 |
++ vx_vmlocked_add(mm, grow); |
25976 |
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow); |
25977 |
+ return 0; |
25978 |
+ } |
25979 |
+@@ -1748,7 +1750,8 @@ static void remove_vma_list(struct mm_st |
25980 |
+ do { |
25981 |
+ long nrpages = vma_pages(vma); |
25982 |
+ |
25983 |
+- mm->total_vm -= nrpages; |
25984 |
++ // mm->total_vm -= nrpages; |
25985 |
++ vx_vmpages_sub(mm, nrpages); |
25986 |
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages); |
25987 |
+ vma = remove_vma(vma); |
25988 |
+ } while (vma); |
25989 |
+@@ -1920,7 +1923,8 @@ int do_munmap(struct mm_struct *mm, unsi |
25990 |
+ struct vm_area_struct *tmp = vma; |
25991 |
+ while (tmp && tmp->vm_start < end) { |
25992 |
+ if (tmp->vm_flags & VM_LOCKED) { |
25993 |
+- mm->locked_vm -= vma_pages(tmp); |
25994 |
++ // mm->locked_vm -= vma_pages(tmp); |
25995 |
++ vx_vmlocked_sub(mm, vma_pages(tmp)); |
25996 |
+ munlock_vma_pages_all(tmp); |
25997 |
+ } |
25998 |
+ tmp = tmp->vm_next; |
25999 |
+@@ -2009,6 +2013,8 @@ unsigned long do_brk(unsigned long addr, |
26000 |
+ lock_limit >>= PAGE_SHIFT; |
26001 |
+ if (locked > lock_limit && !capable(CAP_IPC_LOCK)) |
26002 |
+ return -EAGAIN; |
26003 |
++ if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT)) |
26004 |
++ return -ENOMEM; |
26005 |
+ } |
26006 |
+ |
26007 |
+ /* |
26008 |
+@@ -2035,7 +2041,8 @@ unsigned long do_brk(unsigned long addr, |
26009 |
+ if (mm->map_count > sysctl_max_map_count) |
26010 |
+ return -ENOMEM; |
26011 |
+ |
26012 |
+- if (security_vm_enough_memory(len >> PAGE_SHIFT)) |
26013 |
++ if (security_vm_enough_memory(len >> PAGE_SHIFT) || |
26014 |
++ !vx_vmpages_avail(mm, len >> PAGE_SHIFT)) |
26015 |
+ return -ENOMEM; |
26016 |
+ |
26017 |
+ /* Can we just expand an old private anonymous mapping? */ |
26018 |
+@@ -2061,10 +2068,13 @@ unsigned long do_brk(unsigned long addr, |
26019 |
+ vma->vm_page_prot = vm_get_page_prot(flags); |
26020 |
+ vma_link(mm, vma, prev, rb_link, rb_parent); |
26021 |
+ out: |
26022 |
+- mm->total_vm += len >> PAGE_SHIFT; |
26023 |
++ // mm->total_vm += len >> PAGE_SHIFT; |
26024 |
++ vx_vmpages_add(mm, len >> PAGE_SHIFT); |
26025 |
++ |
26026 |
+ if (flags & VM_LOCKED) { |
26027 |
+ if (!mlock_vma_pages_range(vma, addr, addr + len)) |
26028 |
+- mm->locked_vm += (len >> PAGE_SHIFT); |
26029 |
++ // mm->locked_vm += (len >> PAGE_SHIFT); |
26030 |
++ vx_vmlocked_add(mm, len >> PAGE_SHIFT); |
26031 |
+ } |
26032 |
+ return addr; |
26033 |
+ } |
26034 |
+@@ -2107,6 +2117,11 @@ void exit_mmap(struct mm_struct *mm) |
26035 |
+ free_pgtables(tlb, vma, FIRST_USER_ADDRESS, 0); |
26036 |
+ tlb_finish_mmu(tlb, 0, end); |
26037 |
+ |
26038 |
++ set_mm_counter(mm, file_rss, 0); |
26039 |
++ set_mm_counter(mm, anon_rss, 0); |
26040 |
++ vx_vmpages_sub(mm, mm->total_vm); |
26041 |
++ vx_vmlocked_sub(mm, mm->locked_vm); |
26042 |
++ |
26043 |
+ /* |
26044 |
+ * Walk the list again, actually closing and freeing it, |
26045 |
+ * with preemption enabled, without holding any MM locks. |
26046 |
+@@ -2146,7 +2161,8 @@ int insert_vm_struct(struct mm_struct * |
26047 |
+ if (__vma && __vma->vm_start < vma->vm_end) |
26048 |
+ return -ENOMEM; |
26049 |
+ if ((vma->vm_flags & VM_ACCOUNT) && |
26050 |
+- security_vm_enough_memory_mm(mm, vma_pages(vma))) |
26051 |
++ (security_vm_enough_memory_mm(mm, vma_pages(vma)) || |
26052 |
++ !vx_vmpages_avail(mm, vma_pages(vma)))) |
26053 |
+ return -ENOMEM; |
26054 |
+ vma_link(mm, vma, prev, rb_link, rb_parent); |
26055 |
+ return 0; |
26056 |
+@@ -2222,6 +2238,8 @@ int may_expand_vm(struct mm_struct *mm, |
26057 |
+ |
26058 |
+ if (cur + npages > lim) |
26059 |
+ return 0; |
26060 |
++ if (!vx_vmpages_avail(mm, npages)) |
26061 |
++ return 0; |
26062 |
+ return 1; |
26063 |
+ } |
26064 |
+ |
26065 |
+@@ -2299,8 +2317,7 @@ int install_special_mapping(struct mm_st |
26066 |
+ return -ENOMEM; |
26067 |
+ } |
26068 |
+ |
26069 |
+- mm->total_vm += len >> PAGE_SHIFT; |
26070 |
+- |
26071 |
++ vx_vmpages_add(mm, len >> PAGE_SHIFT); |
26072 |
+ return 0; |
26073 |
+ } |
26074 |
+ |
26075 |
+diff -NurpP --minimal linux-2.6.29.4/mm/mremap.c linux-2.6.29.4-vs2.3.0.36.14/mm/mremap.c |
26076 |
+--- linux-2.6.29.4/mm/mremap.c 2009-03-24 14:22:45.000000000 +0100 |
26077 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/mremap.c 2009-03-24 14:48:36.000000000 +0100 |
26078 |
+@@ -19,6 +19,7 @@ |
26079 |
+ #include <linux/security.h> |
26080 |
+ #include <linux/syscalls.h> |
26081 |
+ #include <linux/mmu_notifier.h> |
26082 |
++#include <linux/vs_memory.h> |
26083 |
+ |
26084 |
+ #include <asm/uaccess.h> |
26085 |
+ #include <asm/cacheflush.h> |
26086 |
+@@ -220,7 +221,7 @@ static unsigned long move_vma(struct vm_ |
26087 |
+ * If this were a serious issue, we'd add a flag to do_munmap(). |
26088 |
+ */ |
26089 |
+ hiwater_vm = mm->hiwater_vm; |
26090 |
+- mm->total_vm += new_len >> PAGE_SHIFT; |
26091 |
++ vx_vmpages_add(mm, new_len >> PAGE_SHIFT); |
26092 |
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT); |
26093 |
+ |
26094 |
+ if (do_munmap(mm, old_addr, old_len) < 0) { |
26095 |
+@@ -238,7 +239,7 @@ static unsigned long move_vma(struct vm_ |
26096 |
+ } |
26097 |
+ |
26098 |
+ if (vm_flags & VM_LOCKED) { |
26099 |
+- mm->locked_vm += new_len >> PAGE_SHIFT; |
26100 |
++ vx_vmlocked_add(mm, new_len >> PAGE_SHIFT); |
26101 |
+ if (new_len > old_len) |
26102 |
+ mlock_vma_pages_range(new_vma, new_addr + old_len, |
26103 |
+ new_addr + new_len); |
26104 |
+@@ -349,6 +350,9 @@ unsigned long do_mremap(unsigned long ad |
26105 |
+ ret = -EAGAIN; |
26106 |
+ if (locked > lock_limit && !capable(CAP_IPC_LOCK)) |
26107 |
+ goto out; |
26108 |
++ if (!vx_vmlocked_avail(current->mm, |
26109 |
++ (new_len - old_len) >> PAGE_SHIFT)) |
26110 |
++ goto out; |
26111 |
+ } |
26112 |
+ if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) { |
26113 |
+ ret = -ENOMEM; |
26114 |
+@@ -377,10 +381,12 @@ unsigned long do_mremap(unsigned long ad |
26115 |
+ vma_adjust(vma, vma->vm_start, |
26116 |
+ addr + new_len, vma->vm_pgoff, NULL); |
26117 |
+ |
26118 |
+- mm->total_vm += pages; |
26119 |
++ // mm->total_vm += pages; |
26120 |
++ vx_vmpages_add(mm, pages); |
26121 |
+ vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages); |
26122 |
+ if (vma->vm_flags & VM_LOCKED) { |
26123 |
+- mm->locked_vm += pages; |
26124 |
++ // mm->locked_vm += pages; |
26125 |
++ vx_vmlocked_add(mm, pages); |
26126 |
+ mlock_vma_pages_range(vma, addr + old_len, |
26127 |
+ addr + new_len); |
26128 |
+ } |
26129 |
+diff -NurpP --minimal linux-2.6.29.4/mm/nommu.c linux-2.6.29.4-vs2.3.0.36.14/mm/nommu.c |
26130 |
+--- linux-2.6.29.4/mm/nommu.c 2009-05-23 23:16:53.000000000 +0200 |
26131 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/nommu.c 2009-05-10 23:42:01.000000000 +0200 |
26132 |
+@@ -1352,7 +1352,7 @@ unsigned long do_mmap_pgoff(struct file |
26133 |
+ /* okay... we have a mapping; now we have to register it */ |
26134 |
+ result = vma->vm_start; |
26135 |
+ |
26136 |
+- current->mm->total_vm += len >> PAGE_SHIFT; |
26137 |
++ vx_vmpages_add(current->mm, len >> PAGE_SHIFT); |
26138 |
+ |
26139 |
+ share: |
26140 |
+ add_vma_to_mm(current->mm, vma); |
26141 |
+@@ -1618,7 +1618,7 @@ void exit_mmap(struct mm_struct *mm) |
26142 |
+ |
26143 |
+ kenter(""); |
26144 |
+ |
26145 |
+- mm->total_vm = 0; |
26146 |
++ vx_vmpages_sub(mm, mm->total_vm); |
26147 |
+ |
26148 |
+ while ((vma = mm->mmap)) { |
26149 |
+ mm->mmap = vma->vm_next; |
26150 |
+diff -NurpP --minimal linux-2.6.29.4/mm/oom_kill.c linux-2.6.29.4-vs2.3.0.36.14/mm/oom_kill.c |
26151 |
+--- linux-2.6.29.4/mm/oom_kill.c 2009-03-24 14:22:45.000000000 +0100 |
26152 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/oom_kill.c 2009-03-24 14:48:36.000000000 +0100 |
26153 |
+@@ -27,6 +27,7 @@ |
26154 |
+ #include <linux/notifier.h> |
26155 |
+ #include <linux/memcontrol.h> |
26156 |
+ #include <linux/security.h> |
26157 |
++#include <linux/vs_memory.h> |
26158 |
+ |
26159 |
+ int sysctl_panic_on_oom; |
26160 |
+ int sysctl_oom_kill_allocating_task; |
26161 |
+@@ -72,6 +73,12 @@ unsigned long badness(struct task_struct |
26162 |
+ points = mm->total_vm; |
26163 |
+ |
26164 |
+ /* |
26165 |
++ * add points for context badness |
26166 |
++ */ |
26167 |
++ |
26168 |
++ points += vx_badness(p, mm); |
26169 |
++ |
26170 |
++ /* |
26171 |
+ * After this unlock we can no longer dereference local variable `mm' |
26172 |
+ */ |
26173 |
+ task_unlock(p); |
26174 |
+@@ -162,8 +169,8 @@ unsigned long badness(struct task_struct |
26175 |
+ } |
26176 |
+ |
26177 |
+ #ifdef DEBUG |
26178 |
+- printk(KERN_DEBUG "OOMkill: task %d (%s) got %lu points\n", |
26179 |
+- p->pid, p->comm, points); |
26180 |
++ printk(KERN_DEBUG "OOMkill: task %d:#%u (%s) got %d points\n", |
26181 |
++ task_pid_nr(p), p->xid, p->comm, points); |
26182 |
+ #endif |
26183 |
+ return points; |
26184 |
+ } |
26185 |
+@@ -326,8 +333,8 @@ static void __oom_kill_task(struct task_ |
26186 |
+ } |
26187 |
+ |
26188 |
+ if (verbose) |
26189 |
+- printk(KERN_ERR "Killed process %d (%s)\n", |
26190 |
+- task_pid_nr(p), p->comm); |
26191 |
++ printk(KERN_ERR "Killed process %d:#%u (%s)\n", |
26192 |
++ task_pid_nr(p), p->xid, p->comm); |
26193 |
+ |
26194 |
+ /* |
26195 |
+ * We give our sacrificial lamb high priority and access to |
26196 |
+@@ -410,8 +417,8 @@ static int oom_kill_process(struct task_ |
26197 |
+ return 0; |
26198 |
+ } |
26199 |
+ |
26200 |
+- printk(KERN_ERR "%s: kill process %d (%s) score %li or a child\n", |
26201 |
+- message, task_pid_nr(p), p->comm, points); |
26202 |
++ printk(KERN_ERR "%s: kill process %d:#%u (%s) score %li or a child\n", |
26203 |
++ message, task_pid_nr(p), p->xid, p->comm, points); |
26204 |
+ |
26205 |
+ /* Try to kill a child first */ |
26206 |
+ list_for_each_entry(c, &p->children, sibling) { |
26207 |
+diff -NurpP --minimal linux-2.6.29.4/mm/page_alloc.c linux-2.6.29.4-vs2.3.0.36.14/mm/page_alloc.c |
26208 |
+--- linux-2.6.29.4/mm/page_alloc.c 2009-03-24 14:22:45.000000000 +0100 |
26209 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/page_alloc.c 2009-03-24 14:48:36.000000000 +0100 |
26210 |
+@@ -46,6 +46,8 @@ |
26211 |
+ #include <linux/page-isolation.h> |
26212 |
+ #include <linux/page_cgroup.h> |
26213 |
+ #include <linux/debugobjects.h> |
26214 |
++#include <linux/vs_base.h> |
26215 |
++#include <linux/vs_limit.h> |
26216 |
+ |
26217 |
+ #include <asm/tlbflush.h> |
26218 |
+ #include <asm/div64.h> |
26219 |
+@@ -1839,6 +1841,9 @@ void si_meminfo(struct sysinfo *val) |
26220 |
+ val->totalhigh = totalhigh_pages; |
26221 |
+ val->freehigh = nr_free_highpages(); |
26222 |
+ val->mem_unit = PAGE_SIZE; |
26223 |
++ |
26224 |
++ if (vx_flags(VXF_VIRT_MEM, 0)) |
26225 |
++ vx_vsi_meminfo(val); |
26226 |
+ } |
26227 |
+ |
26228 |
+ EXPORT_SYMBOL(si_meminfo); |
26229 |
+@@ -1859,6 +1864,9 @@ void si_meminfo_node(struct sysinfo *val |
26230 |
+ val->freehigh = 0; |
26231 |
+ #endif |
26232 |
+ val->mem_unit = PAGE_SIZE; |
26233 |
++ |
26234 |
++ if (vx_flags(VXF_VIRT_MEM, 0)) |
26235 |
++ vx_vsi_meminfo(val); |
26236 |
+ } |
26237 |
+ #endif |
26238 |
+ |
26239 |
+diff -NurpP --minimal linux-2.6.29.4/mm/rmap.c linux-2.6.29.4-vs2.3.0.36.14/mm/rmap.c |
26240 |
+--- linux-2.6.29.4/mm/rmap.c 2009-03-24 14:22:45.000000000 +0100 |
26241 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/rmap.c 2009-03-24 18:26:27.000000000 +0100 |
26242 |
+@@ -50,6 +50,7 @@ |
26243 |
+ #include <linux/memcontrol.h> |
26244 |
+ #include <linux/mmu_notifier.h> |
26245 |
+ #include <linux/migrate.h> |
26246 |
++#include <linux/vs_memory.h> |
26247 |
+ |
26248 |
+ #include <asm/tlbflush.h> |
26249 |
+ |
26250 |
+diff -NurpP --minimal linux-2.6.29.4/mm/shmem.c linux-2.6.29.4-vs2.3.0.36.14/mm/shmem.c |
26251 |
+--- linux-2.6.29.4/mm/shmem.c 2009-03-24 14:22:45.000000000 +0100 |
26252 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/shmem.c 2009-03-24 14:48:36.000000000 +0100 |
26253 |
+@@ -1757,7 +1757,7 @@ static int shmem_statfs(struct dentry *d |
26254 |
+ { |
26255 |
+ struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb); |
26256 |
+ |
26257 |
+- buf->f_type = TMPFS_MAGIC; |
26258 |
++ buf->f_type = TMPFS_SUPER_MAGIC; |
26259 |
+ buf->f_bsize = PAGE_CACHE_SIZE; |
26260 |
+ buf->f_namelen = NAME_MAX; |
26261 |
+ spin_lock(&sbinfo->stat_lock); |
26262 |
+@@ -2326,7 +2326,7 @@ static int shmem_fill_super(struct super |
26263 |
+ sb->s_maxbytes = SHMEM_MAX_BYTES; |
26264 |
+ sb->s_blocksize = PAGE_CACHE_SIZE; |
26265 |
+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
26266 |
+- sb->s_magic = TMPFS_MAGIC; |
26267 |
++ sb->s_magic = TMPFS_SUPER_MAGIC; |
26268 |
+ sb->s_op = &shmem_ops; |
26269 |
+ sb->s_time_gran = 1; |
26270 |
+ #ifdef CONFIG_TMPFS_POSIX_ACL |
26271 |
+diff -NurpP --minimal linux-2.6.29.4/mm/slab.c linux-2.6.29.4-vs2.3.0.36.14/mm/slab.c |
26272 |
+--- linux-2.6.29.4/mm/slab.c 2009-03-24 14:22:45.000000000 +0100 |
26273 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/slab.c 2009-03-24 14:48:36.000000000 +0100 |
26274 |
+@@ -509,6 +509,8 @@ struct kmem_cache { |
26275 |
+ #define STATS_INC_FREEMISS(x) do { } while (0) |
26276 |
+ #endif |
26277 |
+ |
26278 |
++#include "slab_vs.h" |
26279 |
++ |
26280 |
+ #if DEBUG |
26281 |
+ |
26282 |
+ /* |
26283 |
+@@ -3275,6 +3277,7 @@ retry: |
26284 |
+ |
26285 |
+ obj = slab_get_obj(cachep, slabp, nodeid); |
26286 |
+ check_slabp(cachep, slabp); |
26287 |
++ vx_slab_alloc(cachep, flags); |
26288 |
+ l3->free_objects--; |
26289 |
+ /* move slabp to correct slabp list: */ |
26290 |
+ list_del(&slabp->list); |
26291 |
+@@ -3347,6 +3350,7 @@ __cache_alloc_node(struct kmem_cache *ca |
26292 |
+ /* ___cache_alloc_node can fall back to other nodes */ |
26293 |
+ ptr = ____cache_alloc_node(cachep, flags, nodeid); |
26294 |
+ out: |
26295 |
++ vx_slab_alloc(cachep, flags); |
26296 |
+ local_irq_restore(save_flags); |
26297 |
+ ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller); |
26298 |
+ |
26299 |
+@@ -3518,6 +3522,7 @@ static inline void __cache_free(struct k |
26300 |
+ |
26301 |
+ check_irq_off(); |
26302 |
+ objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0)); |
26303 |
++ vx_slab_free(cachep); |
26304 |
+ |
26305 |
+ /* |
26306 |
+ * Skip calling cache_free_alien() when the platform is not numa. |
26307 |
+diff -NurpP --minimal linux-2.6.29.4/mm/slab_vs.h linux-2.6.29.4-vs2.3.0.36.14/mm/slab_vs.h |
26308 |
+--- linux-2.6.29.4/mm/slab_vs.h 1970-01-01 01:00:00.000000000 +0100 |
26309 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/slab_vs.h 2009-02-22 22:54:26.000000000 +0100 |
26310 |
+@@ -0,0 +1,27 @@ |
26311 |
++ |
26312 |
++#include <linux/vserver/context.h> |
26313 |
++ |
26314 |
++#include <linux/vs_context.h> |
26315 |
++ |
26316 |
++static inline |
26317 |
++void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags) |
26318 |
++{ |
26319 |
++ int what = gfp_zone(cachep->gfpflags); |
26320 |
++ |
26321 |
++ if (!current->vx_info) |
26322 |
++ return; |
26323 |
++ |
26324 |
++ atomic_add(cachep->buffer_size, ¤t->vx_info->cacct.slab[what]); |
26325 |
++} |
26326 |
++ |
26327 |
++static inline |
26328 |
++void vx_slab_free(struct kmem_cache *cachep) |
26329 |
++{ |
26330 |
++ int what = gfp_zone(cachep->gfpflags); |
26331 |
++ |
26332 |
++ if (!current->vx_info) |
26333 |
++ return; |
26334 |
++ |
26335 |
++ atomic_sub(cachep->buffer_size, ¤t->vx_info->cacct.slab[what]); |
26336 |
++} |
26337 |
++ |
26338 |
+diff -NurpP --minimal linux-2.6.29.4/mm/swapfile.c linux-2.6.29.4-vs2.3.0.36.14/mm/swapfile.c |
26339 |
+--- linux-2.6.29.4/mm/swapfile.c 2009-03-24 14:22:45.000000000 +0100 |
26340 |
++++ linux-2.6.29.4-vs2.3.0.36.14/mm/swapfile.c 2009-03-24 18:27:15.000000000 +0100 |
26341 |
+@@ -34,6 +34,8 @@ |
26342 |
+ #include <asm/tlbflush.h> |
26343 |
+ #include <linux/swapops.h> |
26344 |
+ #include <linux/page_cgroup.h> |
26345 |
++#include <linux/vs_base.h> |
26346 |
++#include <linux/vs_memory.h> |
26347 |
+ |
26348 |
+ static DEFINE_SPINLOCK(swap_lock); |
26349 |
+ static unsigned int nr_swapfiles; |
26350 |
+@@ -1935,6 +1937,8 @@ void si_swapinfo(struct sysinfo *val) |
26351 |
+ val->freeswap = nr_swap_pages + nr_to_be_unused; |
26352 |
+ val->totalswap = total_swap_pages + nr_to_be_unused; |
26353 |
+ spin_unlock(&swap_lock); |
26354 |
++ if (vx_flags(VXF_VIRT_MEM, 0)) |
26355 |
++ vx_vsi_swapinfo(val); |
26356 |
+ } |
26357 |
+ |
26358 |
+ /* |
26359 |
+diff -NurpP --minimal linux-2.6.29.4/net/core/dev.c linux-2.6.29.4-vs2.3.0.36.14/net/core/dev.c |
26360 |
+--- linux-2.6.29.4/net/core/dev.c 2009-05-23 23:16:53.000000000 +0200 |
26361 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/core/dev.c 2009-04-15 22:58:30.000000000 +0200 |
26362 |
+@@ -126,6 +126,7 @@ |
26363 |
+ #include <linux/in.h> |
26364 |
+ #include <linux/jhash.h> |
26365 |
+ #include <linux/random.h> |
26366 |
++#include <linux/vs_inet.h> |
26367 |
+ |
26368 |
+ #include "net-sysfs.h" |
26369 |
+ |
26370 |
+@@ -2853,6 +2854,8 @@ static int dev_ifconf(struct net *net, c |
26371 |
+ |
26372 |
+ total = 0; |
26373 |
+ for_each_netdev(net, dev) { |
26374 |
++ if (!nx_dev_visible(current->nx_info, dev)) |
26375 |
++ continue; |
26376 |
+ for (i = 0; i < NPROTO; i++) { |
26377 |
+ if (gifconf_list[i]) { |
26378 |
+ int done; |
26379 |
+@@ -2921,6 +2924,9 @@ static void dev_seq_printf_stats(struct |
26380 |
+ { |
26381 |
+ const struct net_device_stats *stats = dev_get_stats(dev); |
26382 |
+ |
26383 |
++ if (!nx_dev_visible(current->nx_info, dev)) |
26384 |
++ return; |
26385 |
++ |
26386 |
+ seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu " |
26387 |
+ "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n", |
26388 |
+ dev->name, stats->rx_bytes, stats->rx_packets, |
26389 |
+@@ -4862,6 +4868,15 @@ int dev_change_net_namespace(struct net_ |
26390 |
+ goto out; |
26391 |
+ #endif |
26392 |
+ |
26393 |
++#ifdef CONFIG_SYSFS |
26394 |
++ /* Don't allow real devices to be moved when sysfs |
26395 |
++ * is enabled. |
26396 |
++ */ |
26397 |
++ err = -EINVAL; |
26398 |
++ if (dev->dev.parent) |
26399 |
++ goto out; |
26400 |
++#endif |
26401 |
++ |
26402 |
+ /* Ensure the device has been registrered */ |
26403 |
+ err = -EINVAL; |
26404 |
+ if (dev->reg_state != NETREG_REGISTERED) |
26405 |
+@@ -4921,6 +4936,8 @@ int dev_change_net_namespace(struct net_ |
26406 |
+ |
26407 |
+ netdev_unregister_kobject(dev); |
26408 |
+ |
26409 |
++ netdev_unregister_kobject(dev); |
26410 |
++ |
26411 |
+ /* Actually switch the network namespace */ |
26412 |
+ dev_net_set(dev, net); |
26413 |
+ |
26414 |
+diff -NurpP --minimal linux-2.6.29.4/net/core/net-sysfs.c linux-2.6.29.4-vs2.3.0.36.14/net/core/net-sysfs.c |
26415 |
+--- linux-2.6.29.4/net/core/net-sysfs.c 2009-03-24 14:22:46.000000000 +0100 |
26416 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/core/net-sysfs.c 2009-03-24 18:30:01.000000000 +0100 |
26417 |
+@@ -512,6 +512,9 @@ int netdev_register_kobject(struct net_d |
26418 |
+ if (dev_net(net) != &init_net) |
26419 |
+ return 0; |
26420 |
+ |
26421 |
++ if (dev_net(net) != &init_net) |
26422 |
++ return 0; |
26423 |
++ |
26424 |
+ return device_add(dev); |
26425 |
+ } |
26426 |
+ |
26427 |
+diff -NurpP --minimal linux-2.6.29.4/net/core/rtnetlink.c linux-2.6.29.4-vs2.3.0.36.14/net/core/rtnetlink.c |
26428 |
+--- linux-2.6.29.4/net/core/rtnetlink.c 2009-03-24 14:22:46.000000000 +0100 |
26429 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/core/rtnetlink.c 2009-03-24 14:48:36.000000000 +0100 |
26430 |
+@@ -690,6 +690,8 @@ static int rtnl_dump_ifinfo(struct sk_bu |
26431 |
+ |
26432 |
+ idx = 0; |
26433 |
+ for_each_netdev(net, dev) { |
26434 |
++ if (!nx_dev_visible(skb->sk->sk_nx_info, dev)) |
26435 |
++ continue; |
26436 |
+ if (idx < s_idx) |
26437 |
+ goto cont; |
26438 |
+ if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, |
26439 |
+@@ -1235,6 +1237,9 @@ void rtmsg_ifinfo(int type, struct net_d |
26440 |
+ struct sk_buff *skb; |
26441 |
+ int err = -ENOBUFS; |
26442 |
+ |
26443 |
++ if (!nx_dev_visible(current->nx_info, dev)) |
26444 |
++ return; |
26445 |
++ |
26446 |
+ skb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL); |
26447 |
+ if (skb == NULL) |
26448 |
+ goto errout; |
26449 |
+diff -NurpP --minimal linux-2.6.29.4/net/core/sock.c linux-2.6.29.4-vs2.3.0.36.14/net/core/sock.c |
26450 |
+--- linux-2.6.29.4/net/core/sock.c 2009-03-24 14:22:46.000000000 +0100 |
26451 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/core/sock.c 2009-03-24 14:48:36.000000000 +0100 |
26452 |
+@@ -124,6 +124,10 @@ |
26453 |
+ #include <linux/ipsec.h> |
26454 |
+ |
26455 |
+ #include <linux/filter.h> |
26456 |
++#include <linux/vs_socket.h> |
26457 |
++#include <linux/vs_limit.h> |
26458 |
++#include <linux/vs_context.h> |
26459 |
++#include <linux/vs_network.h> |
26460 |
+ |
26461 |
+ #ifdef CONFIG_INET |
26462 |
+ #include <net/tcp.h> |
26463 |
+@@ -900,6 +904,8 @@ static struct sock *sk_prot_alloc(struct |
26464 |
+ if (!try_module_get(prot->owner)) |
26465 |
+ goto out_free_sec; |
26466 |
+ } |
26467 |
++ sock_vx_init(sk); |
26468 |
++ sock_nx_init(sk); |
26469 |
+ |
26470 |
+ return sk; |
26471 |
+ |
26472 |
+@@ -976,6 +982,11 @@ void sk_free(struct sock *sk) |
26473 |
+ __func__, atomic_read(&sk->sk_omem_alloc)); |
26474 |
+ |
26475 |
+ put_net(sock_net(sk)); |
26476 |
++ vx_sock_dec(sk); |
26477 |
++ clr_vx_info(&sk->sk_vx_info); |
26478 |
++ sk->sk_xid = -1; |
26479 |
++ clr_nx_info(&sk->sk_nx_info); |
26480 |
++ sk->sk_nid = -1; |
26481 |
+ sk_prot_free(sk->sk_prot_creator, sk); |
26482 |
+ } |
26483 |
+ |
26484 |
+@@ -1011,6 +1022,8 @@ struct sock *sk_clone(const struct sock |
26485 |
+ |
26486 |
+ /* SANITY */ |
26487 |
+ get_net(sock_net(newsk)); |
26488 |
++ sock_vx_init(newsk); |
26489 |
++ sock_nx_init(newsk); |
26490 |
+ sk_node_init(&newsk->sk_node); |
26491 |
+ sock_lock_init(newsk); |
26492 |
+ bh_lock_sock(newsk); |
26493 |
+@@ -1057,6 +1070,12 @@ struct sock *sk_clone(const struct sock |
26494 |
+ newsk->sk_priority = 0; |
26495 |
+ atomic_set(&newsk->sk_refcnt, 2); |
26496 |
+ |
26497 |
++ set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info); |
26498 |
++ newsk->sk_xid = sk->sk_xid; |
26499 |
++ vx_sock_inc(newsk); |
26500 |
++ set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info); |
26501 |
++ newsk->sk_nid = sk->sk_nid; |
26502 |
++ |
26503 |
+ /* |
26504 |
+ * Increment the counter in the same struct proto as the master |
26505 |
+ * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that |
26506 |
+@@ -1744,6 +1763,11 @@ void sock_init_data(struct socket *sock, |
26507 |
+ |
26508 |
+ sk->sk_stamp = ktime_set(-1L, 0); |
26509 |
+ |
26510 |
++ set_vx_info(&sk->sk_vx_info, current->vx_info); |
26511 |
++ sk->sk_xid = vx_current_xid(); |
26512 |
++ vx_sock_inc(sk); |
26513 |
++ set_nx_info(&sk->sk_nx_info, current->nx_info); |
26514 |
++ sk->sk_nid = nx_current_nid(); |
26515 |
+ atomic_set(&sk->sk_refcnt, 1); |
26516 |
+ atomic_set(&sk->sk_drops, 0); |
26517 |
+ } |
26518 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/af_inet.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/af_inet.c |
26519 |
+--- linux-2.6.29.4/net/ipv4/af_inet.c 2009-03-24 14:22:46.000000000 +0100 |
26520 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/af_inet.c 2009-03-24 14:48:37.000000000 +0100 |
26521 |
+@@ -115,6 +115,7 @@ |
26522 |
+ #ifdef CONFIG_IP_MROUTE |
26523 |
+ #include <linux/mroute.h> |
26524 |
+ #endif |
26525 |
++#include <linux/vs_limit.h> |
26526 |
+ |
26527 |
+ extern void ip_mc_drop_socket(struct sock *sk); |
26528 |
+ |
26529 |
+@@ -325,9 +326,12 @@ lookup_protocol: |
26530 |
+ } |
26531 |
+ |
26532 |
+ err = -EPERM; |
26533 |
++ if ((protocol == IPPROTO_ICMP) && |
26534 |
++ nx_capable(answer->capability, NXC_RAW_ICMP)) |
26535 |
++ goto override; |
26536 |
+ if (answer->capability > 0 && !capable(answer->capability)) |
26537 |
+ goto out_rcu_unlock; |
26538 |
+- |
26539 |
++override: |
26540 |
+ err = -EAFNOSUPPORT; |
26541 |
+ if (!inet_netns_ok(net, protocol)) |
26542 |
+ goto out_rcu_unlock; |
26543 |
+@@ -445,6 +449,7 @@ int inet_bind(struct socket *sock, struc |
26544 |
+ struct sockaddr_in *addr = (struct sockaddr_in *)uaddr; |
26545 |
+ struct sock *sk = sock->sk; |
26546 |
+ struct inet_sock *inet = inet_sk(sk); |
26547 |
++ struct nx_v4_sock_addr nsa; |
26548 |
+ unsigned short snum; |
26549 |
+ int chk_addr_ret; |
26550 |
+ int err; |
26551 |
+@@ -458,7 +463,11 @@ int inet_bind(struct socket *sock, struc |
26552 |
+ if (addr_len < sizeof(struct sockaddr_in)) |
26553 |
+ goto out; |
26554 |
+ |
26555 |
+- chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); |
26556 |
++ err = v4_map_sock_addr(inet, addr, &nsa); |
26557 |
++ if (err) |
26558 |
++ goto out; |
26559 |
++ |
26560 |
++ chk_addr_ret = inet_addr_type(sock_net(sk), nsa.saddr); |
26561 |
+ |
26562 |
+ /* Not specified by any standard per-se, however it breaks too |
26563 |
+ * many applications when removed. It is unfortunate since |
26564 |
+@@ -470,7 +479,7 @@ int inet_bind(struct socket *sock, struc |
26565 |
+ err = -EADDRNOTAVAIL; |
26566 |
+ if (!sysctl_ip_nonlocal_bind && |
26567 |
+ !(inet->freebind || inet->transparent) && |
26568 |
+- addr->sin_addr.s_addr != htonl(INADDR_ANY) && |
26569 |
++ nsa.saddr != htonl(INADDR_ANY) && |
26570 |
+ chk_addr_ret != RTN_LOCAL && |
26571 |
+ chk_addr_ret != RTN_MULTICAST && |
26572 |
+ chk_addr_ret != RTN_BROADCAST) |
26573 |
+@@ -495,7 +504,7 @@ int inet_bind(struct socket *sock, struc |
26574 |
+ if (sk->sk_state != TCP_CLOSE || inet->num) |
26575 |
+ goto out_release_sock; |
26576 |
+ |
26577 |
+- inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr; |
26578 |
++ v4_set_sock_addr(inet, &nsa); |
26579 |
+ if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) |
26580 |
+ inet->saddr = 0; /* Use device */ |
26581 |
+ |
26582 |
+@@ -688,11 +697,13 @@ int inet_getname(struct socket *sock, st |
26583 |
+ peer == 1)) |
26584 |
+ return -ENOTCONN; |
26585 |
+ sin->sin_port = inet->dport; |
26586 |
+- sin->sin_addr.s_addr = inet->daddr; |
26587 |
++ sin->sin_addr.s_addr = |
26588 |
++ nx_map_sock_lback(sk->sk_nx_info, inet->daddr); |
26589 |
+ } else { |
26590 |
+ __be32 addr = inet->rcv_saddr; |
26591 |
+ if (!addr) |
26592 |
+ addr = inet->saddr; |
26593 |
++ addr = nx_map_sock_lback(sk->sk_nx_info, addr); |
26594 |
+ sin->sin_port = inet->sport; |
26595 |
+ sin->sin_addr.s_addr = addr; |
26596 |
+ } |
26597 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/devinet.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/devinet.c |
26598 |
+--- linux-2.6.29.4/net/ipv4/devinet.c 2009-03-24 14:22:46.000000000 +0100 |
26599 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/devinet.c 2009-03-24 14:48:37.000000000 +0100 |
26600 |
+@@ -413,6 +413,7 @@ struct in_device *inetdev_by_index(struc |
26601 |
+ return in_dev; |
26602 |
+ } |
26603 |
+ |
26604 |
++ |
26605 |
+ /* Called only from RTNL semaphored context. No locks. */ |
26606 |
+ |
26607 |
+ struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, |
26608 |
+@@ -653,6 +654,8 @@ int devinet_ioctl(struct net *net, unsig |
26609 |
+ *colon = ':'; |
26610 |
+ |
26611 |
+ if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { |
26612 |
++ struct nx_info *nxi = current->nx_info; |
26613 |
++ |
26614 |
+ if (tryaddrmatch) { |
26615 |
+ /* Matthias Andree */ |
26616 |
+ /* compare label and address (4.4BSD style) */ |
26617 |
+@@ -661,6 +664,8 @@ int devinet_ioctl(struct net *net, unsig |
26618 |
+ This is checked above. */ |
26619 |
+ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; |
26620 |
+ ifap = &ifa->ifa_next) { |
26621 |
++ if (!nx_v4_ifa_visible(nxi, ifa)) |
26622 |
++ continue; |
26623 |
+ if (!strcmp(ifr.ifr_name, ifa->ifa_label) && |
26624 |
+ sin_orig.sin_addr.s_addr == |
26625 |
+ ifa->ifa_address) { |
26626 |
+@@ -673,9 +678,12 @@ int devinet_ioctl(struct net *net, unsig |
26627 |
+ comparing just the label */ |
26628 |
+ if (!ifa) { |
26629 |
+ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; |
26630 |
+- ifap = &ifa->ifa_next) |
26631 |
++ ifap = &ifa->ifa_next) { |
26632 |
++ if (!nx_v4_ifa_visible(nxi, ifa)) |
26633 |
++ continue; |
26634 |
+ if (!strcmp(ifr.ifr_name, ifa->ifa_label)) |
26635 |
+ break; |
26636 |
++ } |
26637 |
+ } |
26638 |
+ } |
26639 |
+ |
26640 |
+@@ -826,6 +834,8 @@ static int inet_gifconf(struct net_devic |
26641 |
+ goto out; |
26642 |
+ |
26643 |
+ for (; ifa; ifa = ifa->ifa_next) { |
26644 |
++ if (!nx_v4_ifa_visible(current->nx_info, ifa)) |
26645 |
++ continue; |
26646 |
+ if (!buf) { |
26647 |
+ done += sizeof(ifr); |
26648 |
+ continue; |
26649 |
+@@ -1156,6 +1166,7 @@ static int inet_dump_ifaddr(struct sk_bu |
26650 |
+ struct net_device *dev; |
26651 |
+ struct in_device *in_dev; |
26652 |
+ struct in_ifaddr *ifa; |
26653 |
++ struct sock *sk = skb->sk; |
26654 |
+ int s_ip_idx, s_idx = cb->args[0]; |
26655 |
+ |
26656 |
+ s_ip_idx = ip_idx = cb->args[1]; |
26657 |
+@@ -1170,6 +1181,8 @@ static int inet_dump_ifaddr(struct sk_bu |
26658 |
+ |
26659 |
+ for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; |
26660 |
+ ifa = ifa->ifa_next, ip_idx++) { |
26661 |
++ if (sk && !nx_v4_ifa_visible(sk->sk_nx_info, ifa)) |
26662 |
++ continue; |
26663 |
+ if (ip_idx < s_ip_idx) |
26664 |
+ continue; |
26665 |
+ if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, |
26666 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/fib_hash.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/fib_hash.c |
26667 |
+--- linux-2.6.29.4/net/ipv4/fib_hash.c 2009-03-24 14:22:46.000000000 +0100 |
26668 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/fib_hash.c 2009-03-24 14:48:37.000000000 +0100 |
26669 |
+@@ -1022,7 +1022,7 @@ static int fib_seq_show(struct seq_file |
26670 |
+ prefix = f->fn_key; |
26671 |
+ mask = FZ_MASK(iter->zone); |
26672 |
+ flags = fib_flag_trans(fa->fa_type, mask, fi); |
26673 |
+- if (fi) |
26674 |
++ if (fi && nx_dev_visible(current->nx_info, fi->fib_dev)) |
26675 |
+ seq_printf(seq, |
26676 |
+ "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u%n", |
26677 |
+ fi->fib_dev ? fi->fib_dev->name : "*", prefix, |
26678 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/inet_connection_sock.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/inet_connection_sock.c |
26679 |
+--- linux-2.6.29.4/net/ipv4/inet_connection_sock.c 2009-03-24 14:22:46.000000000 +0100 |
26680 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/inet_connection_sock.c 2009-03-24 14:48:37.000000000 +0100 |
26681 |
+@@ -49,10 +49,40 @@ void inet_get_local_port_range(int *low, |
26682 |
+ } |
26683 |
+ EXPORT_SYMBOL(inet_get_local_port_range); |
26684 |
+ |
26685 |
++int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) |
26686 |
++{ |
26687 |
++ __be32 sk1_rcv_saddr = inet_rcv_saddr(sk1), |
26688 |
++ sk2_rcv_saddr = inet_rcv_saddr(sk2); |
26689 |
++ |
26690 |
++ if (inet_v6_ipv6only(sk2)) |
26691 |
++ return 0; |
26692 |
++ |
26693 |
++ if (sk1_rcv_saddr && |
26694 |
++ sk2_rcv_saddr && |
26695 |
++ sk1_rcv_saddr == sk2_rcv_saddr) |
26696 |
++ return 1; |
26697 |
++ |
26698 |
++ if (sk1_rcv_saddr && |
26699 |
++ !sk2_rcv_saddr && |
26700 |
++ v4_addr_in_nx_info(sk2->sk_nx_info, sk1_rcv_saddr, NXA_MASK_BIND)) |
26701 |
++ return 1; |
26702 |
++ |
26703 |
++ if (sk2_rcv_saddr && |
26704 |
++ !sk1_rcv_saddr && |
26705 |
++ v4_addr_in_nx_info(sk1->sk_nx_info, sk2_rcv_saddr, NXA_MASK_BIND)) |
26706 |
++ return 1; |
26707 |
++ |
26708 |
++ if (!sk1_rcv_saddr && |
26709 |
++ !sk2_rcv_saddr && |
26710 |
++ nx_v4_addr_conflict(sk1->sk_nx_info, sk2->sk_nx_info)) |
26711 |
++ return 1; |
26712 |
++ |
26713 |
++ return 0; |
26714 |
++} |
26715 |
++ |
26716 |
+ int inet_csk_bind_conflict(const struct sock *sk, |
26717 |
+ const struct inet_bind_bucket *tb) |
26718 |
+ { |
26719 |
+- const __be32 sk_rcv_saddr = inet_rcv_saddr(sk); |
26720 |
+ struct sock *sk2; |
26721 |
+ struct hlist_node *node; |
26722 |
+ int reuse = sk->sk_reuse; |
26723 |
+@@ -72,9 +102,7 @@ int inet_csk_bind_conflict(const struct |
26724 |
+ sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { |
26725 |
+ if (!reuse || !sk2->sk_reuse || |
26726 |
+ sk2->sk_state == TCP_LISTEN) { |
26727 |
+- const __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2); |
26728 |
+- if (!sk2_rcv_saddr || !sk_rcv_saddr || |
26729 |
+- sk2_rcv_saddr == sk_rcv_saddr) |
26730 |
++ if (ipv4_rcv_saddr_equal(sk, sk2)) |
26731 |
+ break; |
26732 |
+ } |
26733 |
+ } |
26734 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/inet_diag.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/inet_diag.c |
26735 |
+--- linux-2.6.29.4/net/ipv4/inet_diag.c 2009-03-24 14:22:46.000000000 +0100 |
26736 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/inet_diag.c 2009-03-24 14:48:37.000000000 +0100 |
26737 |
+@@ -32,6 +32,8 @@ |
26738 |
+ #include <linux/stddef.h> |
26739 |
+ |
26740 |
+ #include <linux/inet_diag.h> |
26741 |
++#include <linux/vs_network.h> |
26742 |
++#include <linux/vs_inet.h> |
26743 |
+ |
26744 |
+ static const struct inet_diag_handler **inet_diag_table; |
26745 |
+ |
26746 |
+@@ -118,8 +120,8 @@ static int inet_csk_diag_fill(struct soc |
26747 |
+ |
26748 |
+ r->id.idiag_sport = inet->sport; |
26749 |
+ r->id.idiag_dport = inet->dport; |
26750 |
+- r->id.idiag_src[0] = inet->rcv_saddr; |
26751 |
+- r->id.idiag_dst[0] = inet->daddr; |
26752 |
++ r->id.idiag_src[0] = nx_map_sock_lback(sk->sk_nx_info, inet->rcv_saddr); |
26753 |
++ r->id.idiag_dst[0] = nx_map_sock_lback(sk->sk_nx_info, inet->daddr); |
26754 |
+ |
26755 |
+ #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) |
26756 |
+ if (r->idiag_family == AF_INET6) { |
26757 |
+@@ -206,8 +208,8 @@ static int inet_twsk_diag_fill(struct in |
26758 |
+ r->id.idiag_cookie[1] = (u32)(((unsigned long)tw >> 31) >> 1); |
26759 |
+ r->id.idiag_sport = tw->tw_sport; |
26760 |
+ r->id.idiag_dport = tw->tw_dport; |
26761 |
+- r->id.idiag_src[0] = tw->tw_rcv_saddr; |
26762 |
+- r->id.idiag_dst[0] = tw->tw_daddr; |
26763 |
++ r->id.idiag_src[0] = nx_map_sock_lback(tw->tw_nx_info, tw->tw_rcv_saddr); |
26764 |
++ r->id.idiag_dst[0] = nx_map_sock_lback(tw->tw_nx_info, tw->tw_daddr); |
26765 |
+ r->idiag_state = tw->tw_substate; |
26766 |
+ r->idiag_timer = 3; |
26767 |
+ r->idiag_expires = DIV_ROUND_UP(tmo * 1000, HZ); |
26768 |
+@@ -264,6 +266,7 @@ static int inet_diag_get_exact(struct sk |
26769 |
+ err = -EINVAL; |
26770 |
+ |
26771 |
+ if (req->idiag_family == AF_INET) { |
26772 |
++ /* TODO: lback */ |
26773 |
+ sk = inet_lookup(&init_net, hashinfo, req->id.idiag_dst[0], |
26774 |
+ req->id.idiag_dport, req->id.idiag_src[0], |
26775 |
+ req->id.idiag_sport, req->id.idiag_if); |
26776 |
+@@ -506,6 +509,7 @@ static int inet_csk_diag_dump(struct soc |
26777 |
+ } else |
26778 |
+ #endif |
26779 |
+ { |
26780 |
++ /* TODO: lback */ |
26781 |
+ entry.saddr = &inet->rcv_saddr; |
26782 |
+ entry.daddr = &inet->daddr; |
26783 |
+ } |
26784 |
+@@ -542,6 +546,7 @@ static int inet_twsk_diag_dump(struct in |
26785 |
+ } else |
26786 |
+ #endif |
26787 |
+ { |
26788 |
++ /* TODO: lback */ |
26789 |
+ entry.saddr = &tw->tw_rcv_saddr; |
26790 |
+ entry.daddr = &tw->tw_daddr; |
26791 |
+ } |
26792 |
+@@ -588,8 +593,8 @@ static int inet_diag_fill_req(struct sk_ |
26793 |
+ |
26794 |
+ r->id.idiag_sport = inet->sport; |
26795 |
+ r->id.idiag_dport = ireq->rmt_port; |
26796 |
+- r->id.idiag_src[0] = ireq->loc_addr; |
26797 |
+- r->id.idiag_dst[0] = ireq->rmt_addr; |
26798 |
++ r->id.idiag_src[0] = nx_map_sock_lback(sk->sk_nx_info, ireq->loc_addr); |
26799 |
++ r->id.idiag_dst[0] = nx_map_sock_lback(sk->sk_nx_info, ireq->rmt_addr); |
26800 |
+ r->idiag_expires = jiffies_to_msecs(tmo); |
26801 |
+ r->idiag_rqueue = 0; |
26802 |
+ r->idiag_wqueue = 0; |
26803 |
+@@ -659,6 +664,7 @@ static int inet_diag_dump_reqs(struct sk |
26804 |
+ continue; |
26805 |
+ |
26806 |
+ if (bc) { |
26807 |
++ /* TODO: lback */ |
26808 |
+ entry.saddr = |
26809 |
+ #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) |
26810 |
+ (entry.family == AF_INET6) ? |
26811 |
+@@ -729,6 +735,8 @@ static int inet_diag_dump(struct sk_buff |
26812 |
+ sk_nulls_for_each(sk, node, &ilb->head) { |
26813 |
+ struct inet_sock *inet = inet_sk(sk); |
26814 |
+ |
26815 |
++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)) |
26816 |
++ continue; |
26817 |
+ if (num < s_num) { |
26818 |
+ num++; |
26819 |
+ continue; |
26820 |
+@@ -795,6 +803,8 @@ skip_listen_ht: |
26821 |
+ sk_nulls_for_each(sk, node, &head->chain) { |
26822 |
+ struct inet_sock *inet = inet_sk(sk); |
26823 |
+ |
26824 |
++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)) |
26825 |
++ continue; |
26826 |
+ if (num < s_num) |
26827 |
+ goto next_normal; |
26828 |
+ if (!(r->idiag_states & (1 << sk->sk_state))) |
26829 |
+@@ -819,6 +829,8 @@ next_normal: |
26830 |
+ inet_twsk_for_each(tw, node, |
26831 |
+ &head->twchain) { |
26832 |
+ |
26833 |
++ if (!nx_check(tw->tw_nid, VS_WATCH_P | VS_IDENT)) |
26834 |
++ continue; |
26835 |
+ if (num < s_num) |
26836 |
+ goto next_dying; |
26837 |
+ if (r->id.idiag_sport != tw->tw_sport && |
26838 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/inet_hashtables.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/inet_hashtables.c |
26839 |
+--- linux-2.6.29.4/net/ipv4/inet_hashtables.c 2009-03-24 14:22:46.000000000 +0100 |
26840 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/inet_hashtables.c 2009-04-17 15:35:48.000000000 +0200 |
26841 |
+@@ -21,6 +21,7 @@ |
26842 |
+ |
26843 |
+ #include <net/inet_connection_sock.h> |
26844 |
+ #include <net/inet_hashtables.h> |
26845 |
++#include <net/route.h> |
26846 |
+ #include <net/ip.h> |
26847 |
+ |
26848 |
+ /* |
26849 |
+@@ -125,6 +126,11 @@ static inline int compute_score(struct s |
26850 |
+ if (rcv_saddr != daddr) |
26851 |
+ return -1; |
26852 |
+ score += 2; |
26853 |
++ } else { |
26854 |
++ /* block non nx_info ips */ |
26855 |
++ if (!v4_addr_in_nx_info(sk->sk_nx_info, |
26856 |
++ daddr, NXA_MASK_BIND)) |
26857 |
++ return -1; |
26858 |
+ } |
26859 |
+ if (sk->sk_bound_dev_if) { |
26860 |
+ if (sk->sk_bound_dev_if != dif) |
26861 |
+@@ -142,7 +148,6 @@ static inline int compute_score(struct s |
26862 |
+ * wildcarded during the search since they can never be otherwise. |
26863 |
+ */ |
26864 |
+ |
26865 |
+- |
26866 |
+ struct sock *__inet_lookup_listener(struct net *net, |
26867 |
+ struct inet_hashinfo *hashinfo, |
26868 |
+ const __be32 daddr, const unsigned short hnum, |
26869 |
+@@ -165,6 +170,7 @@ begin: |
26870 |
+ hiscore = score; |
26871 |
+ } |
26872 |
+ } |
26873 |
++ |
26874 |
+ /* |
26875 |
+ * if the nulls value we got at the end of this lookup is |
26876 |
+ * not the expected one, we must restart lookup. |
26877 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/netfilter/nf_nat_helper.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/netfilter/nf_nat_helper.c |
26878 |
+--- linux-2.6.29.4/net/ipv4/netfilter/nf_nat_helper.c 2008-12-25 00:26:37.000000000 +0100 |
26879 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/netfilter/nf_nat_helper.c 2009-02-22 22:54:26.000000000 +0100 |
26880 |
+@@ -19,6 +19,7 @@ |
26881 |
+ #include <net/route.h> |
26882 |
+ |
26883 |
+ #include <linux/netfilter_ipv4.h> |
26884 |
++#include <net/route.h> |
26885 |
+ #include <net/netfilter/nf_conntrack.h> |
26886 |
+ #include <net/netfilter/nf_conntrack_helper.h> |
26887 |
+ #include <net/netfilter/nf_conntrack_ecache.h> |
26888 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/netfilter.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/netfilter.c |
26889 |
+--- linux-2.6.29.4/net/ipv4/netfilter.c 2009-03-24 14:22:46.000000000 +0100 |
26890 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/netfilter.c 2009-03-24 14:48:37.000000000 +0100 |
26891 |
+@@ -4,7 +4,7 @@ |
26892 |
+ #include <linux/netfilter_ipv4.h> |
26893 |
+ #include <linux/ip.h> |
26894 |
+ #include <linux/skbuff.h> |
26895 |
+-#include <net/route.h> |
26896 |
++// #include <net/route.h> |
26897 |
+ #include <net/xfrm.h> |
26898 |
+ #include <net/ip.h> |
26899 |
+ #include <net/netfilter/nf_queue.h> |
26900 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/raw.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/raw.c |
26901 |
+--- linux-2.6.29.4/net/ipv4/raw.c 2009-03-24 14:22:46.000000000 +0100 |
26902 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/raw.c 2009-03-24 14:48:37.000000000 +0100 |
26903 |
+@@ -117,7 +117,7 @@ static struct sock *__raw_v4_lookup(stru |
26904 |
+ |
26905 |
+ if (net_eq(sock_net(sk), net) && inet->num == num && |
26906 |
+ !(inet->daddr && inet->daddr != raddr) && |
26907 |
+- !(inet->rcv_saddr && inet->rcv_saddr != laddr) && |
26908 |
++ v4_sock_addr_match(sk->sk_nx_info, inet, laddr) && |
26909 |
+ !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) |
26910 |
+ goto found; /* gotcha */ |
26911 |
+ } |
26912 |
+@@ -372,6 +372,12 @@ static int raw_send_hdrinc(struct sock * |
26913 |
+ icmp_out_count(net, ((struct icmphdr *) |
26914 |
+ skb_transport_header(skb))->type); |
26915 |
+ |
26916 |
++ err = -EPERM; |
26917 |
++ if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW) && |
26918 |
++ sk->sk_nx_info && |
26919 |
++ !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND)) |
26920 |
++ goto error_free; |
26921 |
++ |
26922 |
+ err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, |
26923 |
+ dst_output); |
26924 |
+ if (err > 0) |
26925 |
+@@ -383,6 +389,7 @@ out: |
26926 |
+ |
26927 |
+ error_fault: |
26928 |
+ err = -EFAULT; |
26929 |
++error_free: |
26930 |
+ kfree_skb(skb); |
26931 |
+ error: |
26932 |
+ IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS); |
26933 |
+@@ -550,6 +557,13 @@ static int raw_sendmsg(struct kiocb *ioc |
26934 |
+ } |
26935 |
+ |
26936 |
+ security_sk_classify_flow(sk, &fl); |
26937 |
++ if (sk->sk_nx_info) { |
26938 |
++ err = ip_v4_find_src(sock_net(sk), |
26939 |
++ sk->sk_nx_info, &rt, &fl); |
26940 |
++ |
26941 |
++ if (err) |
26942 |
++ goto done; |
26943 |
++ } |
26944 |
+ err = ip_route_output_flow(sock_net(sk), &rt, &fl, sk, 1); |
26945 |
+ } |
26946 |
+ if (err) |
26947 |
+@@ -619,17 +633,19 @@ static int raw_bind(struct sock *sk, str |
26948 |
+ { |
26949 |
+ struct inet_sock *inet = inet_sk(sk); |
26950 |
+ struct sockaddr_in *addr = (struct sockaddr_in *) uaddr; |
26951 |
++ struct nx_v4_sock_addr nsa = { 0 }; |
26952 |
+ int ret = -EINVAL; |
26953 |
+ int chk_addr_ret; |
26954 |
+ |
26955 |
+ if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in)) |
26956 |
+ goto out; |
26957 |
+- chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); |
26958 |
++ v4_map_sock_addr(inet, addr, &nsa); |
26959 |
++ chk_addr_ret = inet_addr_type(sock_net(sk), nsa.saddr); |
26960 |
+ ret = -EADDRNOTAVAIL; |
26961 |
+- if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL && |
26962 |
++ if (nsa.saddr && chk_addr_ret != RTN_LOCAL && |
26963 |
+ chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) |
26964 |
+ goto out; |
26965 |
+- inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr; |
26966 |
++ v4_set_sock_addr(inet, &nsa); |
26967 |
+ if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) |
26968 |
+ inet->saddr = 0; /* Use device */ |
26969 |
+ sk_dst_reset(sk); |
26970 |
+@@ -681,7 +697,8 @@ static int raw_recvmsg(struct kiocb *ioc |
26971 |
+ /* Copy the address. */ |
26972 |
+ if (sin) { |
26973 |
+ sin->sin_family = AF_INET; |
26974 |
+- sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
26975 |
++ sin->sin_addr.s_addr = |
26976 |
++ nx_map_sock_lback(sk->sk_nx_info, ip_hdr(skb)->saddr); |
26977 |
+ sin->sin_port = 0; |
26978 |
+ memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); |
26979 |
+ } |
26980 |
+@@ -858,7 +875,8 @@ static struct sock *raw_get_first(struct |
26981 |
+ struct hlist_node *node; |
26982 |
+ |
26983 |
+ sk_for_each(sk, node, &state->h->ht[state->bucket]) |
26984 |
+- if (sock_net(sk) == seq_file_net(seq)) |
26985 |
++ if ((sock_net(sk) == seq_file_net(seq)) && |
26986 |
++ nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)) |
26987 |
+ goto found; |
26988 |
+ } |
26989 |
+ sk = NULL; |
26990 |
+@@ -874,7 +892,8 @@ static struct sock *raw_get_next(struct |
26991 |
+ sk = sk_next(sk); |
26992 |
+ try_again: |
26993 |
+ ; |
26994 |
+- } while (sk && sock_net(sk) != seq_file_net(seq)); |
26995 |
++ } while (sk && ((sock_net(sk) != seq_file_net(seq)) || |
26996 |
++ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))); |
26997 |
+ |
26998 |
+ if (!sk && ++state->bucket < RAW_HTABLE_SIZE) { |
26999 |
+ sk = sk_head(&state->h->ht[state->bucket]); |
27000 |
+@@ -933,7 +952,10 @@ static void raw_sock_seq_show(struct seq |
27001 |
+ |
27002 |
+ seq_printf(seq, "%4d: %08X:%04X %08X:%04X" |
27003 |
+ " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", |
27004 |
+- i, src, srcp, dest, destp, sp->sk_state, |
27005 |
++ i, |
27006 |
++ nx_map_sock_lback(current_nx_info(), src), srcp, |
27007 |
++ nx_map_sock_lback(current_nx_info(), dest), destp, |
27008 |
++ sp->sk_state, |
27009 |
+ atomic_read(&sp->sk_wmem_alloc), |
27010 |
+ atomic_read(&sp->sk_rmem_alloc), |
27011 |
+ 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), |
27012 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/tcp.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/tcp.c |
27013 |
+--- linux-2.6.29.4/net/ipv4/tcp.c 2009-03-24 14:22:46.000000000 +0100 |
27014 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/tcp.c 2009-03-24 14:48:37.000000000 +0100 |
27015 |
+@@ -264,6 +264,7 @@ |
27016 |
+ #include <linux/cache.h> |
27017 |
+ #include <linux/err.h> |
27018 |
+ #include <linux/crypto.h> |
27019 |
++#include <linux/in.h> |
27020 |
+ |
27021 |
+ #include <net/icmp.h> |
27022 |
+ #include <net/tcp.h> |
27023 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/tcp_ipv4.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/tcp_ipv4.c |
27024 |
+--- linux-2.6.29.4/net/ipv4/tcp_ipv4.c 2009-05-23 23:16:53.000000000 +0200 |
27025 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/tcp_ipv4.c 2009-05-23 23:19:11.000000000 +0200 |
27026 |
+@@ -1895,6 +1895,12 @@ static void *listening_get_next(struct s |
27027 |
+ req = req->dl_next; |
27028 |
+ while (1) { |
27029 |
+ while (req) { |
27030 |
++ vxdprintk(VXD_CBIT(net, 6), |
27031 |
++ "sk,req: %p [#%d] (from %d)", req->sk, |
27032 |
++ (req->sk)?req->sk->sk_nid:0, nx_current_nid()); |
27033 |
++ if (req->sk && |
27034 |
++ !nx_check(req->sk->sk_nid, VS_WATCH_P | VS_IDENT)) |
27035 |
++ continue; |
27036 |
+ if (req->rsk_ops->family == st->family) { |
27037 |
+ cur = req; |
27038 |
+ goto out; |
27039 |
+@@ -1919,6 +1925,10 @@ get_req: |
27040 |
+ } |
27041 |
+ get_sk: |
27042 |
+ sk_nulls_for_each_from(sk, node) { |
27043 |
++ vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)", |
27044 |
++ sk, sk->sk_nid, nx_current_nid()); |
27045 |
++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)) |
27046 |
++ continue; |
27047 |
+ if (sk->sk_family == st->family && net_eq(sock_net(sk), net)) { |
27048 |
+ cur = sk; |
27049 |
+ goto out; |
27050 |
+@@ -1982,6 +1992,11 @@ static void *established_get_first(struc |
27051 |
+ |
27052 |
+ spin_lock_bh(lock); |
27053 |
+ sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) { |
27054 |
++ vxdprintk(VXD_CBIT(net, 6), |
27055 |
++ "sk,egf: %p [#%d] (from %d)", |
27056 |
++ sk, sk->sk_nid, nx_current_nid()); |
27057 |
++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)) |
27058 |
++ continue; |
27059 |
+ if (sk->sk_family != st->family || |
27060 |
+ !net_eq(sock_net(sk), net)) { |
27061 |
+ continue; |
27062 |
+@@ -1992,6 +2007,11 @@ static void *established_get_first(struc |
27063 |
+ st->state = TCP_SEQ_STATE_TIME_WAIT; |
27064 |
+ inet_twsk_for_each(tw, node, |
27065 |
+ &tcp_hashinfo.ehash[st->bucket].twchain) { |
27066 |
++ vxdprintk(VXD_CBIT(net, 6), |
27067 |
++ "tw: %p [#%d] (from %d)", |
27068 |
++ tw, tw->tw_nid, nx_current_nid()); |
27069 |
++ if (!nx_check(tw->tw_nid, VS_WATCH_P | VS_IDENT)) |
27070 |
++ continue; |
27071 |
+ if (tw->tw_family != st->family || |
27072 |
+ !net_eq(twsk_net(tw), net)) { |
27073 |
+ continue; |
27074 |
+@@ -2020,7 +2040,9 @@ static void *established_get_next(struct |
27075 |
+ tw = cur; |
27076 |
+ tw = tw_next(tw); |
27077 |
+ get_tw: |
27078 |
+- while (tw && (tw->tw_family != st->family || !net_eq(twsk_net(tw), net))) { |
27079 |
++ while (tw && (tw->tw_family != st->family || |
27080 |
++ !net_eq(twsk_net(tw), net) || |
27081 |
++ !nx_check(tw->tw_nid, VS_WATCH_P | VS_IDENT))) { |
27082 |
+ tw = tw_next(tw); |
27083 |
+ } |
27084 |
+ if (tw) { |
27085 |
+@@ -2043,6 +2065,11 @@ get_tw: |
27086 |
+ sk = sk_nulls_next(sk); |
27087 |
+ |
27088 |
+ sk_nulls_for_each_from(sk, node) { |
27089 |
++ vxdprintk(VXD_CBIT(net, 6), |
27090 |
++ "sk,egn: %p [#%d] (from %d)", |
27091 |
++ sk, sk->sk_nid, nx_current_nid()); |
27092 |
++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)) |
27093 |
++ continue; |
27094 |
+ if (sk->sk_family == st->family && net_eq(sock_net(sk), net)) |
27095 |
+ goto found; |
27096 |
+ } |
27097 |
+@@ -2194,9 +2221,9 @@ static void get_openreq4(struct sock *sk |
27098 |
+ seq_printf(f, "%4d: %08X:%04X %08X:%04X" |
27099 |
+ " %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p%n", |
27100 |
+ i, |
27101 |
+- ireq->loc_addr, |
27102 |
++ nx_map_sock_lback(current_nx_info(), ireq->loc_addr), |
27103 |
+ ntohs(inet_sk(sk)->sport), |
27104 |
+- ireq->rmt_addr, |
27105 |
++ nx_map_sock_lback(current_nx_info(), ireq->rmt_addr), |
27106 |
+ ntohs(ireq->rmt_port), |
27107 |
+ TCP_SYN_RECV, |
27108 |
+ 0, 0, /* could print option size, but that is af dependent. */ |
27109 |
+@@ -2239,7 +2266,10 @@ static void get_tcp4_sock(struct sock *s |
27110 |
+ |
27111 |
+ seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " |
27112 |
+ "%08X %5d %8d %lu %d %p %lu %lu %u %u %d%n", |
27113 |
+- i, src, srcp, dest, destp, sk->sk_state, |
27114 |
++ i, |
27115 |
++ nx_map_sock_lback(current_nx_info(), src), srcp, |
27116 |
++ nx_map_sock_lback(current_nx_info(), dest), destp, |
27117 |
++ sk->sk_state, |
27118 |
+ tp->write_seq - tp->snd_una, |
27119 |
+ sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog : |
27120 |
+ (tp->rcv_nxt - tp->copied_seq), |
27121 |
+@@ -2275,7 +2305,10 @@ static void get_timewait4_sock(struct in |
27122 |
+ |
27123 |
+ seq_printf(f, "%4d: %08X:%04X %08X:%04X" |
27124 |
+ " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p%n", |
27125 |
+- i, src, srcp, dest, destp, tw->tw_substate, 0, 0, |
27126 |
++ i, |
27127 |
++ nx_map_sock_lback(current_nx_info(), src), srcp, |
27128 |
++ nx_map_sock_lback(current_nx_info(), dest), destp, |
27129 |
++ tw->tw_substate, 0, 0, |
27130 |
+ 3, jiffies_to_clock_t(ttd), 0, 0, 0, 0, |
27131 |
+ atomic_read(&tw->tw_refcnt), tw, len); |
27132 |
+ } |
27133 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/tcp_minisocks.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/tcp_minisocks.c |
27134 |
+--- linux-2.6.29.4/net/ipv4/tcp_minisocks.c 2009-03-24 14:22:46.000000000 +0100 |
27135 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/tcp_minisocks.c 2009-03-24 14:48:37.000000000 +0100 |
27136 |
+@@ -26,6 +26,10 @@ |
27137 |
+ #include <net/inet_common.h> |
27138 |
+ #include <net/xfrm.h> |
27139 |
+ |
27140 |
++#include <linux/vs_limit.h> |
27141 |
++#include <linux/vs_socket.h> |
27142 |
++#include <linux/vs_context.h> |
27143 |
++ |
27144 |
+ #ifdef CONFIG_SYSCTL |
27145 |
+ #define SYNC_INIT 0 /* let the user enable it */ |
27146 |
+ #else |
27147 |
+@@ -293,6 +297,11 @@ void tcp_time_wait(struct sock *sk, int |
27148 |
+ tcptw->tw_ts_recent = tp->rx_opt.ts_recent; |
27149 |
+ tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp; |
27150 |
+ |
27151 |
++ tw->tw_xid = sk->sk_xid; |
27152 |
++ tw->tw_vx_info = NULL; |
27153 |
++ tw->tw_nid = sk->sk_nid; |
27154 |
++ tw->tw_nx_info = NULL; |
27155 |
++ |
27156 |
+ #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
27157 |
+ if (tw->tw_family == PF_INET6) { |
27158 |
+ struct ipv6_pinfo *np = inet6_sk(sk); |
27159 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv4/udp.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/udp.c |
27160 |
+--- linux-2.6.29.4/net/ipv4/udp.c 2009-05-23 23:16:53.000000000 +0200 |
27161 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv4/udp.c 2009-04-15 22:58:30.000000000 +0200 |
27162 |
+@@ -222,14 +222,7 @@ fail: |
27163 |
+ return error; |
27164 |
+ } |
27165 |
+ |
27166 |
+-static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) |
27167 |
+-{ |
27168 |
+- struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); |
27169 |
+- |
27170 |
+- return ( !ipv6_only_sock(sk2) && |
27171 |
+- (!inet1->rcv_saddr || !inet2->rcv_saddr || |
27172 |
+- inet1->rcv_saddr == inet2->rcv_saddr )); |
27173 |
+-} |
27174 |
++extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *); |
27175 |
+ |
27176 |
+ int udp_v4_get_port(struct sock *sk, unsigned short snum) |
27177 |
+ { |
27178 |
+@@ -251,6 +244,11 @@ static inline int compute_score(struct s |
27179 |
+ if (inet->rcv_saddr != daddr) |
27180 |
+ return -1; |
27181 |
+ score += 2; |
27182 |
++ } else { |
27183 |
++ /* block non nx_info ips */ |
27184 |
++ if (!v4_addr_in_nx_info(sk->sk_nx_info, |
27185 |
++ daddr, NXA_MASK_BIND)) |
27186 |
++ return -1; |
27187 |
+ } |
27188 |
+ if (inet->daddr) { |
27189 |
+ if (inet->daddr != saddr) |
27190 |
+@@ -271,6 +269,7 @@ static inline int compute_score(struct s |
27191 |
+ return score; |
27192 |
+ } |
27193 |
+ |
27194 |
++ |
27195 |
+ /* UDP is nearly always wildcards out the wazoo, it makes no sense to try |
27196 |
+ * harder than this. -DaveM |
27197 |
+ */ |
27198 |
+@@ -292,6 +291,11 @@ begin: |
27199 |
+ sk_nulls_for_each_rcu(sk, node, &hslot->head) { |
27200 |
+ score = compute_score(sk, net, saddr, hnum, sport, |
27201 |
+ daddr, dport, dif); |
27202 |
++ /* FIXME: disabled? |
27203 |
++ if (score == 9) { |
27204 |
++ result = sk; |
27205 |
++ break; |
27206 |
++ } else */ |
27207 |
+ if (score > badness) { |
27208 |
+ result = sk; |
27209 |
+ badness = score; |
27210 |
+@@ -305,6 +309,7 @@ begin: |
27211 |
+ if (get_nulls_value(node) != hash) |
27212 |
+ goto begin; |
27213 |
+ |
27214 |
++ |
27215 |
+ if (result) { |
27216 |
+ if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) |
27217 |
+ result = NULL; |
27218 |
+@@ -314,6 +319,7 @@ begin: |
27219 |
+ goto begin; |
27220 |
+ } |
27221 |
+ } |
27222 |
++ |
27223 |
+ rcu_read_unlock(); |
27224 |
+ return result; |
27225 |
+ } |
27226 |
+@@ -356,7 +362,7 @@ static inline struct sock *udp_v4_mcast_ |
27227 |
+ s->sk_hash != hnum || |
27228 |
+ (inet->daddr && inet->daddr != rmt_addr) || |
27229 |
+ (inet->dport != rmt_port && inet->dport) || |
27230 |
+- (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || |
27231 |
++ !v4_sock_addr_match(sk->sk_nx_info, inet, loc_addr) || |
27232 |
+ ipv6_only_sock(s) || |
27233 |
+ (s->sk_bound_dev_if && s->sk_bound_dev_if != dif)) |
27234 |
+ continue; |
27235 |
+@@ -694,8 +700,13 @@ int udp_sendmsg(struct kiocb *iocb, stru |
27236 |
+ { .sport = inet->sport, |
27237 |
+ .dport = dport } } }; |
27238 |
+ struct net *net = sock_net(sk); |
27239 |
++ struct nx_info *nxi = sk->sk_nx_info; |
27240 |
+ |
27241 |
+ security_sk_classify_flow(sk, &fl); |
27242 |
++ err = ip_v4_find_src(net, nxi, &rt, &fl); |
27243 |
++ if (err) |
27244 |
++ goto out; |
27245 |
++ |
27246 |
+ err = ip_route_output_flow(net, &rt, &fl, sk, 1); |
27247 |
+ if (err) { |
27248 |
+ if (err == -ENETUNREACH) |
27249 |
+@@ -940,7 +951,8 @@ try_again: |
27250 |
+ { |
27251 |
+ sin->sin_family = AF_INET; |
27252 |
+ sin->sin_port = udp_hdr(skb)->source; |
27253 |
+- sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
27254 |
++ sin->sin_addr.s_addr = nx_map_sock_lback( |
27255 |
++ skb->sk->sk_nx_info, ip_hdr(skb)->saddr); |
27256 |
+ memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); |
27257 |
+ } |
27258 |
+ if (inet->cmsg_flags) |
27259 |
+@@ -1594,6 +1606,8 @@ static struct sock *udp_get_first(struct |
27260 |
+ sk_nulls_for_each(sk, node, &hslot->head) { |
27261 |
+ if (!net_eq(sock_net(sk), net)) |
27262 |
+ continue; |
27263 |
++ if (!nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT)) |
27264 |
++ continue; |
27265 |
+ if (sk->sk_family == state->family) |
27266 |
+ goto found; |
27267 |
+ } |
27268 |
+@@ -1611,7 +1625,9 @@ static struct sock *udp_get_next(struct |
27269 |
+ |
27270 |
+ do { |
27271 |
+ sk = sk_nulls_next(sk); |
27272 |
+- } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family)); |
27273 |
++ } while (sk && (!net_eq(sock_net(sk), net) || |
27274 |
++ sk->sk_family != state->family || |
27275 |
++ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))); |
27276 |
+ |
27277 |
+ if (!sk) { |
27278 |
+ if (state->bucket < UDP_HTABLE_SIZE) |
27279 |
+@@ -1716,7 +1732,10 @@ static void udp4_format_sock(struct sock |
27280 |
+ |
27281 |
+ seq_printf(f, "%4d: %08X:%04X %08X:%04X" |
27282 |
+ " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n", |
27283 |
+- bucket, src, srcp, dest, destp, sp->sk_state, |
27284 |
++ bucket, |
27285 |
++ nx_map_sock_lback(current_nx_info(), src), srcp, |
27286 |
++ nx_map_sock_lback(current_nx_info(), dest), destp, |
27287 |
++ sp->sk_state, |
27288 |
+ atomic_read(&sp->sk_wmem_alloc), |
27289 |
+ atomic_read(&sp->sk_rmem_alloc), |
27290 |
+ 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), |
27291 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/addrconf.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/addrconf.c |
27292 |
+--- linux-2.6.29.4/net/ipv6/addrconf.c 2009-03-24 14:22:46.000000000 +0100 |
27293 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/addrconf.c 2009-03-24 20:39:23.000000000 +0100 |
27294 |
+@@ -85,6 +85,8 @@ |
27295 |
+ |
27296 |
+ #include <linux/proc_fs.h> |
27297 |
+ #include <linux/seq_file.h> |
27298 |
++#include <linux/vs_network.h> |
27299 |
++#include <linux/vs_inet6.h> |
27300 |
+ |
27301 |
+ /* Set to 3 to get tracing... */ |
27302 |
+ #define ACONF_DEBUG 2 |
27303 |
+@@ -1111,7 +1113,7 @@ out: |
27304 |
+ |
27305 |
+ int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev, |
27306 |
+ const struct in6_addr *daddr, unsigned int prefs, |
27307 |
+- struct in6_addr *saddr) |
27308 |
++ struct in6_addr *saddr, struct nx_info *nxi) |
27309 |
+ { |
27310 |
+ struct ipv6_saddr_score scores[2], |
27311 |
+ *score = &scores[0], *hiscore = &scores[1]; |
27312 |
+@@ -1184,6 +1186,8 @@ int ipv6_dev_get_saddr(struct net *net, |
27313 |
+ dev->name); |
27314 |
+ continue; |
27315 |
+ } |
27316 |
++ if (!v6_addr_in_nx_info(nxi, &score->ifa->addr, -1)) |
27317 |
++ continue; |
27318 |
+ |
27319 |
+ score->rule = -1; |
27320 |
+ bitmap_zero(score->scorebits, IPV6_SADDR_RULE_MAX); |
27321 |
+@@ -1367,35 +1371,46 @@ struct inet6_ifaddr *ipv6_get_ifaddr(str |
27322 |
+ return ifp; |
27323 |
+ } |
27324 |
+ |
27325 |
++extern int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2); |
27326 |
++ |
27327 |
+ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) |
27328 |
+ { |
27329 |
+ const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr; |
27330 |
+ const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2); |
27331 |
+- __be32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr; |
27332 |
+ __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2); |
27333 |
+ int sk_ipv6only = ipv6_only_sock(sk); |
27334 |
+ int sk2_ipv6only = inet_v6_ipv6only(sk2); |
27335 |
+ int addr_type = ipv6_addr_type(sk_rcv_saddr6); |
27336 |
+ int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED; |
27337 |
+ |
27338 |
+- if (!sk2_rcv_saddr && !sk_ipv6only) |
27339 |
++ /* FIXME: needs handling for v4 ANY */ |
27340 |
++ if (!sk2_rcv_saddr && !sk_ipv6only && !sk2->sk_nx_info) |
27341 |
+ return 1; |
27342 |
+ |
27343 |
+ if (addr_type2 == IPV6_ADDR_ANY && |
27344 |
+- !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED)) |
27345 |
++ !(sk2_ipv6only && addr_type == IPV6_ADDR_MAPPED) && |
27346 |
++ v6_addr_in_nx_info(sk2->sk_nx_info, sk_rcv_saddr6, -1)) |
27347 |
+ return 1; |
27348 |
+ |
27349 |
+ if (addr_type == IPV6_ADDR_ANY && |
27350 |
+- !(sk_ipv6only && addr_type2 == IPV6_ADDR_MAPPED)) |
27351 |
++ !(sk_ipv6only && addr_type2 == IPV6_ADDR_MAPPED) && |
27352 |
++ (sk2_rcv_saddr6 && v6_addr_in_nx_info(sk->sk_nx_info, sk2_rcv_saddr6, -1))) |
27353 |
++ return 1; |
27354 |
++ |
27355 |
++ if (addr_type == IPV6_ADDR_ANY && |
27356 |
++ addr_type2 == IPV6_ADDR_ANY && |
27357 |
++ nx_v6_addr_conflict(sk->sk_nx_info, sk2->sk_nx_info)) |
27358 |
+ return 1; |
27359 |
+ |
27360 |
+ if (sk2_rcv_saddr6 && |
27361 |
++ addr_type != IPV6_ADDR_ANY && |
27362 |
++ addr_type != IPV6_ADDR_ANY && |
27363 |
+ ipv6_addr_equal(sk_rcv_saddr6, sk2_rcv_saddr6)) |
27364 |
+ return 1; |
27365 |
+ |
27366 |
+ if (addr_type == IPV6_ADDR_MAPPED && |
27367 |
+ !sk2_ipv6only && |
27368 |
+- (!sk2_rcv_saddr || !sk_rcv_saddr || sk_rcv_saddr == sk2_rcv_saddr)) |
27369 |
++ ipv4_rcv_saddr_equal(sk, sk2)) |
27370 |
+ return 1; |
27371 |
+ |
27372 |
+ return 0; |
27373 |
+@@ -2993,7 +3008,10 @@ static void if6_seq_stop(struct seq_file |
27374 |
+ static int if6_seq_show(struct seq_file *seq, void *v) |
27375 |
+ { |
27376 |
+ struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v; |
27377 |
+- seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n", |
27378 |
++ |
27379 |
++ if (nx_check(0, VS_ADMIN|VS_WATCH) || |
27380 |
++ v6_addr_in_nx_info(current_nx_info(), &ifp->addr, -1)) |
27381 |
++ seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n", |
27382 |
+ &ifp->addr, |
27383 |
+ ifp->idev->dev->ifindex, |
27384 |
+ ifp->prefix_len, |
27385 |
+@@ -3487,6 +3505,12 @@ static int inet6_dump_addr(struct sk_buf |
27386 |
+ struct ifmcaddr6 *ifmca; |
27387 |
+ struct ifacaddr6 *ifaca; |
27388 |
+ struct net *net = sock_net(skb->sk); |
27389 |
++ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL; |
27390 |
++ |
27391 |
++ /* disable ipv6 on non v6 guests */ |
27392 |
++ if (nxi && !nx_info_has_v6(nxi)) |
27393 |
++ return skb->len; |
27394 |
++ |
27395 |
+ |
27396 |
+ s_idx = cb->args[0]; |
27397 |
+ s_ip_idx = ip_idx = cb->args[1]; |
27398 |
+@@ -3508,6 +3532,8 @@ static int inet6_dump_addr(struct sk_buf |
27399 |
+ ifa = ifa->if_next, ip_idx++) { |
27400 |
+ if (ip_idx < s_ip_idx) |
27401 |
+ continue; |
27402 |
++ if (!v6_addr_in_nx_info(nxi, &ifa->addr, -1)) |
27403 |
++ continue; |
27404 |
+ err = inet6_fill_ifaddr(skb, ifa, |
27405 |
+ NETLINK_CB(cb->skb).pid, |
27406 |
+ cb->nlh->nlmsg_seq, |
27407 |
+@@ -3521,6 +3547,8 @@ static int inet6_dump_addr(struct sk_buf |
27408 |
+ ifmca = ifmca->next, ip_idx++) { |
27409 |
+ if (ip_idx < s_ip_idx) |
27410 |
+ continue; |
27411 |
++ if (!v6_addr_in_nx_info(nxi, &ifmca->mca_addr, -1)) |
27412 |
++ continue; |
27413 |
+ err = inet6_fill_ifmcaddr(skb, ifmca, |
27414 |
+ NETLINK_CB(cb->skb).pid, |
27415 |
+ cb->nlh->nlmsg_seq, |
27416 |
+@@ -3534,6 +3562,8 @@ static int inet6_dump_addr(struct sk_buf |
27417 |
+ ifaca = ifaca->aca_next, ip_idx++) { |
27418 |
+ if (ip_idx < s_ip_idx) |
27419 |
+ continue; |
27420 |
++ if (!v6_addr_in_nx_info(nxi, &ifaca->aca_addr, -1)) |
27421 |
++ continue; |
27422 |
+ err = inet6_fill_ifacaddr(skb, ifaca, |
27423 |
+ NETLINK_CB(cb->skb).pid, |
27424 |
+ cb->nlh->nlmsg_seq, |
27425 |
+@@ -3819,12 +3849,19 @@ static int inet6_dump_ifinfo(struct sk_b |
27426 |
+ int s_idx = cb->args[0]; |
27427 |
+ struct net_device *dev; |
27428 |
+ struct inet6_dev *idev; |
27429 |
++ struct nx_info *nxi = skb->sk ? skb->sk->sk_nx_info : NULL; |
27430 |
++ |
27431 |
++ /* FIXME: maybe disable ipv6 on non v6 guests? |
27432 |
++ if (skb->sk && skb->sk->sk_vx_info) |
27433 |
++ return skb->len; */ |
27434 |
+ |
27435 |
+ read_lock(&dev_base_lock); |
27436 |
+ idx = 0; |
27437 |
+ for_each_netdev(net, dev) { |
27438 |
+ if (idx < s_idx) |
27439 |
+ goto cont; |
27440 |
++ if (!v6_dev_in_nx_info(dev, nxi)) |
27441 |
++ goto cont; |
27442 |
+ if ((idev = in6_dev_get(dev)) == NULL) |
27443 |
+ goto cont; |
27444 |
+ err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, |
27445 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/af_inet6.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/af_inet6.c |
27446 |
+--- linux-2.6.29.4/net/ipv6/af_inet6.c 2009-03-24 14:22:46.000000000 +0100 |
27447 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/af_inet6.c 2009-03-24 14:48:37.000000000 +0100 |
27448 |
+@@ -41,6 +41,8 @@ |
27449 |
+ #include <linux/netdevice.h> |
27450 |
+ #include <linux/icmpv6.h> |
27451 |
+ #include <linux/netfilter_ipv6.h> |
27452 |
++#include <linux/vs_inet.h> |
27453 |
++#include <linux/vs_inet6.h> |
27454 |
+ |
27455 |
+ #include <net/ip.h> |
27456 |
+ #include <net/ipv6.h> |
27457 |
+@@ -49,6 +51,7 @@ |
27458 |
+ #include <net/tcp.h> |
27459 |
+ #include <net/ipip.h> |
27460 |
+ #include <net/protocol.h> |
27461 |
++#include <net/route.h> |
27462 |
+ #include <net/inet_common.h> |
27463 |
+ #include <net/route.h> |
27464 |
+ #include <net/transp_v6.h> |
27465 |
+@@ -146,9 +149,12 @@ lookup_protocol: |
27466 |
+ } |
27467 |
+ |
27468 |
+ err = -EPERM; |
27469 |
++ if ((protocol == IPPROTO_ICMPV6) && |
27470 |
++ nx_capable(answer->capability, NXC_RAW_ICMP)) |
27471 |
++ goto override; |
27472 |
+ if (answer->capability > 0 && !capable(answer->capability)) |
27473 |
+ goto out_rcu_unlock; |
27474 |
+- |
27475 |
++override: |
27476 |
+ sock->ops = answer->ops; |
27477 |
+ answer_prot = answer->prot; |
27478 |
+ answer_no_check = answer->no_check; |
27479 |
+@@ -247,6 +253,7 @@ int inet6_bind(struct socket *sock, stru |
27480 |
+ struct inet_sock *inet = inet_sk(sk); |
27481 |
+ struct ipv6_pinfo *np = inet6_sk(sk); |
27482 |
+ struct net *net = sock_net(sk); |
27483 |
++ struct nx_v6_sock_addr nsa; |
27484 |
+ __be32 v4addr = 0; |
27485 |
+ unsigned short snum; |
27486 |
+ int addr_type = 0; |
27487 |
+@@ -258,6 +265,11 @@ int inet6_bind(struct socket *sock, stru |
27488 |
+ |
27489 |
+ if (addr_len < SIN6_LEN_RFC2133) |
27490 |
+ return -EINVAL; |
27491 |
++ |
27492 |
++ err = v6_map_sock_addr(inet, addr, &nsa); |
27493 |
++ if (err) |
27494 |
++ return err; |
27495 |
++ |
27496 |
+ addr_type = ipv6_addr_type(&addr->sin6_addr); |
27497 |
+ if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM) |
27498 |
+ return -EINVAL; |
27499 |
+@@ -281,6 +293,10 @@ int inet6_bind(struct socket *sock, stru |
27500 |
+ err = -EADDRNOTAVAIL; |
27501 |
+ goto out; |
27502 |
+ } |
27503 |
++ if (!v4_addr_in_nx_info(sk->sk_nx_info, v4addr, NXA_MASK_BIND)) { |
27504 |
++ err = -EADDRNOTAVAIL; |
27505 |
++ goto out; |
27506 |
++ } |
27507 |
+ } else { |
27508 |
+ if (addr_type != IPV6_ADDR_ANY) { |
27509 |
+ struct net_device *dev = NULL; |
27510 |
+@@ -306,6 +322,11 @@ int inet6_bind(struct socket *sock, stru |
27511 |
+ } |
27512 |
+ } |
27513 |
+ |
27514 |
++ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) { |
27515 |
++ err = -EADDRNOTAVAIL; |
27516 |
++ goto out; |
27517 |
++ } |
27518 |
++ |
27519 |
+ /* ipv4 addr of the socket is invalid. Only the |
27520 |
+ * unspecified and mapped address have a v4 equivalent. |
27521 |
+ */ |
27522 |
+@@ -324,6 +345,8 @@ int inet6_bind(struct socket *sock, stru |
27523 |
+ } |
27524 |
+ } |
27525 |
+ |
27526 |
++ v6_set_sock_addr(inet, &nsa); |
27527 |
++ |
27528 |
+ inet->rcv_saddr = v4addr; |
27529 |
+ inet->saddr = v4addr; |
27530 |
+ |
27531 |
+@@ -416,9 +439,11 @@ int inet6_getname(struct socket *sock, s |
27532 |
+ return -ENOTCONN; |
27533 |
+ sin->sin6_port = inet->dport; |
27534 |
+ ipv6_addr_copy(&sin->sin6_addr, &np->daddr); |
27535 |
++ /* FIXME: remap lback? */ |
27536 |
+ if (np->sndflow) |
27537 |
+ sin->sin6_flowinfo = np->flow_label; |
27538 |
+ } else { |
27539 |
++ /* FIXME: remap lback? */ |
27540 |
+ if (ipv6_addr_any(&np->rcv_saddr)) |
27541 |
+ ipv6_addr_copy(&sin->sin6_addr, &np->saddr); |
27542 |
+ else |
27543 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/fib6_rules.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/fib6_rules.c |
27544 |
+--- linux-2.6.29.4/net/ipv6/fib6_rules.c 2008-12-25 00:26:37.000000000 +0100 |
27545 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/fib6_rules.c 2009-02-22 22:54:26.000000000 +0100 |
27546 |
+@@ -96,7 +96,7 @@ static int fib6_rule_action(struct fib_r |
27547 |
+ if (ipv6_dev_get_saddr(net, |
27548 |
+ ip6_dst_idev(&rt->u.dst)->dev, |
27549 |
+ &flp->fl6_dst, srcprefs, |
27550 |
+- &saddr)) |
27551 |
++ &saddr, NULL)) |
27552 |
+ goto again; |
27553 |
+ if (!ipv6_prefix_equal(&saddr, &r->src.addr, |
27554 |
+ r->src.plen)) |
27555 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/inet6_hashtables.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/inet6_hashtables.c |
27556 |
+--- linux-2.6.29.4/net/ipv6/inet6_hashtables.c 2009-03-24 14:22:46.000000000 +0100 |
27557 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/inet6_hashtables.c 2009-03-24 20:50:24.000000000 +0100 |
27558 |
+@@ -16,6 +16,7 @@ |
27559 |
+ |
27560 |
+ #include <linux/module.h> |
27561 |
+ #include <linux/random.h> |
27562 |
++#include <linux/vs_inet6.h> |
27563 |
+ |
27564 |
+ #include <net/inet_connection_sock.h> |
27565 |
+ #include <net/inet_hashtables.h> |
27566 |
+@@ -76,7 +77,6 @@ struct sock *__inet6_lookup_established( |
27567 |
+ unsigned int slot = hash & (hashinfo->ehash_size - 1); |
27568 |
+ struct inet_ehash_bucket *head = &hashinfo->ehash[slot]; |
27569 |
+ |
27570 |
+- |
27571 |
+ rcu_read_lock(); |
27572 |
+ begin: |
27573 |
+ sk_nulls_for_each_rcu(sk, node, &head->chain) { |
27574 |
+@@ -88,7 +88,7 @@ begin: |
27575 |
+ sock_put(sk); |
27576 |
+ goto begin; |
27577 |
+ } |
27578 |
+- goto out; |
27579 |
++ goto out; |
27580 |
+ } |
27581 |
+ } |
27582 |
+ if (get_nulls_value(node) != slot) |
27583 |
+@@ -134,6 +134,9 @@ static int inline compute_score(struct s |
27584 |
+ if (!ipv6_addr_equal(&np->rcv_saddr, daddr)) |
27585 |
+ return -1; |
27586 |
+ score++; |
27587 |
++ } else { |
27588 |
++ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1)) |
27589 |
++ return -1; |
27590 |
+ } |
27591 |
+ if (sk->sk_bound_dev_if) { |
27592 |
+ if (sk->sk_bound_dev_if != dif) |
27593 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/ip6_output.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/ip6_output.c |
27594 |
+--- linux-2.6.29.4/net/ipv6/ip6_output.c 2009-03-24 14:22:47.000000000 +0100 |
27595 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/ip6_output.c 2009-03-24 14:48:37.000000000 +0100 |
27596 |
+@@ -951,7 +951,7 @@ static int ip6_dst_lookup_tail(struct so |
27597 |
+ err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev, |
27598 |
+ &fl->fl6_dst, |
27599 |
+ sk ? inet6_sk(sk)->srcprefs : 0, |
27600 |
+- &fl->fl6_src); |
27601 |
++ &fl->fl6_src, sk->sk_nx_info); |
27602 |
+ if (err) |
27603 |
+ goto out_err_release; |
27604 |
+ } |
27605 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/Kconfig linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/Kconfig |
27606 |
+--- linux-2.6.29.4/net/ipv6/Kconfig 2008-12-25 00:26:37.000000000 +0100 |
27607 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/Kconfig 2009-02-22 22:54:26.000000000 +0100 |
27608 |
+@@ -4,8 +4,8 @@ |
27609 |
+ |
27610 |
+ # IPv6 as module will cause a CRASH if you try to unload it |
27611 |
+ menuconfig IPV6 |
27612 |
+- tristate "The IPv6 protocol" |
27613 |
+- default m |
27614 |
++ bool "The IPv6 protocol" |
27615 |
++ default n |
27616 |
+ ---help--- |
27617 |
+ This is complemental support for the IP version 6. |
27618 |
+ You will still be able to do traditional IPv4 networking as well. |
27619 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/ndisc.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/ndisc.c |
27620 |
+--- linux-2.6.29.4/net/ipv6/ndisc.c 2009-03-24 14:22:47.000000000 +0100 |
27621 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/ndisc.c 2009-03-24 14:48:37.000000000 +0100 |
27622 |
+@@ -589,7 +589,7 @@ static void ndisc_send_na(struct net_dev |
27623 |
+ } else { |
27624 |
+ if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr, |
27625 |
+ inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs, |
27626 |
+- &tmpaddr)) |
27627 |
++ &tmpaddr, NULL /* FIXME: ? */ )) |
27628 |
+ return; |
27629 |
+ src_addr = &tmpaddr; |
27630 |
+ } |
27631 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/raw.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/raw.c |
27632 |
+--- linux-2.6.29.4/net/ipv6/raw.c 2009-03-24 14:22:47.000000000 +0100 |
27633 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/raw.c 2009-03-24 14:48:37.000000000 +0100 |
27634 |
+@@ -29,6 +29,7 @@ |
27635 |
+ #include <linux/icmpv6.h> |
27636 |
+ #include <linux/netfilter.h> |
27637 |
+ #include <linux/netfilter_ipv6.h> |
27638 |
++#include <linux/vs_inet6.h> |
27639 |
+ #include <linux/skbuff.h> |
27640 |
+ #include <asm/uaccess.h> |
27641 |
+ #include <asm/ioctls.h> |
27642 |
+@@ -281,6 +282,13 @@ static int rawv6_bind(struct sock *sk, s |
27643 |
+ } |
27644 |
+ } |
27645 |
+ |
27646 |
++ if (!v6_addr_in_nx_info(sk->sk_nx_info, &addr->sin6_addr, -1)) { |
27647 |
++ err = -EADDRNOTAVAIL; |
27648 |
++ if (dev) |
27649 |
++ dev_put(dev); |
27650 |
++ goto out; |
27651 |
++ } |
27652 |
++ |
27653 |
+ /* ipv4 addr of the socket is invalid. Only the |
27654 |
+ * unspecified and mapped address have a v4 equivalent. |
27655 |
+ */ |
27656 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/route.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/route.c |
27657 |
+--- linux-2.6.29.4/net/ipv6/route.c 2009-03-24 14:22:47.000000000 +0100 |
27658 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/route.c 2009-03-24 14:48:37.000000000 +0100 |
27659 |
+@@ -2254,7 +2254,8 @@ static int rt6_fill_node(struct net *net |
27660 |
+ struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst); |
27661 |
+ struct in6_addr saddr_buf; |
27662 |
+ if (ipv6_dev_get_saddr(net, idev ? idev->dev : NULL, |
27663 |
+- dst, 0, &saddr_buf) == 0) |
27664 |
++ dst, 0, &saddr_buf, |
27665 |
++ (skb->sk ? skb->sk->sk_nx_info : NULL)) == 0) |
27666 |
+ NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); |
27667 |
+ } |
27668 |
+ |
27669 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/tcp_ipv6.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/tcp_ipv6.c |
27670 |
+--- linux-2.6.29.4/net/ipv6/tcp_ipv6.c 2009-03-24 14:22:47.000000000 +0100 |
27671 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/tcp_ipv6.c 2009-03-24 14:48:37.000000000 +0100 |
27672 |
+@@ -68,6 +68,7 @@ |
27673 |
+ |
27674 |
+ #include <linux/crypto.h> |
27675 |
+ #include <linux/scatterlist.h> |
27676 |
++#include <linux/vs_inet6.h> |
27677 |
+ |
27678 |
+ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); |
27679 |
+ static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, |
27680 |
+@@ -156,8 +157,15 @@ static int tcp_v6_connect(struct sock *s |
27681 |
+ * connect() to INADDR_ANY means loopback (BSD'ism). |
27682 |
+ */ |
27683 |
+ |
27684 |
+- if(ipv6_addr_any(&usin->sin6_addr)) |
27685 |
+- usin->sin6_addr.s6_addr[15] = 0x1; |
27686 |
++ if(ipv6_addr_any(&usin->sin6_addr)) { |
27687 |
++ struct nx_info *nxi = sk->sk_nx_info; |
27688 |
++ |
27689 |
++ if (nxi && nx_info_has_v6(nxi)) |
27690 |
++ /* FIXME: remap lback? */ |
27691 |
++ usin->sin6_addr = nxi->v6.ip; |
27692 |
++ else |
27693 |
++ usin->sin6_addr.s6_addr[15] = 0x1; |
27694 |
++ } |
27695 |
+ |
27696 |
+ addr_type = ipv6_addr_type(&usin->sin6_addr); |
27697 |
+ |
27698 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/udp.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/udp.c |
27699 |
+--- linux-2.6.29.4/net/ipv6/udp.c 2009-03-24 14:22:47.000000000 +0100 |
27700 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/udp.c 2009-03-24 20:56:49.000000000 +0100 |
27701 |
+@@ -47,6 +47,7 @@ |
27702 |
+ |
27703 |
+ #include <linux/proc_fs.h> |
27704 |
+ #include <linux/seq_file.h> |
27705 |
++#include <linux/vs_inet6.h> |
27706 |
+ #include "udp_impl.h" |
27707 |
+ |
27708 |
+ int udp_v6_get_port(struct sock *sk, unsigned short snum) |
27709 |
+@@ -77,6 +78,10 @@ static inline int compute_score(struct s |
27710 |
+ if (!ipv6_addr_equal(&np->rcv_saddr, daddr)) |
27711 |
+ return -1; |
27712 |
+ score++; |
27713 |
++ } else { |
27714 |
++ /* block non nx_info ips */ |
27715 |
++ if (!v6_addr_in_nx_info(sk->sk_nx_info, daddr, -1)) |
27716 |
++ return -1; |
27717 |
+ } |
27718 |
+ if (!ipv6_addr_any(&np->daddr)) { |
27719 |
+ if (!ipv6_addr_equal(&np->daddr, saddr)) |
27720 |
+diff -NurpP --minimal linux-2.6.29.4/net/ipv6/xfrm6_policy.c linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/xfrm6_policy.c |
27721 |
+--- linux-2.6.29.4/net/ipv6/xfrm6_policy.c 2009-03-24 14:22:47.000000000 +0100 |
27722 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/ipv6/xfrm6_policy.c 2009-03-24 14:48:37.000000000 +0100 |
27723 |
+@@ -63,7 +63,7 @@ static int xfrm6_get_saddr(struct net *n |
27724 |
+ dev = ip6_dst_idev(dst)->dev; |
27725 |
+ ipv6_dev_get_saddr(dev_net(dev), dev, |
27726 |
+ (struct in6_addr *)&daddr->a6, 0, |
27727 |
+- (struct in6_addr *)&saddr->a6); |
27728 |
++ (struct in6_addr *)&saddr->a6, NULL); |
27729 |
+ dst_release(dst); |
27730 |
+ return 0; |
27731 |
+ } |
27732 |
+diff -NurpP --minimal linux-2.6.29.4/net/netlink/af_netlink.c linux-2.6.29.4-vs2.3.0.36.14/net/netlink/af_netlink.c |
27733 |
+--- linux-2.6.29.4/net/netlink/af_netlink.c 2009-03-24 14:22:47.000000000 +0100 |
27734 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/netlink/af_netlink.c 2009-03-24 14:48:37.000000000 +0100 |
27735 |
+@@ -55,6 +55,9 @@ |
27736 |
+ #include <linux/types.h> |
27737 |
+ #include <linux/audit.h> |
27738 |
+ #include <linux/mutex.h> |
27739 |
++#include <linux/vs_context.h> |
27740 |
++#include <linux/vs_network.h> |
27741 |
++#include <linux/vs_limit.h> |
27742 |
+ |
27743 |
+ #include <net/net_namespace.h> |
27744 |
+ #include <net/sock.h> |
27745 |
+@@ -1776,6 +1779,8 @@ static struct sock *netlink_seq_socket_i |
27746 |
+ sk_for_each(s, node, &hash->table[j]) { |
27747 |
+ if (sock_net(s) != seq_file_net(seq)) |
27748 |
+ continue; |
27749 |
++ if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT)) |
27750 |
++ continue; |
27751 |
+ if (off == pos) { |
27752 |
+ iter->link = i; |
27753 |
+ iter->hash_idx = j; |
27754 |
+@@ -1810,7 +1815,8 @@ static void *netlink_seq_next(struct seq |
27755 |
+ s = v; |
27756 |
+ do { |
27757 |
+ s = sk_next(s); |
27758 |
+- } while (s && sock_net(s) != seq_file_net(seq)); |
27759 |
++ } while (s && (sock_net(s) != seq_file_net(seq) || |
27760 |
++ !nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))); |
27761 |
+ if (s) |
27762 |
+ return s; |
27763 |
+ |
27764 |
+@@ -1822,7 +1828,8 @@ static void *netlink_seq_next(struct seq |
27765 |
+ |
27766 |
+ for (; j <= hash->mask; j++) { |
27767 |
+ s = sk_head(&hash->table[j]); |
27768 |
+- while (s && sock_net(s) != seq_file_net(seq)) |
27769 |
++ while (s && (sock_net(s) != seq_file_net(seq) || |
27770 |
++ !nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT))) |
27771 |
+ s = sk_next(s); |
27772 |
+ if (s) { |
27773 |
+ iter->link = i; |
27774 |
+diff -NurpP --minimal linux-2.6.29.4/net/sctp/ipv6.c linux-2.6.29.4-vs2.3.0.36.14/net/sctp/ipv6.c |
27775 |
+--- linux-2.6.29.4/net/sctp/ipv6.c 2009-03-24 14:22:48.000000000 +0100 |
27776 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/sctp/ipv6.c 2009-03-24 20:58:14.000000000 +0100 |
27777 |
+@@ -317,7 +317,8 @@ static void sctp_v6_get_saddr(struct sct |
27778 |
+ dst ? ip6_dst_idev(dst)->dev : NULL, |
27779 |
+ &daddr->v6.sin6_addr, |
27780 |
+ inet6_sk(&sk->inet.sk)->srcprefs, |
27781 |
+- &saddr->v6.sin6_addr); |
27782 |
++ &saddr->v6.sin6_addr, |
27783 |
++ asoc->base.sk->sk_nx_info); |
27784 |
+ SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: %pI6\n", |
27785 |
+ &saddr->v6.sin6_addr); |
27786 |
+ return; |
27787 |
+diff -NurpP --minimal linux-2.6.29.4/net/socket.c linux-2.6.29.4-vs2.3.0.36.14/net/socket.c |
27788 |
+--- linux-2.6.29.4/net/socket.c 2009-03-24 14:22:48.000000000 +0100 |
27789 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/socket.c 2009-03-24 14:48:37.000000000 +0100 |
27790 |
+@@ -95,6 +95,10 @@ |
27791 |
+ |
27792 |
+ #include <net/sock.h> |
27793 |
+ #include <linux/netfilter.h> |
27794 |
++#include <linux/vs_base.h> |
27795 |
++#include <linux/vs_socket.h> |
27796 |
++#include <linux/vs_inet.h> |
27797 |
++#include <linux/vs_inet6.h> |
27798 |
+ |
27799 |
+ static int sock_no_open(struct inode *irrelevant, struct file *dontcare); |
27800 |
+ static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, |
27801 |
+@@ -549,7 +553,7 @@ static inline int __sock_sendmsg(struct |
27802 |
+ struct msghdr *msg, size_t size) |
27803 |
+ { |
27804 |
+ struct sock_iocb *si = kiocb_to_siocb(iocb); |
27805 |
+- int err; |
27806 |
++ int err, len; |
27807 |
+ |
27808 |
+ si->sock = sock; |
27809 |
+ si->scm = NULL; |
27810 |
+@@ -560,7 +564,22 @@ static inline int __sock_sendmsg(struct |
27811 |
+ if (err) |
27812 |
+ return err; |
27813 |
+ |
27814 |
+- return sock->ops->sendmsg(iocb, sock, msg, size); |
27815 |
++ len = sock->ops->sendmsg(iocb, sock, msg, size); |
27816 |
++ if (sock->sk) { |
27817 |
++ if (len == size) |
27818 |
++ vx_sock_send(sock->sk, size); |
27819 |
++ else |
27820 |
++ vx_sock_fail(sock->sk, size); |
27821 |
++ } |
27822 |
++ vxdprintk(VXD_CBIT(net, 7), |
27823 |
++ "__sock_sendmsg: %p[%p,%p,%p;%d/%d]:%d/%d", |
27824 |
++ sock, sock->sk, |
27825 |
++ (sock->sk)?sock->sk->sk_nx_info:0, |
27826 |
++ (sock->sk)?sock->sk->sk_vx_info:0, |
27827 |
++ (sock->sk)?sock->sk->sk_xid:0, |
27828 |
++ (sock->sk)?sock->sk->sk_nid:0, |
27829 |
++ (unsigned int)size, len); |
27830 |
++ return len; |
27831 |
+ } |
27832 |
+ |
27833 |
+ int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) |
27834 |
+@@ -629,7 +648,7 @@ EXPORT_SYMBOL_GPL(__sock_recv_timestamp) |
27835 |
+ static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock, |
27836 |
+ struct msghdr *msg, size_t size, int flags) |
27837 |
+ { |
27838 |
+- int err; |
27839 |
++ int err, len; |
27840 |
+ struct sock_iocb *si = kiocb_to_siocb(iocb); |
27841 |
+ |
27842 |
+ si->sock = sock; |
27843 |
+@@ -642,7 +661,18 @@ static inline int __sock_recvmsg(struct |
27844 |
+ if (err) |
27845 |
+ return err; |
27846 |
+ |
27847 |
+- return sock->ops->recvmsg(iocb, sock, msg, size, flags); |
27848 |
++ len = sock->ops->recvmsg(iocb, sock, msg, size, flags); |
27849 |
++ if ((len >= 0) && sock->sk) |
27850 |
++ vx_sock_recv(sock->sk, len); |
27851 |
++ vxdprintk(VXD_CBIT(net, 7), |
27852 |
++ "__sock_recvmsg: %p[%p,%p,%p;%d/%d]:%d/%d", |
27853 |
++ sock, sock->sk, |
27854 |
++ (sock->sk)?sock->sk->sk_nx_info:0, |
27855 |
++ (sock->sk)?sock->sk->sk_vx_info:0, |
27856 |
++ (sock->sk)?sock->sk->sk_xid:0, |
27857 |
++ (sock->sk)?sock->sk->sk_nid:0, |
27858 |
++ (unsigned int)size, len); |
27859 |
++ return len; |
27860 |
+ } |
27861 |
+ |
27862 |
+ int sock_recvmsg(struct socket *sock, struct msghdr *msg, |
27863 |
+@@ -1106,6 +1136,13 @@ static int __sock_create(struct net *net |
27864 |
+ if (type < 0 || type >= SOCK_MAX) |
27865 |
+ return -EINVAL; |
27866 |
+ |
27867 |
++ if (!nx_check(0, VS_ADMIN)) { |
27868 |
++ if (family == PF_INET && !current_nx_info_has_v4()) |
27869 |
++ return -EAFNOSUPPORT; |
27870 |
++ if (family == PF_INET6 && !current_nx_info_has_v6()) |
27871 |
++ return -EAFNOSUPPORT; |
27872 |
++ } |
27873 |
++ |
27874 |
+ /* Compatibility. |
27875 |
+ |
27876 |
+ This uglymoron is moved from INET layer to here to avoid |
27877 |
+@@ -1238,6 +1275,7 @@ SYSCALL_DEFINE3(socket, int, family, int |
27878 |
+ if (retval < 0) |
27879 |
+ goto out; |
27880 |
+ |
27881 |
++ set_bit(SOCK_USER_SOCKET, &sock->flags); |
27882 |
+ retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK)); |
27883 |
+ if (retval < 0) |
27884 |
+ goto out_release; |
27885 |
+@@ -1279,10 +1317,12 @@ SYSCALL_DEFINE4(socketpair, int, family, |
27886 |
+ err = sock_create(family, type, protocol, &sock1); |
27887 |
+ if (err < 0) |
27888 |
+ goto out; |
27889 |
++ set_bit(SOCK_USER_SOCKET, &sock1->flags); |
27890 |
+ |
27891 |
+ err = sock_create(family, type, protocol, &sock2); |
27892 |
+ if (err < 0) |
27893 |
+ goto out_release_1; |
27894 |
++ set_bit(SOCK_USER_SOCKET, &sock2->flags); |
27895 |
+ |
27896 |
+ err = sock1->ops->socketpair(sock1, sock2); |
27897 |
+ if (err < 0) |
27898 |
+diff -NurpP --minimal linux-2.6.29.4/net/sunrpc/auth.c linux-2.6.29.4-vs2.3.0.36.14/net/sunrpc/auth.c |
27899 |
+--- linux-2.6.29.4/net/sunrpc/auth.c 2009-03-24 14:22:48.000000000 +0100 |
27900 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/sunrpc/auth.c 2009-03-24 21:00:49.000000000 +0100 |
27901 |
+@@ -14,6 +14,7 @@ |
27902 |
+ #include <linux/hash.h> |
27903 |
+ #include <linux/sunrpc/clnt.h> |
27904 |
+ #include <linux/spinlock.h> |
27905 |
++#include <linux/vs_tag.h> |
27906 |
+ |
27907 |
+ #ifdef RPC_DEBUG |
27908 |
+ # define RPCDBG_FACILITY RPCDBG_AUTH |
27909 |
+@@ -360,6 +361,7 @@ rpcauth_lookupcred(struct rpc_auth *auth |
27910 |
+ memset(&acred, 0, sizeof(acred)); |
27911 |
+ acred.uid = cred->fsuid; |
27912 |
+ acred.gid = cred->fsgid; |
27913 |
++ acred.tag = dx_current_tag(); |
27914 |
+ acred.group_info = get_group_info(((struct cred *)cred)->group_info); |
27915 |
+ |
27916 |
+ ret = auth->au_ops->lookup_cred(auth, &acred, flags); |
27917 |
+@@ -400,6 +402,7 @@ rpcauth_bind_root_cred(struct rpc_task * |
27918 |
+ struct auth_cred acred = { |
27919 |
+ .uid = 0, |
27920 |
+ .gid = 0, |
27921 |
++ .tag = dx_current_tag(), |
27922 |
+ }; |
27923 |
+ struct rpc_cred *ret; |
27924 |
+ |
27925 |
+diff -NurpP --minimal linux-2.6.29.4/net/sunrpc/auth_unix.c linux-2.6.29.4-vs2.3.0.36.14/net/sunrpc/auth_unix.c |
27926 |
+--- linux-2.6.29.4/net/sunrpc/auth_unix.c 2008-12-25 00:26:37.000000000 +0100 |
27927 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/sunrpc/auth_unix.c 2009-02-22 22:54:26.000000000 +0100 |
27928 |
+@@ -11,12 +11,14 @@ |
27929 |
+ #include <linux/module.h> |
27930 |
+ #include <linux/sunrpc/clnt.h> |
27931 |
+ #include <linux/sunrpc/auth.h> |
27932 |
++#include <linux/vs_tag.h> |
27933 |
+ |
27934 |
+ #define NFS_NGROUPS 16 |
27935 |
+ |
27936 |
+ struct unx_cred { |
27937 |
+ struct rpc_cred uc_base; |
27938 |
+ gid_t uc_gid; |
27939 |
++ tag_t uc_tag; |
27940 |
+ gid_t uc_gids[NFS_NGROUPS]; |
27941 |
+ }; |
27942 |
+ #define uc_uid uc_base.cr_uid |
27943 |
+@@ -78,6 +80,7 @@ unx_create_cred(struct rpc_auth *auth, s |
27944 |
+ groups = NFS_NGROUPS; |
27945 |
+ |
27946 |
+ cred->uc_gid = acred->gid; |
27947 |
++ cred->uc_tag = acred->tag; |
27948 |
+ for (i = 0; i < groups; i++) |
27949 |
+ cred->uc_gids[i] = GROUP_AT(acred->group_info, i); |
27950 |
+ if (i < NFS_NGROUPS) |
27951 |
+@@ -119,7 +122,9 @@ unx_match(struct auth_cred *acred, struc |
27952 |
+ unsigned int i; |
27953 |
+ |
27954 |
+ |
27955 |
+- if (cred->uc_uid != acred->uid || cred->uc_gid != acred->gid) |
27956 |
++ if (cred->uc_uid != acred->uid || |
27957 |
++ cred->uc_gid != acred->gid || |
27958 |
++ cred->uc_tag != acred->tag) |
27959 |
+ return 0; |
27960 |
+ |
27961 |
+ if (acred->group_info != NULL) |
27962 |
+@@ -142,7 +147,7 @@ unx_marshal(struct rpc_task *task, __be3 |
27963 |
+ struct rpc_clnt *clnt = task->tk_client; |
27964 |
+ struct unx_cred *cred = container_of(task->tk_msg.rpc_cred, struct unx_cred, uc_base); |
27965 |
+ __be32 *base, *hold; |
27966 |
+- int i; |
27967 |
++ int i, tag; |
27968 |
+ |
27969 |
+ *p++ = htonl(RPC_AUTH_UNIX); |
27970 |
+ base = p++; |
27971 |
+@@ -152,9 +157,12 @@ unx_marshal(struct rpc_task *task, __be3 |
27972 |
+ * Copy the UTS nodename captured when the client was created. |
27973 |
+ */ |
27974 |
+ p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen); |
27975 |
++ tag = task->tk_client->cl_tag; |
27976 |
+ |
27977 |
+- *p++ = htonl((u32) cred->uc_uid); |
27978 |
+- *p++ = htonl((u32) cred->uc_gid); |
27979 |
++ *p++ = htonl((u32) TAGINO_UID(tag, |
27980 |
++ cred->uc_uid, cred->uc_tag)); |
27981 |
++ *p++ = htonl((u32) TAGINO_GID(tag, |
27982 |
++ cred->uc_gid, cred->uc_tag)); |
27983 |
+ hold = p++; |
27984 |
+ for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++) |
27985 |
+ *p++ = htonl((u32) cred->uc_gids[i]); |
27986 |
+diff -NurpP --minimal linux-2.6.29.4/net/sunrpc/clnt.c linux-2.6.29.4-vs2.3.0.36.14/net/sunrpc/clnt.c |
27987 |
+--- linux-2.6.29.4/net/sunrpc/clnt.c 2009-03-24 14:22:48.000000000 +0100 |
27988 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/sunrpc/clnt.c 2009-03-24 14:48:37.000000000 +0100 |
27989 |
+@@ -32,6 +32,7 @@ |
27990 |
+ #include <linux/utsname.h> |
27991 |
+ #include <linux/workqueue.h> |
27992 |
+ #include <linux/in6.h> |
27993 |
++#include <linux/vs_cvirt.h> |
27994 |
+ |
27995 |
+ #include <linux/sunrpc/clnt.h> |
27996 |
+ #include <linux/sunrpc/rpc_pipe_fs.h> |
27997 |
+@@ -335,6 +336,9 @@ struct rpc_clnt *rpc_create(struct rpc_c |
27998 |
+ if (!(args->flags & RPC_CLNT_CREATE_QUIET)) |
27999 |
+ clnt->cl_chatty = 1; |
28000 |
+ |
28001 |
++ /* TODO: handle RPC_CLNT_CREATE_TAGGED |
28002 |
++ if (args->flags & RPC_CLNT_CREATE_TAGGED) |
28003 |
++ clnt->cl_tag = 1; */ |
28004 |
+ return clnt; |
28005 |
+ } |
28006 |
+ EXPORT_SYMBOL_GPL(rpc_create); |
28007 |
+diff -NurpP --minimal linux-2.6.29.4/net/unix/af_unix.c linux-2.6.29.4-vs2.3.0.36.14/net/unix/af_unix.c |
28008 |
+--- linux-2.6.29.4/net/unix/af_unix.c 2009-03-24 14:22:48.000000000 +0100 |
28009 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/unix/af_unix.c 2009-03-24 14:48:37.000000000 +0100 |
28010 |
+@@ -114,6 +114,8 @@ |
28011 |
+ #include <linux/mount.h> |
28012 |
+ #include <net/checksum.h> |
28013 |
+ #include <linux/security.h> |
28014 |
++#include <linux/vs_context.h> |
28015 |
++#include <linux/vs_limit.h> |
28016 |
+ |
28017 |
+ static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; |
28018 |
+ static DEFINE_SPINLOCK(unix_table_lock); |
28019 |
+@@ -258,6 +260,8 @@ static struct sock *__unix_find_socket_b |
28020 |
+ if (!net_eq(sock_net(s), net)) |
28021 |
+ continue; |
28022 |
+ |
28023 |
++ if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT)) |
28024 |
++ continue; |
28025 |
+ if (u->addr->len == len && |
28026 |
+ !memcmp(u->addr->name, sunname, len)) |
28027 |
+ goto found; |
28028 |
+@@ -2110,6 +2114,8 @@ static struct sock *unix_seq_idx(struct |
28029 |
+ for (s = first_unix_socket(&iter->i); s; s = next_unix_socket(&iter->i, s)) { |
28030 |
+ if (sock_net(s) != seq_file_net(seq)) |
28031 |
+ continue; |
28032 |
++ if (!nx_check(s->sk_nid, VS_WATCH_P | VS_IDENT)) |
28033 |
++ continue; |
28034 |
+ if (off == pos) |
28035 |
+ return s; |
28036 |
+ ++off; |
28037 |
+@@ -2134,7 +2140,8 @@ static void *unix_seq_next(struct seq_fi |
28038 |
+ sk = first_unix_socket(&iter->i); |
28039 |
+ else |
28040 |
+ sk = next_unix_socket(&iter->i, sk); |
28041 |
+- while (sk && (sock_net(sk) != seq_file_net(seq))) |
28042 |
++ while (sk && (sock_net(sk) != seq_file_net(seq) || |
28043 |
++ !nx_check(sk->sk_nid, VS_WATCH_P | VS_IDENT))) |
28044 |
+ sk = next_unix_socket(&iter->i, sk); |
28045 |
+ return sk; |
28046 |
+ } |
28047 |
+diff -NurpP --minimal linux-2.6.29.4/net/x25/af_x25.c linux-2.6.29.4-vs2.3.0.36.14/net/x25/af_x25.c |
28048 |
+--- linux-2.6.29.4/net/x25/af_x25.c 2009-05-23 23:16:53.000000000 +0200 |
28049 |
++++ linux-2.6.29.4-vs2.3.0.36.14/net/x25/af_x25.c 2009-04-30 12:14:53.000000000 +0200 |
28050 |
+@@ -506,7 +506,10 @@ static int x25_create(struct net *net, s |
28051 |
+ |
28052 |
+ x25 = x25_sk(sk); |
28053 |
+ |
28054 |
+- sock_init_data(sock, sk); |
28055 |
++ sk->sk_socket = sock; |
28056 |
++ sk->sk_type = sock->type; |
28057 |
++ sk->sk_sleep = &sock->wait; |
28058 |
++ sock->sk = sk; |
28059 |
+ |
28060 |
+ x25_init_timers(sk); |
28061 |
+ |
28062 |
+diff -NurpP --minimal linux-2.6.29.4/scripts/checksyscalls.sh linux-2.6.29.4-vs2.3.0.36.14/scripts/checksyscalls.sh |
28063 |
+--- linux-2.6.29.4/scripts/checksyscalls.sh 2008-12-25 00:26:37.000000000 +0100 |
28064 |
++++ linux-2.6.29.4-vs2.3.0.36.14/scripts/checksyscalls.sh 2009-02-22 22:54:26.000000000 +0100 |
28065 |
+@@ -108,7 +108,6 @@ cat << EOF |
28066 |
+ #define __IGNORE_afs_syscall |
28067 |
+ #define __IGNORE_getpmsg |
28068 |
+ #define __IGNORE_putpmsg |
28069 |
+-#define __IGNORE_vserver |
28070 |
+ EOF |
28071 |
+ } |
28072 |
+ |
28073 |
+diff -NurpP --minimal linux-2.6.29.4/security/commoncap.c linux-2.6.29.4-vs2.3.0.36.14/security/commoncap.c |
28074 |
+--- linux-2.6.29.4/security/commoncap.c 2009-05-23 23:16:53.000000000 +0200 |
28075 |
++++ linux-2.6.29.4-vs2.3.0.36.14/security/commoncap.c 2009-04-30 12:14:53.000000000 +0200 |
28076 |
+@@ -27,10 +27,11 @@ |
28077 |
+ #include <linux/sched.h> |
28078 |
+ #include <linux/prctl.h> |
28079 |
+ #include <linux/securebits.h> |
28080 |
++#include <linux/vs_context.h> |
28081 |
+ |
28082 |
+ int cap_netlink_send(struct sock *sk, struct sk_buff *skb) |
28083 |
+ { |
28084 |
+- NETLINK_CB(skb).eff_cap = current_cap(); |
28085 |
++ NETLINK_CB(skb).eff_cap = vx_mbcaps(current_cap()); |
28086 |
+ return 0; |
28087 |
+ } |
28088 |
+ |
28089 |
+@@ -40,6 +41,7 @@ int cap_netlink_recv(struct sk_buff *skb |
28090 |
+ return -EPERM; |
28091 |
+ return 0; |
28092 |
+ } |
28093 |
++ |
28094 |
+ EXPORT_SYMBOL(cap_netlink_recv); |
28095 |
+ |
28096 |
+ /** |
28097 |
+@@ -60,7 +62,22 @@ EXPORT_SYMBOL(cap_netlink_recv); |
28098 |
+ int cap_capable(struct task_struct *tsk, const struct cred *cred, int cap, |
28099 |
+ int audit) |
28100 |
+ { |
28101 |
+- return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM; |
28102 |
++ struct vx_info *vxi = tsk->vx_info; |
28103 |
++ |
28104 |
++#if 0 |
28105 |
++ printk("cap_capable() VXF_STATE_SETUP = %llx, raised = %x, eff = %08x:%08x\n", |
28106 |
++ vx_info_flags(vxi, VXF_STATE_SETUP, 0), |
28107 |
++ cap_raised(tsk->cap_effective, cap), |
28108 |
++ tsk->cap_effective.cap[1], tsk->cap_effective.cap[0]); |
28109 |
++#endif |
28110 |
++ |
28111 |
++ /* special case SETUP */ |
28112 |
++ if (vx_info_flags(vxi, VXF_STATE_SETUP, 0) && |
28113 |
++ /* FIXME: maybe use cred instead? */ |
28114 |
++ cap_raised(tsk->cred->cap_effective, cap)) |
28115 |
++ return 0; |
28116 |
++ |
28117 |
++ return vx_cap_raised(vxi, cred->cap_effective, cap) ? 0 : -EPERM; |
28118 |
+ } |
28119 |
+ |
28120 |
+ /** |
28121 |
+@@ -586,7 +603,7 @@ int cap_inode_setxattr(struct dentry *de |
28122 |
+ |
28123 |
+ if (!strncmp(name, XATTR_SECURITY_PREFIX, |
28124 |
+ sizeof(XATTR_SECURITY_PREFIX) - 1) && |
28125 |
+- !capable(CAP_SYS_ADMIN)) |
28126 |
++ !vx_capable(CAP_SYS_ADMIN, VXC_FS_SECURITY)) |
28127 |
+ return -EPERM; |
28128 |
+ return 0; |
28129 |
+ } |
28130 |
+@@ -930,7 +947,8 @@ error: |
28131 |
+ */ |
28132 |
+ int cap_syslog(int type) |
28133 |
+ { |
28134 |
+- if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN)) |
28135 |
++ if ((type != 3 && type != 10) && |
28136 |
++ !vx_capable(CAP_SYS_ADMIN, VXC_SYSLOG)) |
28137 |
+ return -EPERM; |
28138 |
+ return 0; |
28139 |
+ } |
28140 |
+@@ -952,3 +970,4 @@ int cap_vm_enough_memory(struct mm_struc |
28141 |
+ cap_sys_admin = 1; |
28142 |
+ return __vm_enough_memory(mm, pages, cap_sys_admin); |
28143 |
+ } |
28144 |
++ |
28145 |
+diff -NurpP --minimal linux-2.6.29.4/security/selinux/hooks.c linux-2.6.29.4-vs2.3.0.36.14/security/selinux/hooks.c |
28146 |
+--- linux-2.6.29.4/security/selinux/hooks.c 2009-05-23 23:16:53.000000000 +0200 |
28147 |
++++ linux-2.6.29.4-vs2.3.0.36.14/security/selinux/hooks.c 2009-05-23 23:19:11.000000000 +0200 |
28148 |
+@@ -64,7 +64,6 @@ |
28149 |
+ #include <linux/dccp.h> |
28150 |
+ #include <linux/quota.h> |
28151 |
+ #include <linux/un.h> /* for Unix socket types */ |
28152 |
+-#include <net/af_unix.h> /* for Unix socket types */ |
28153 |
+ #include <linux/parser.h> |
28154 |
+ #include <linux/nfs_mount.h> |
28155 |
+ #include <net/ipv6.h> |