1 diff -NurpP --minimal linux-2.6.19.1/Documentation/vserver/debug.txt linux-2.6.19.1-vs2.3.0.6/Documentation/vserver/debug.txt
2 --- linux-2.6.19.1/Documentation/vserver/debug.txt 1970-01-01 01:00:00 +0100
3 +++ linux-2.6.19.1-vs2.3.0.6/Documentation/vserver/debug.txt 2006-11-08 04:57:48 +0100
8 + 2 4 "vx_map_tgid: %p/%llx: %d -> %d"
9 + "vx_rmap_tgid: %p/%llx: %d -> %d"
13 + 0 1 "ALLOC (%p,#%d)%c inode (%d)"
14 + "FREE (%p,#%d)%c inode"
15 + 1 2 "ALLOC (%p,#%d)%c %lld bytes (%d)"
16 + "FREE (%p,#%d)%c %lld bytes"
17 + 2 4 "ADJUST: %lld,%lld on %ld,%ld [mult=%d]"
18 + 3 8 "ext3_has_free_blocks(%p): %lu<%lu+1, %c, %u!=%u r=%d"
19 + "ext3_has_free_blocks(%p): free=%lu, root=%lu"
20 + "rcu_free_dl_info(%p)"
21 + 4 10 "alloc_dl_info(%p,%d) = %p"
22 + "dealloc_dl_info(%p)"
23 + "get_dl_info(%p[#%d.%d])"
24 + "put_dl_info(%p[#%d.%d])"
25 + 5 20 "alloc_dl_info(%p,%d)*"
26 + 6 40 "__hash_dl_info: %p[#%d]"
27 + "__unhash_dl_info: %p[#%d]"
28 + 7 80 "locate_dl_info(%p,#%d) = %p"
32 + 0 1 "destroy_dqhash: %p [#0x%08x] c=%d"
33 + "new_dqhash: %p [#0x%08x]"
34 + "vroot[%d]_clr_dev: dev=%p[%lu,%d:%d]"
35 + "vroot[%d]_get_real_bdev: dev=%p[%lu,%d:%d]"
36 + "vroot[%d]_set_dev: dev=%p[%lu,%d:%d]"
37 + "vroot_get_real_bdev not set"
38 + 1 2 "cow_break_link(»%s«)"
40 + 2 4 "dentry_open(new): %p"
41 + "dentry_open(old): %p"
42 + "lookup_create(new): %p"
44 + "path_lookup(old): %d"
45 + "vfs_create(new): %d"
48 + 3 8 "fput(new_file=%p[#%d])"
49 + "fput(old_file=%p[#%d])"
50 + 4 10 "vx_info_kill(%p[#%d],%d,%d) = %d"
51 + "vx_info_kill(%p[#%d],%d,%d)*"
52 + 5 20 "vs_reboot(%p[#%d],%d)"
53 + 6 40 "dropping task %p[#%u,%u] for %p[#%u,%u]"
57 + 2 4 "nx_addr_conflict(%p,%p) %d.%d,%d.%d"
58 + 3 8 "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d"
59 + "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d"
60 + 4 10 "ip_route_connect(%p) %p,%p;%lx"
61 + 5 20 "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx"
62 + 6 40 "sk,egf: %p [#%d] (from %d)"
63 + "sk,egn: %p [#%d] (from %d)"
64 + "sk,req: %p [#%d] (from %d)"
65 + "sk: %p [#%d] (from %d)"
66 + "tw: %p [#%d] (from %d)"
67 + 7 80 "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d"
68 + "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d"
72 + 0 1 "__lookup_nx_info(#%u): %p[#%u]"
73 + "alloc_nx_info(%d) = %p"
74 + "create_nx_info(%d) (dynamic rejected)"
75 + "create_nx_info(%d) = %p (already there)"
76 + "create_nx_info(%d) = %p (new)"
77 + "dealloc_nx_info(%p)"
78 + 1 2 "alloc_nx_info(%d)*"
79 + "create_nx_info(%d)*"
80 + 2 4 "get_nx_info(%p[#%d.%d])"
81 + "put_nx_info(%p[#%d.%d])"
82 + 3 8 "claim_nx_info(%p[#%d.%d.%d]) %p"
83 + "clr_nx_info(%p[#%d.%d])"
84 + "init_nx_info(%p[#%d.%d])"
85 + "release_nx_info(%p[#%d.%d.%d]) %p"
86 + "set_nx_info(%p[#%d.%d])"
87 + 4 10 "__hash_nx_info: %p[#%d]"
88 + "__nx_dynamic_id: [#%d]"
89 + "__unhash_nx_info: %p[#%d]"
90 + 5 20 "moved task %p into nxi:%p[#%d]"
91 + "nx_migrate_task(%p,%p[#%d.%d.%d])"
92 + "task_get_nx_info(%p)"
93 + 6 40 "nx_clear_persistent(%p[#%d])"
97 + 0 1 "quota_sync_dqh(%p,%d) discard inode %p"
98 + 1 2 "quota_sync_dqh(%p,%d)"
99 + "sync_dquots(%p,%d)"
100 + "sync_dquots_dqh(%p,%d)"
101 + 3 8 "do_quotactl(%p,%d,cmd=%d,id=%d,%p)"
105 + 0 1 "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]"
106 + 1 2 "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]"
107 + 4 10 "%s: (%s %s) returned %s with %d"
111 + 7 80 "dx_parse_tag(»%s«): %d:#%d"
112 + "dx_propagate_tag(%p[#%lu.%d]): %d,%d"
116 + 0 1 "__lookup_vx_info(#%u): %p[#%u]"
117 + "alloc_vx_info(%d) = %p"
118 + "alloc_vx_info(%d)*"
119 + "create_vx_info(%d) (dynamic rejected)"
120 + "create_vx_info(%d) = %p (already there)"
121 + "create_vx_info(%d) = %p (new)"
122 + "dealloc_vx_info(%p)"
123 + "loc_vx_info(%d) = %p (found)"
124 + "loc_vx_info(%d) = %p (new)"
125 + "loc_vx_info(%d) = %p (not available)"
126 + 1 2 "create_vx_info(%d)*"
128 + 2 4 "get_vx_info(%p[#%d.%d])"
129 + "put_vx_info(%p[#%d.%d])"
130 + 3 8 "claim_vx_info(%p[#%d.%d.%d]) %p"
131 + "clr_vx_info(%p[#%d.%d])"
132 + "init_vx_info(%p[#%d.%d])"
133 + "release_vx_info(%p[#%d.%d.%d]) %p"
134 + "set_vx_info(%p[#%d.%d])"
135 + "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]"
136 + 4 10 "__hash_vx_info: %p[#%d]"
137 + "__unhash_vx_info: %p[#%d]"
138 + "__vx_dynamic_id: [#%d]"
139 + 5 20 "enter_vx_info(%p[#%d],%p) %p[#%d,%p]"
140 + "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]"
141 + "moved task %p into vxi:%p[#%d]"
142 + "task_get_vx_info(%p)"
143 + "vx_migrate_task(%p,%p[#%d.%d])"
144 + 6 40 "vx_clear_persistent(%p[#%d])"
145 + "vx_exit_init(%p[#%d],%p[#%d,%d,%d])"
146 + "vx_set_init(%p[#%d],%p[#%d,%d,%d])"
147 + "vx_set_persistent(%p[#%d])"
148 + "vx_set_reaper(%p[#%d],%p[#%d,%d])"
153 + n 2^n "vx_acc_cres[%5d,%s,%2d]: %5d%s"
154 + "vx_cres_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
156 + m 2^m "vx_acc_page[%5d,%s,%2d]: %5d%s"
157 + "vx_acc_pages[%5d,%s,%2d]: %5d += %5d"
158 + "vx_pages_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
159 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/alpha/Kconfig
160 --- linux-2.6.19.1/arch/alpha/Kconfig 2006-11-30 21:18:23 +0100
161 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/Kconfig 2006-11-08 04:57:40 +0100
162 @@ -632,6 +632,8 @@ source "arch/alpha/oprofile/Kconfig"
164 source "arch/alpha/Kconfig.debug"
166 +source "kernel/vserver/Kconfig"
168 source "security/Kconfig"
170 source "crypto/Kconfig"
171 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/asm-offsets.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/asm-offsets.c
172 --- linux-2.6.19.1/arch/alpha/kernel/asm-offsets.c 2006-02-15 13:54:10 +0100
173 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/asm-offsets.c 2006-11-08 04:57:50 +0100
174 @@ -36,6 +36,7 @@ void foo(void)
175 DEFINE(PT_PTRACED, PT_PTRACED);
176 DEFINE(CLONE_VM, CLONE_VM);
177 DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
178 + DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
179 DEFINE(SIGCHLD, SIGCHLD);
182 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/entry.S linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/entry.S
183 --- linux-2.6.19.1/arch/alpha/kernel/entry.S 2006-11-30 21:18:23 +0100
184 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/entry.S 2006-11-08 04:57:52 +0100
185 @@ -644,7 +644,7 @@ kernel_thread:
186 stq $2, 152($sp) /* HAE */
188 /* Shuffle FLAGS to the front; add CLONE_VM. */
189 - ldi $1, CLONE_VM|CLONE_UNTRACED
190 + ldi $1, CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
194 @@ -873,24 +873,15 @@ sys_getxgid:
201 - ldq $2, TI_TASK($8)
203 - /* See linux/kernel/timer.c sys_getppid for discussion
204 - about this loop. */
205 - ldq $3, TASK_GROUP_LEADER($2)
206 - ldq $4, TASK_REAL_PARENT($3)
207 - ldl $0, TASK_TGID($2)
208 -1: ldl $1, TASK_TGID($4)
212 - ldq $3, TASK_GROUP_LEADER($2)
213 - ldq $4, TASK_REAL_PARENT($3)
219 + jsr $26, do_getxpid
226 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/osf_sys.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/osf_sys.c
227 --- linux-2.6.19.1/arch/alpha/kernel/osf_sys.c 2006-11-30 21:18:23 +0100
228 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/osf_sys.c 2006-12-02 01:37:05 +0100
229 @@ -885,7 +885,7 @@ osf_gettimeofday(struct timeval32 __user
233 - do_gettimeofday(&ktv);
234 + vx_gettimeofday(&ktv);
235 if (put_tv32(tv, &ktv))
238 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/ptrace.c
239 --- linux-2.6.19.1/arch/alpha/kernel/ptrace.c 2006-04-09 13:49:39 +0200
240 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/ptrace.c 2006-11-30 18:53:18 +0100
242 #include <linux/slab.h>
243 #include <linux/security.h>
244 #include <linux/signal.h>
245 +#include <linux/vs_base.h>
247 #include <asm/uaccess.h>
248 #include <asm/pgtable.h>
249 @@ -283,6 +284,11 @@ do_sys_ptrace(long request, long pid, lo
253 + if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT)) {
258 if (request == PTRACE_ATTACH) {
259 ret = ptrace_attach(child);
261 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/semaphore.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/semaphore.c
262 --- linux-2.6.19.1/arch/alpha/kernel/semaphore.c 2004-08-14 12:55:32 +0200
263 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/semaphore.c 2006-11-08 04:57:42 +0100
264 @@ -68,8 +68,8 @@ __down_failed(struct semaphore *sem)
265 DECLARE_WAITQUEUE(wait, tsk);
267 #ifdef CONFIG_DEBUG_SEMAPHORE
268 - printk("%s(%d): down failed(%p)\n",
269 - tsk->comm, tsk->pid, sem);
270 + printk("%s(%d:#%u): down failed(%p)\n",
271 + tsk->comm, tsk->pid, tsk->xid, sem);
274 tsk->state = TASK_UNINTERRUPTIBLE;
275 @@ -97,8 +97,8 @@ __down_failed(struct semaphore *sem)
278 #ifdef CONFIG_DEBUG_SEMAPHORE
279 - printk("%s(%d): down acquired(%p)\n",
280 - tsk->comm, tsk->pid, sem);
281 + printk("%s(%d:#%u): down acquired(%p)\n",
282 + tsk->comm, tsk->pid, tsk->xid, sem);
286 @@ -110,8 +110,8 @@ __down_failed_interruptible(struct semap
289 #ifdef CONFIG_DEBUG_SEMAPHORE
290 - printk("%s(%d): down failed(%p)\n",
291 - tsk->comm, tsk->pid, sem);
292 + printk("%s(%d:#%u): down failed(%p)\n",
293 + tsk->comm, tsk->pid, tsk->xid, sem);
296 tsk->state = TASK_INTERRUPTIBLE;
297 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/systbls.S linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/systbls.S
298 --- linux-2.6.19.1/arch/alpha/kernel/systbls.S 2006-11-30 21:18:23 +0100
299 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/systbls.S 2006-11-08 04:57:41 +0100
300 @@ -446,7 +446,7 @@ sys_call_table:
301 .quad sys_stat64 /* 425 */
304 - .quad sys_ni_syscall /* sys_vserver */
305 + .quad sys_vserver /* sys_vserver */
306 .quad sys_ni_syscall /* sys_mbind */
307 .quad sys_ni_syscall /* sys_get_mempolicy */
308 .quad sys_ni_syscall /* sys_set_mempolicy */
309 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/traps.c
310 --- linux-2.6.19.1/arch/alpha/kernel/traps.c 2006-09-20 16:57:57 +0200
311 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/traps.c 2006-11-08 04:57:42 +0100
312 @@ -182,7 +182,8 @@ die_if_kernel(char * str, struct pt_regs
314 printk("CPU %d ", hard_smp_processor_id());
316 - printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
317 + printk("%s(%d[#%u]): %s %ld\n", current->comm,
318 + current->pid, current->xid, str, err);
319 dik_show_regs(regs, r9_15);
320 dik_show_trace((unsigned long *)(regs+1));
321 dik_show_code((unsigned int *)regs->pc);
322 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/mm/init.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/mm/init.c
323 --- linux-2.6.19.1/arch/alpha/mm/init.c 2006-11-30 21:18:23 +0100
324 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/mm/init.c 2006-11-08 04:57:39 +0100
326 #include <linux/init.h>
327 #include <linux/bootmem.h> /* max_low_pfn */
328 #include <linux/vmalloc.h>
329 +#include <linux/pagemap.h>
331 #include <asm/system.h>
332 #include <asm/uaccess.h>
333 diff -NurpP --minimal linux-2.6.19.1/arch/arm/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/arm/Kconfig
334 --- linux-2.6.19.1/arch/arm/Kconfig 2006-11-30 21:18:24 +0100
335 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm/Kconfig 2006-11-30 20:55:45 +0100
336 @@ -935,6 +935,8 @@ source "arch/arm/oprofile/Kconfig"
338 source "arch/arm/Kconfig.debug"
340 +source "kernel/vserver/Kconfig"
342 source "security/Kconfig"
344 source "crypto/Kconfig"
345 diff -NurpP --minimal linux-2.6.19.1/arch/arm/kernel/calls.S linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/calls.S
346 --- linux-2.6.19.1/arch/arm/kernel/calls.S 2006-02-18 14:39:40 +0100
347 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/calls.S 2006-11-08 04:57:41 +0100
349 /* 310 */ CALL(sys_request_key)
351 CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
352 -/* vserver */ CALL(sys_ni_syscall)
355 /* 315 */ CALL(sys_ioprio_get)
356 CALL(sys_inotify_init)
357 diff -NurpP --minimal linux-2.6.19.1/arch/arm/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/process.c
358 --- linux-2.6.19.1/arch/arm/kernel/process.c 2006-11-30 21:18:24 +0100
359 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/process.c 2006-11-08 04:57:50 +0100
360 @@ -246,7 +246,8 @@ void __show_regs(struct pt_regs *regs)
361 void show_regs(struct pt_regs * regs)
364 - printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
365 + printk("Pid: %d[#%u], comm: %20s\n",
366 + current->pid, current->xid, current->comm);
370 @@ -469,7 +470,8 @@ pid_t kernel_thread(int (*fn)(void *), v
371 regs.ARM_pc = (unsigned long)kernel_thread_helper;
372 regs.ARM_cpsr = SVC_MODE;
374 - return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
375 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
376 + 0, ®s, 0, NULL, NULL);
378 EXPORT_SYMBOL(kernel_thread);
380 diff -NurpP --minimal linux-2.6.19.1/arch/arm/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/traps.c
381 --- linux-2.6.19.1/arch/arm/kernel/traps.c 2006-11-30 21:18:24 +0100
382 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/traps.c 2006-11-08 04:57:42 +0100
383 @@ -205,8 +205,8 @@ static void __die(const char *str, int e
384 printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
387 - printk("Process %s (pid: %d, stack limit = 0x%p)\n",
388 - tsk->comm, tsk->pid, thread + 1);
389 + printk("Process %s (pid: %d:#%u, stack limit = 0x%p)\n",
390 + tsk->comm, tsk->pid, tsk->xid, thread + 1);
392 if (!user_mode(regs) || in_interrupt()) {
393 dump_mem("Stack: ", regs->ARM_sp,
394 diff -NurpP --minimal linux-2.6.19.1/arch/arm26/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/arm26/Kconfig
395 --- linux-2.6.19.1/arch/arm26/Kconfig 2006-09-20 16:57:57 +0200
396 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm26/Kconfig 2006-11-08 04:57:40 +0100
397 @@ -234,6 +234,8 @@ source "drivers/usb/Kconfig"
399 source "arch/arm26/Kconfig.debug"
401 +source "kernel/vserver/Kconfig"
403 source "security/Kconfig"
405 source "crypto/Kconfig"
406 diff -NurpP --minimal linux-2.6.19.1/arch/arm26/kernel/calls.S linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/calls.S
407 --- linux-2.6.19.1/arch/arm26/kernel/calls.S 2005-03-02 12:38:19 +0100
408 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/calls.S 2006-11-08 04:57:41 +0100
409 @@ -257,6 +257,11 @@ __syscall_start:
410 .long sys_lremovexattr
411 .long sys_fremovexattr
414 + .rept 313 - (. - __syscall_start) / 4
415 + .long sys_ni_syscall
417 + .long sys_vserver /* 313 */
420 .rept NR_syscalls - (__syscall_end - __syscall_start) / 4
421 diff -NurpP --minimal linux-2.6.19.1/arch/arm26/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/process.c
422 --- linux-2.6.19.1/arch/arm26/kernel/process.c 2006-09-20 16:57:57 +0200
423 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/process.c 2006-11-08 04:57:50 +0100
424 @@ -365,7 +365,8 @@ pid_t kernel_thread(int (*fn)(void *), v
425 regs.ARM_r3 = (unsigned long)do_exit;
426 regs.ARM_pc = (unsigned long)kernel_thread_helper | MODE_SVC26;
428 - return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
429 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
430 + 0, ®s, 0, NULL, NULL);
432 EXPORT_SYMBOL(kernel_thread);
434 diff -NurpP --minimal linux-2.6.19.1/arch/arm26/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/traps.c
435 --- linux-2.6.19.1/arch/arm26/kernel/traps.c 2006-09-20 16:57:57 +0200
436 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/traps.c 2006-11-08 04:57:42 +0100
437 @@ -185,8 +185,9 @@ NORET_TYPE void die(const char *str, str
438 printk("Internal error: %s: %x\n", str, err);
439 printk("CPU: %d\n", smp_processor_id());
441 - printk("Process %s (pid: %d, stack limit = 0x%p)\n",
442 - current->comm, current->pid, end_of_stack(tsk));
443 + printk("Process %s (pid: %d[#%u], stack limit = 0x%p)\n",
444 + current->comm, current->pid,
445 + current->xid, end_of_stack(tsk));
447 if (!user_mode(regs) || in_interrupt()) {
448 __dump_stack(tsk, (unsigned long)(regs + 1));
449 diff -NurpP --minimal linux-2.6.19.1/arch/cris/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/cris/Kconfig
450 --- linux-2.6.19.1/arch/cris/Kconfig 2006-09-20 16:57:57 +0200
451 +++ linux-2.6.19.1-vs2.3.0.6/arch/cris/Kconfig 2006-11-08 04:57:40 +0100
452 @@ -185,6 +185,8 @@ source "drivers/usb/Kconfig"
454 source "arch/cris/Kconfig.debug"
456 +source "kernel/vserver/Kconfig"
458 source "security/Kconfig"
460 source "crypto/Kconfig"
461 diff -NurpP --minimal linux-2.6.19.1/arch/cris/arch-v10/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/cris/arch-v10/kernel/process.c
462 --- linux-2.6.19.1/arch/cris/arch-v10/kernel/process.c 2006-09-20 16:57:57 +0200
463 +++ linux-2.6.19.1-vs2.3.0.6/arch/cris/arch-v10/kernel/process.c 2006-11-08 04:57:50 +0100
464 @@ -103,7 +103,8 @@ int kernel_thread(int (*fn)(void *), voi
465 regs.dccr = 1 << I_DCCR_BITNR;
467 /* Ok, create the new process.. */
468 - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
469 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
470 + 0, ®s, 0, NULL, NULL);
473 /* setup the child's kernel stack with a pt_regs and switch_stack on it.
474 diff -NurpP --minimal linux-2.6.19.1/arch/cris/arch-v32/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/cris/arch-v32/kernel/process.c
475 --- linux-2.6.19.1/arch/cris/arch-v32/kernel/process.c 2006-09-20 16:57:57 +0200
476 +++ linux-2.6.19.1-vs2.3.0.6/arch/cris/arch-v32/kernel/process.c 2006-11-08 04:57:50 +0100
477 @@ -120,7 +120,8 @@ kernel_thread(int (*fn)(void *), void *
478 regs.ccs = 1 << (I_CCS_BITNR + CCS_SHIFT);
480 /* Create the new process. */
481 - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
482 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
483 + 0, ®s, 0, NULL, NULL);
487 diff -NurpP --minimal linux-2.6.19.1/arch/cris/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/cris/kernel/irq.c
488 --- linux-2.6.19.1/arch/cris/kernel/irq.c 2006-09-20 16:57:57 +0200
489 +++ linux-2.6.19.1-vs2.3.0.6/arch/cris/kernel/irq.c 2006-11-30 18:26:05 +0100
490 @@ -92,6 +92,7 @@ skip:
491 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
497 if (unlikely((sp & (PAGE_SIZE - 1)) < (PAGE_SIZE/8))) {
498 diff -NurpP --minimal linux-2.6.19.1/arch/frv/kernel/kernel_thread.S linux-2.6.19.1-vs2.3.0.6/arch/frv/kernel/kernel_thread.S
499 --- linux-2.6.19.1/arch/frv/kernel/kernel_thread.S 2005-03-02 12:38:20 +0100
500 +++ linux-2.6.19.1-vs2.3.0.6/arch/frv/kernel/kernel_thread.S 2006-11-08 04:57:50 +0100
502 #include <asm/unistd.h>
504 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
505 +#define CLONE_KTHREAD 0x10000000 /* kernel thread */
506 +#define CLONE_KT (CLONE_VM | CLONE_KTHREAD) /* kernel thread flags */
507 #define KERN_ERR "<3>"
510 @@ -37,7 +39,7 @@ kernel_thread:
512 # start by forking the current process, but with shared VM
513 setlos.p #__NR_clone,gr7 ; syscall number
514 - ori gr10,#CLONE_VM,gr8 ; first syscall arg [clone_flags]
515 + ori gr10,#CLONE_KT,gr8 ; first syscall arg [clone_flags]
516 sethi.p #0xe4e4,gr9 ; second syscall arg [newsp]
518 setlos.p #0,gr10 ; third syscall arg [parent_tidptr]
519 diff -NurpP --minimal linux-2.6.19.1/arch/h8300/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/h8300/Kconfig
520 --- linux-2.6.19.1/arch/h8300/Kconfig 2006-06-18 04:51:49 +0200
521 +++ linux-2.6.19.1-vs2.3.0.6/arch/h8300/Kconfig 2006-11-08 04:57:40 +0100
522 @@ -199,6 +199,8 @@ source "fs/Kconfig"
524 source "arch/h8300/Kconfig.debug"
526 +source "kernel/vserver/Kconfig"
528 source "security/Kconfig"
530 source "crypto/Kconfig"
531 diff -NurpP --minimal linux-2.6.19.1/arch/h8300/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/h8300/kernel/process.c
532 --- linux-2.6.19.1/arch/h8300/kernel/process.c 2006-09-20 16:57:58 +0200
533 +++ linux-2.6.19.1-vs2.3.0.6/arch/h8300/kernel/process.c 2006-11-08 04:57:50 +0100
534 @@ -134,7 +134,7 @@ int kernel_thread(int (*fn)(void *), voi
538 - clone_arg = flags | CLONE_VM;
539 + clone_arg = flags | CLONE_VM | CLONE_KTHREAD;
540 __asm__("mov.l sp,er3\n\t"
543 diff -NurpP --minimal linux-2.6.19.1/arch/i386/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/i386/Kconfig
544 --- linux-2.6.19.1/arch/i386/Kconfig 2006-11-30 21:18:25 +0100
545 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/Kconfig 2006-11-08 04:57:40 +0100
546 @@ -1153,6 +1153,8 @@ endmenu
548 source "arch/i386/Kconfig.debug"
550 +source "kernel/vserver/Kconfig"
552 source "security/Kconfig"
554 source "crypto/Kconfig"
555 diff -NurpP --minimal linux-2.6.19.1/arch/i386/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/irq.c
556 --- linux-2.6.19.1/arch/i386/kernel/irq.c 2006-11-30 21:18:26 +0100
557 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/irq.c 2006-11-30 18:26:37 +0100
558 @@ -84,7 +84,6 @@ fastcall unsigned int do_IRQ(struct pt_r
563 #ifdef CONFIG_4KSTACKS
565 curctx = (union irq_ctx *) current_thread_info();
566 @@ -124,7 +123,6 @@ fastcall unsigned int do_IRQ(struct pt_r
569 desc->handle_irq(irq, desc);
572 set_irq_regs(old_regs);
574 diff -NurpP --minimal linux-2.6.19.1/arch/i386/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/process.c
575 --- linux-2.6.19.1/arch/i386/kernel/process.c 2006-11-30 21:18:26 +0100
576 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/process.c 2006-11-30 20:55:45 +0100
577 @@ -300,8 +300,10 @@ void show_regs(struct pt_regs * regs)
578 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
581 - printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
582 - printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
583 + printk("Pid: %d[#%u], comm: %20s\n",
584 + current->pid, current->xid, current->comm);
585 + printk("EIP: %04x:[<%08lx>] CPU: %d\n",
586 + 0xffff & regs->xcs,regs->eip, smp_processor_id());
587 print_symbol("EIP is at %s\n", regs->eip);
589 if (user_mode_vm(regs))
590 @@ -352,7 +354,8 @@ int kernel_thread(int (*fn)(void *), voi
591 regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
593 /* Ok, create the new process.. */
594 - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
595 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
596 + 0, ®s, 0, NULL, NULL);
598 EXPORT_SYMBOL(kernel_thread);
600 diff -NurpP --minimal linux-2.6.19.1/arch/i386/kernel/syscall_table.S linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/syscall_table.S
601 --- linux-2.6.19.1/arch/i386/kernel/syscall_table.S 2006-11-30 21:18:26 +0100
602 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/syscall_table.S 2006-11-08 04:57:41 +0100
603 @@ -272,7 +272,7 @@ ENTRY(sys_call_table)
604 .long sys_tgkill /* 270 */
606 .long sys_fadvise64_64
607 - .long sys_ni_syscall /* sys_vserver */
610 .long sys_get_mempolicy
611 .long sys_set_mempolicy
612 diff -NurpP --minimal linux-2.6.19.1/arch/i386/kernel/sysenter.c linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/sysenter.c
613 --- linux-2.6.19.1/arch/i386/kernel/sysenter.c 2006-09-20 16:57:58 +0200
614 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/sysenter.c 2006-11-08 04:57:47 +0100
616 #include <linux/elf.h>
617 #include <linux/mm.h>
618 #include <linux/module.h>
619 +#include <linux/vs_memory.h>
621 #include <asm/cpufeature.h>
623 @@ -156,7 +157,7 @@ int arch_setup_additional_pages(struct l
624 current->mm->context.vdso = (void *)addr;
625 current_thread_info()->sysenter_return =
626 (void *)VDSO_SYM(&SYSENTER_RETURN);
628 + vx_vmpages_inc(mm);
630 up_write(&mm->mmap_sem);
632 diff -NurpP --minimal linux-2.6.19.1/arch/i386/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/traps.c
633 --- linux-2.6.19.1/arch/i386/kernel/traps.c 2006-11-30 21:18:26 +0100
634 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/traps.c 2006-11-30 20:55:45 +0100
636 #include <asm/stacktrace.h>
638 #include <linux/module.h>
639 +#include <linux/vs_context.h>
640 +#include <linux/vserver/history.h>
642 #include "mach_traps.h"
644 @@ -371,8 +373,8 @@ void show_registers(struct pt_regs *regs
645 regs->esi, regs->edi, regs->ebp, esp);
646 printk(KERN_EMERG "ds: %04x es: %04x ss: %04x\n",
647 regs->xds & 0xffff, regs->xes & 0xffff, ss);
648 - printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",
649 - TASK_COMM_LEN, current->comm, current->pid,
650 + printk(KERN_EMERG "Process %.*s (pid: %d[#%u], ti=%p task=%p task.ti=%p)",
651 + TASK_COMM_LEN, current->comm, current->pid, current->xid,
652 current_thread_info(), current, current->thread_info);
654 * When in-kernel, we also print out the stack and code at the
655 @@ -461,6 +463,8 @@ void die(const char * str, struct pt_reg
661 if (die.lock_owner != raw_smp_processor_id()) {
663 spin_lock_irqsave(&die.lock, flags);
664 @@ -497,9 +501,9 @@ void die(const char * str, struct pt_reg
667 if (notify_die(DIE_OOPS, str, regs, err,
668 - current->thread.trap_no, SIGSEGV) !=
670 + current->thread.trap_no, SIGSEGV) != NOTIFY_STOP) {
671 show_registers(regs);
672 + vxh_dump_history();
673 /* Executive summary in case the oops scrolled away */
674 esp = (unsigned long) (®s->esp);
676 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/ia64/Kconfig
677 --- linux-2.6.19.1/arch/ia64/Kconfig 2006-11-30 21:18:26 +0100
678 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/Kconfig 2006-11-20 21:12:32 +0100
679 @@ -537,6 +537,8 @@ endmenu
681 source "arch/ia64/Kconfig.debug"
683 +source "kernel/vserver/Kconfig"
685 source "security/Kconfig"
687 source "crypto/Kconfig"
688 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/ia32/binfmt_elf32.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/binfmt_elf32.c
689 --- linux-2.6.19.1/arch/ia64/ia32/binfmt_elf32.c 2006-09-20 16:57:58 +0200
690 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/binfmt_elf32.c 2006-11-08 04:57:47 +0100
691 @@ -238,7 +238,8 @@ ia32_setup_arg_pages (struct linux_binpr
692 kmem_cache_free(vm_area_cachep, mpnt);
695 - current->mm->stack_vm = current->mm->total_vm = vma_pages(mpnt);
696 + vx_vmpages_sub(current->mm, current->mm->total_vm - vma_pages(mpnt));
697 + current->mm->stack_vm = current->mm->total_vm;
700 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
701 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/ia32/ia32_entry.S linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/ia32_entry.S
702 --- linux-2.6.19.1/arch/ia64/ia32/ia32_entry.S 2006-06-18 04:51:55 +0200
703 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/ia32_entry.S 2006-11-08 04:57:41 +0100
704 @@ -483,7 +483,7 @@ ia32_syscall_table:
705 data8 sys_tgkill /* 270 */
706 data8 compat_sys_utimes
707 data8 sys32_fadvise64_64
708 - data8 sys_ni_syscall
709 + data8 sys32_vserver
711 data8 sys_ni_syscall /* 275 */
713 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/ia32/sys_ia32.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/sys_ia32.c
714 --- linux-2.6.19.1/arch/ia64/ia32/sys_ia32.c 2006-11-30 21:18:26 +0100
715 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/sys_ia32.c 2006-11-08 04:57:44 +0100
716 @@ -1182,7 +1182,7 @@ sys32_gettimeofday (struct compat_timeva
720 - do_gettimeofday(&ktv);
721 + vx_gettimeofday(&ktv);
722 if (put_tv32(tv, &ktv))
725 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/asm-offsets.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/asm-offsets.c
726 --- linux-2.6.19.1/arch/ia64/kernel/asm-offsets.c 2006-09-20 16:57:58 +0200
727 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/asm-offsets.c 2006-11-08 04:57:50 +0100
728 @@ -191,6 +191,7 @@ void foo(void)
729 /* for assembly files which can't include sched.h: */
730 DEFINE(IA64_CLONE_VFORK, CLONE_VFORK);
731 DEFINE(IA64_CLONE_VM, CLONE_VM);
732 + DEFINE(IA64_CLONE_KTHREAD, CLONE_KTHREAD);
735 DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET,
736 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/entry.S linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/entry.S
737 --- linux-2.6.19.1/arch/ia64/kernel/entry.S 2006-11-30 21:18:26 +0100
738 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/entry.S 2006-11-08 04:57:41 +0100
739 @@ -1576,7 +1576,7 @@ sys_call_table:
741 data8 sys_mq_getsetattr
742 data8 sys_ni_syscall // reserved for kexec_load
743 - data8 sys_ni_syscall // reserved for vserver
745 data8 sys_waitid // 1270
747 data8 sys_request_key
748 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/perfmon.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/perfmon.c
749 --- linux-2.6.19.1/arch/ia64/kernel/perfmon.c 2006-11-30 21:18:27 +0100
750 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/perfmon.c 2006-11-08 04:57:47 +0100
752 #include <linux/capability.h>
753 #include <linux/rcupdate.h>
754 #include <linux/completion.h>
755 +#include <linux/vs_memory.h>
757 #include <asm/errno.h>
758 #include <asm/intrinsics.h>
759 @@ -2357,7 +2358,7 @@ pfm_smpl_buffer_alloc(struct task_struct
761 insert_vm_struct(mm, vma);
763 - mm->total_vm += size >> PAGE_SHIFT;
764 + vx_vmpages_add(mm, size >> PAGE_SHIFT);
765 vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
767 up_write(&task->mm->mmap_sem);
768 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/process.c
769 --- linux-2.6.19.1/arch/ia64/kernel/process.c 2006-11-30 21:18:27 +0100
770 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/process.c 2006-11-08 04:57:50 +0100
771 @@ -105,7 +105,8 @@ show_regs (struct pt_regs *regs)
772 unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
775 - printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
776 + printk("\nPid: %d[#%u], CPU %d, comm: %20s\n",
777 + current->pid, current->xid, smp_processor_id(), current->comm);
778 printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n",
779 regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
780 print_symbol("ip is at %s\n", ip);
781 @@ -688,7 +689,8 @@ kernel_thread (int (*fn)(void *), void *
782 regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR);
783 regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET;
784 regs.sw.pr = (1 << PRED_KERNEL_STACK);
785 - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s.pt, 0, NULL, NULL);
786 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
787 + 0, ®s.pt, 0, NULL, NULL);
789 EXPORT_SYMBOL(kernel_thread);
791 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/ptrace.c
792 --- linux-2.6.19.1/arch/ia64/kernel/ptrace.c 2006-09-20 16:57:58 +0200
793 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/ptrace.c 2006-11-30 18:53:18 +0100
795 #include <linux/security.h>
796 #include <linux/audit.h>
797 #include <linux/signal.h>
798 +#include <linux/vs_base.h>
800 #include <asm/pgtable.h>
801 #include <asm/processor.h>
802 @@ -1442,6 +1443,9 @@ sys_ptrace (long request, pid_t pid, uns
803 read_unlock(&tasklist_lock);
806 + if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT))
810 if (pid == 1) /* no messing around with init! */
812 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/traps.c
813 --- linux-2.6.19.1/arch/ia64/kernel/traps.c 2006-09-20 16:57:58 +0200
814 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/traps.c 2006-11-08 04:57:42 +0100
815 @@ -106,8 +106,9 @@ die (const char *str, struct pt_regs *re
818 if (++die.lock_owner_depth < 3) {
819 - printk("%s[%d]: %s %ld [%d]\n",
820 - current->comm, current->pid, str, err, ++die_counter);
821 + printk("%s[%d[#%u]]: %s %ld [%d]\n",
822 + current->comm, current->pid, current->xid,
823 + str, err, ++die_counter);
824 (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
827 @@ -331,8 +332,9 @@ handle_fpu_swa (int fp_fault, struct pt_
831 - "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
832 - current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
833 + "%s(%d[#%u]): floating-point assist fault at ip %016lx, isr %016lx\n",
834 + current->comm, current->pid, current->xid,
835 + regs->cr_iip + ia64_psr(regs)->ri, isr);
838 exception = fp_emulate(fp_fault, bundle, ®s->cr_ipsr, ®s->ar_fpsr, &isr, ®s->pr,
839 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/mm/fault.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/mm/fault.c
840 --- linux-2.6.19.1/arch/ia64/mm/fault.c 2006-11-30 21:18:27 +0100
841 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/mm/fault.c 2006-11-08 04:57:40 +0100
843 #include <linux/smp_lock.h>
844 #include <linux/interrupt.h>
845 #include <linux/kprobes.h>
846 +#include <linux/vs_memory.h>
848 #include <asm/pgtable.h>
849 #include <asm/processor.h>
850 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/sn/kernel/xpc_main.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/sn/kernel/xpc_main.c
851 --- linux-2.6.19.1/arch/ia64/sn/kernel/xpc_main.c 2006-11-30 21:18:28 +0100
852 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/sn/kernel/xpc_main.c 2006-11-08 04:57:40 +0100
853 @@ -108,6 +108,7 @@ static ctl_table xpc_sys_xpc_hb_dir[] =
856 &proc_dointvec_minmax,
860 &xpc_hb_min_interval,
861 @@ -121,6 +122,7 @@ static ctl_table xpc_sys_xpc_hb_dir[] =
864 &proc_dointvec_minmax,
868 &xpc_hb_check_min_interval,
869 @@ -145,6 +147,7 @@ static ctl_table xpc_sys_xpc_dir[] = {
872 &proc_dointvec_minmax,
876 &xpc_disengage_request_min_timelimit,
877 diff -NurpP --minimal linux-2.6.19.1/arch/m32r/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/irq.c
878 --- linux-2.6.19.1/arch/m32r/kernel/irq.c 2006-11-30 21:18:28 +0100
879 +++ linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/irq.c 2006-11-30 18:26:50 +0100
880 @@ -78,6 +78,7 @@ skip:
881 asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs)
883 struct pt_regs *old_regs;
885 old_regs = set_irq_regs(regs);
888 diff -NurpP --minimal linux-2.6.19.1/arch/m32r/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/process.c
889 --- linux-2.6.19.1/arch/m32r/kernel/process.c 2006-09-20 16:57:58 +0200
890 +++ linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/process.c 2006-11-08 04:57:50 +0100
891 @@ -211,8 +211,8 @@ int kernel_thread(int (*fn)(void *), voi
892 regs.psw = M32R_PSW_BIE;
894 /* Ok, create the new process. */
895 - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL,
897 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
898 + 0, ®s, 0, NULL, NULL);
902 diff -NurpP --minimal linux-2.6.19.1/arch/m32r/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/traps.c
903 --- linux-2.6.19.1/arch/m32r/kernel/traps.c 2006-11-30 21:18:28 +0100
904 +++ linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/traps.c 2006-11-08 04:57:42 +0100
905 @@ -195,8 +195,9 @@ static void show_registers(struct pt_reg
907 printk("SPI: %08lx\n", sp);
909 - printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
910 - current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current);
911 + printk("Process %s (pid: %d[#%u], process nr: %d, stackpage=%08lx)",
912 + current->comm, current->pid, current->xid,
913 + 0xffff & i, 4096+(unsigned long)current);
916 * When in-kernel, we also print out the stack and code at the
917 diff -NurpP --minimal linux-2.6.19.1/arch/m68k/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/m68k/Kconfig
918 --- linux-2.6.19.1/arch/m68k/Kconfig 2006-11-30 21:18:28 +0100
919 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68k/Kconfig 2006-11-08 04:57:40 +0100
920 @@ -654,6 +654,8 @@ source "fs/Kconfig"
922 source "arch/m68k/Kconfig.debug"
924 +source "kernel/vserver/Kconfig"
926 source "security/Kconfig"
928 source "crypto/Kconfig"
929 diff -NurpP --minimal linux-2.6.19.1/arch/m68k/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/process.c
930 --- linux-2.6.19.1/arch/m68k/kernel/process.c 2006-11-30 21:18:28 +0100
931 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/process.c 2006-11-08 04:57:50 +0100
932 @@ -159,7 +159,8 @@ int kernel_thread(int (*fn)(void *), voi
935 register long retval __asm__ ("d0");
936 - register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
937 + register long clone_arg __asm__ ("d1") =
938 + flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
942 diff -NurpP --minimal linux-2.6.19.1/arch/m68k/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/ptrace.c
943 --- linux-2.6.19.1/arch/m68k/kernel/ptrace.c 2006-09-20 16:57:58 +0200
944 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/ptrace.c 2006-11-30 18:53:18 +0100
946 #include <linux/ptrace.h>
947 #include <linux/user.h>
948 #include <linux/signal.h>
949 +#include <linux/vs_base.h>
951 #include <asm/uaccess.h>
952 #include <asm/page.h>
953 @@ -279,6 +280,8 @@ long arch_ptrace(struct task_struct *chi
954 ret = ptrace_request(child, request, addr, data);
957 + if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT))
962 diff -NurpP --minimal linux-2.6.19.1/arch/m68k/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/traps.c
963 --- linux-2.6.19.1/arch/m68k/kernel/traps.c 2006-11-30 21:18:28 +0100
964 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/traps.c 2006-11-08 04:57:42 +0100
965 @@ -899,8 +899,8 @@ void show_registers(struct pt_regs *regs
966 printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
967 regs->d4, regs->d5, regs->a0, regs->a1);
969 - printk("Process %s (pid: %d, task=%p)\n",
970 - current->comm, current->pid, current);
971 + printk("Process %s (pid: %d[#%u], task=%p)\n",
972 + current->comm, current->pid, current->xid, current);
973 addr = (unsigned long)&fp->un;
974 printk("Frame format=%X ", regs->format);
975 switch (regs->format) {
976 diff -NurpP --minimal linux-2.6.19.1/arch/m68knommu/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/Kconfig
977 --- linux-2.6.19.1/arch/m68knommu/Kconfig 2006-11-30 21:18:28 +0100
978 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/Kconfig 2006-11-08 04:57:40 +0100
979 @@ -663,6 +663,8 @@ source "fs/Kconfig"
981 source "arch/m68knommu/Kconfig.debug"
983 +source "kernel/vserver/Kconfig"
985 source "security/Kconfig"
987 source "crypto/Kconfig"
988 diff -NurpP --minimal linux-2.6.19.1/arch/m68knommu/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/kernel/process.c
989 --- linux-2.6.19.1/arch/m68knommu/kernel/process.c 2006-09-20 16:57:58 +0200
990 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/kernel/process.c 2006-11-08 04:57:50 +0100
991 @@ -122,7 +122,7 @@ void show_regs(struct pt_regs * regs)
992 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
995 - long clone_arg = flags | CLONE_VM;
996 + long clone_arg = flags | CLONE_VM | CLONE_KTHREAD;
1000 diff -NurpP --minimal linux-2.6.19.1/arch/m68knommu/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/kernel/traps.c
1001 --- linux-2.6.19.1/arch/m68knommu/kernel/traps.c 2006-09-20 16:57:58 +0200
1002 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/kernel/traps.c 2006-11-08 04:57:42 +0100
1003 @@ -80,8 +80,9 @@ void die_if_kernel(char *str, struct pt_
1004 printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
1005 fp->d4, fp->d5, fp->a0, fp->a1);
1007 - printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n",
1008 - current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
1009 + printk(KERN_EMERG "Process %s (pid: %d[#%u], stackpage=%08lx)\n",
1010 + current->comm, current->pid, current->xid,
1011 + PAGE_SIZE+(unsigned long)current);
1012 show_stack(NULL, (unsigned long *)fp);
1015 diff -NurpP --minimal linux-2.6.19.1/arch/mips/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/mips/Kconfig
1016 --- linux-2.6.19.1/arch/mips/Kconfig 2006-11-30 21:18:28 +0100
1017 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/Kconfig 2006-11-08 21:52:07 +0100
1018 @@ -2006,6 +2006,8 @@ source "arch/mips/oprofile/Kconfig"
1020 source "arch/mips/Kconfig.debug"
1022 +source "kernel/vserver/Kconfig"
1024 source "security/Kconfig"
1026 source "crypto/Kconfig"
1027 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/linux32.c linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/linux32.c
1028 --- linux-2.6.19.1/arch/mips/kernel/linux32.c 2006-11-30 21:18:29 +0100
1029 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/linux32.c 2006-12-02 01:37:05 +0100
1030 @@ -300,7 +300,7 @@ sys32_gettimeofday(struct compat_timeval
1034 - do_gettimeofday(&ktv);
1035 + vx_gettimeofday(&ktv);
1036 if (put_tv32(tv, &ktv))
1039 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/process.c
1040 --- linux-2.6.19.1/arch/mips/kernel/process.c 2006-11-30 21:18:29 +0100
1041 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/process.c 2006-11-08 04:57:50 +0100
1042 @@ -271,7 +271,8 @@ long kernel_thread(int (*fn)(void *), vo
1045 /* Ok, create the new process.. */
1046 - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
1047 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
1048 + 0, ®s, 0, NULL, NULL);
1052 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/ptrace.c
1053 --- linux-2.6.19.1/arch/mips/kernel/ptrace.c 2006-11-30 21:18:29 +0100
1054 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/ptrace.c 2006-11-30 18:53:18 +0100
1056 #include <linux/user.h>
1057 #include <linux/security.h>
1058 #include <linux/signal.h>
1059 +#include <linux/vs_base.h>
1061 #include <asm/byteorder.h>
1062 #include <asm/cpu.h>
1063 @@ -172,6 +173,9 @@ long arch_ptrace(struct task_struct *chi
1067 + if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT))
1071 /* when I and D space are separate, these will need to be fixed. */
1072 case PTRACE_PEEKTEXT: /* read word at location addr. */
1073 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/scall32-o32.S linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall32-o32.S
1074 --- linux-2.6.19.1/arch/mips/kernel/scall32-o32.S 2006-11-30 21:18:29 +0100
1075 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall32-o32.S 2006-11-08 04:57:41 +0100
1076 @@ -619,7 +619,7 @@ einval: li v0, -EINVAL
1077 sys sys_mq_timedreceive 5
1078 sys sys_mq_notify 2 /* 4275 */
1079 sys sys_mq_getsetattr 3
1080 - sys sys_ni_syscall 0 /* sys_vserver */
1083 sys sys_ni_syscall 0 /* available, was setaltroot */
1084 sys sys_add_key 5 /* 4280 */
1085 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/scall64-64.S linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-64.S
1086 --- linux-2.6.19.1/arch/mips/kernel/scall64-64.S 2006-11-30 21:18:29 +0100
1087 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-64.S 2006-11-08 04:57:41 +0100
1088 @@ -434,7 +434,7 @@ sys_call_table:
1089 PTR sys_mq_timedreceive
1091 PTR sys_mq_getsetattr /* 5235 */
1092 - PTR sys_ni_syscall /* sys_vserver */
1095 PTR sys_ni_syscall /* available, was setaltroot */
1097 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/scall64-n32.S linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-n32.S
1098 --- linux-2.6.19.1/arch/mips/kernel/scall64-n32.S 2006-11-30 21:18:29 +0100
1099 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-n32.S 2006-11-08 04:57:41 +0100
1100 @@ -360,7 +360,7 @@ EXPORT(sysn32_call_table)
1101 PTR compat_sys_mq_timedreceive
1102 PTR compat_sys_mq_notify
1103 PTR compat_sys_mq_getsetattr
1104 - PTR sys_ni_syscall /* 6240, sys_vserver */
1105 + PTR sys32_vserver /* 6240 */
1107 PTR sys_ni_syscall /* available, was setaltroot */
1109 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/scall64-o32.S linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-o32.S
1110 --- linux-2.6.19.1/arch/mips/kernel/scall64-o32.S 2006-11-30 21:18:29 +0100
1111 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-o32.S 2006-11-08 04:57:41 +0100
1112 @@ -482,7 +482,7 @@ sys_call_table:
1113 PTR compat_sys_mq_timedreceive
1114 PTR compat_sys_mq_notify /* 4275 */
1115 PTR compat_sys_mq_getsetattr
1116 - PTR sys_ni_syscall /* sys_vserver */
1119 PTR sys_ni_syscall /* available, was setaltroot */
1120 PTR sys_add_key /* 4280 */
1121 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/traps.c
1122 --- linux-2.6.19.1/arch/mips/kernel/traps.c 2006-11-30 21:18:29 +0100
1123 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/traps.c 2006-11-08 21:52:08 +0100
1124 @@ -297,8 +297,9 @@ void show_registers(struct pt_regs *regs
1128 - printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
1129 - current->comm, current->pid, current_thread_info(), current);
1130 + printk("Process %s (pid: %d:#%u, threadinfo=%p, task=%p)\n",
1131 + current->comm, current->pid, current->xid,
1132 + current_thread_info(), current);
1133 show_stacktrace(current, regs);
1134 show_code((unsigned int *) regs->cp0_epc);
1136 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/parisc/Kconfig
1137 --- linux-2.6.19.1/arch/parisc/Kconfig 2006-11-30 21:18:30 +0100
1138 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/Kconfig 2006-11-08 04:57:40 +0100
1139 @@ -257,6 +257,8 @@ source "arch/parisc/oprofile/Kconfig"
1141 source "arch/parisc/Kconfig.debug"
1143 +source "kernel/vserver/Kconfig"
1145 source "security/Kconfig"
1147 source "crypto/Kconfig"
1148 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/kernel/entry.S linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/entry.S
1149 --- linux-2.6.19.1/arch/parisc/kernel/entry.S 2006-11-30 21:18:30 +0100
1150 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/entry.S 2006-11-08 04:57:50 +0100
1151 @@ -761,6 +761,7 @@ fault_vector_11:
1153 #define CLONE_VM 0x100 /* Must agree with <linux/sched.h> */
1154 #define CLONE_UNTRACED 0x00800000
1155 +#define CLONE_KTHREAD 0x10000000
1157 .export __kernel_thread, code
1159 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/process.c
1160 --- linux-2.6.19.1/arch/parisc/kernel/process.c 2006-11-30 21:18:30 +0100
1161 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/process.c 2006-11-08 04:57:50 +0100
1162 @@ -173,7 +173,7 @@ pid_t kernel_thread(int (*fn)(void *), v
1163 * kernel_thread can become a #define.
1166 - return __kernel_thread(fn, arg, flags);
1167 + return __kernel_thread(fn, arg, flags | CLONE_KTHREAD);
1169 EXPORT_SYMBOL(kernel_thread);
1171 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/kernel/sys_parisc32.c linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/sys_parisc32.c
1172 --- linux-2.6.19.1/arch/parisc/kernel/sys_parisc32.c 2006-11-30 21:18:31 +0100
1173 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/sys_parisc32.c 2006-11-08 04:57:44 +0100
1174 @@ -204,11 +204,11 @@ static inline long get_ts32(struct times
1176 sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
1178 - extern void do_gettimeofday(struct timeval *tv);
1179 + extern void vx_gettimeofday(struct timeval *tv);
1183 - do_gettimeofday(&ktv);
1184 + vx_gettimeofday(&ktv);
1185 if (put_compat_timeval(tv, &ktv))
1188 @@ -612,6 +612,7 @@ asmlinkage int sys32_sysinfo(struct sysi
1191 seq = read_seqbegin(&xtime_lock);
1192 + /* FIXME: requires vx virtualization */
1193 val.uptime = jiffies / HZ;
1195 val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
1196 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/kernel/syscall_table.S linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/syscall_table.S
1197 --- linux-2.6.19.1/arch/parisc/kernel/syscall_table.S 2006-11-30 21:18:31 +0100
1198 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/syscall_table.S 2006-11-08 04:57:41 +0100
1200 ENTRY_COMP(mbind) /* 260 */
1201 ENTRY_COMP(get_mempolicy)
1202 ENTRY_COMP(set_mempolicy)
1203 - ENTRY_SAME(ni_syscall) /* 263: reserved for vserver */
1204 + ENTRY_DIFF(vserver)
1206 ENTRY_SAME(request_key) /* 265 */
1208 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/traps.c
1209 --- linux-2.6.19.1/arch/parisc/kernel/traps.c 2006-11-30 21:18:31 +0100
1210 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/traps.c 2006-11-08 04:57:42 +0100
1211 @@ -210,8 +210,9 @@ void die_if_kernel(char *str, struct pt_
1215 - printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
1216 - current->comm, current->pid, str, err, regs->iaoq[0]);
1217 + printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld) at " RFMT "\n",
1218 + current->comm, current->pid, current->xid,
1219 + str, err, regs->iaoq[0]);
1220 #ifdef PRINT_USER_FAULTS
1221 /* XXX for debugging only */
1223 @@ -242,8 +243,8 @@ void die_if_kernel(char *str, struct pt_
1224 if (!console_drivers)
1225 pdc_console_restart();
1227 - printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
1228 - current->comm, current->pid, str, err);
1229 + printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld)\n",
1230 + current->comm, current->pid, current->xid, str, err);
1234 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/mm/fault.c linux-2.6.19.1-vs2.3.0.6/arch/parisc/mm/fault.c
1235 --- linux-2.6.19.1/arch/parisc/mm/fault.c 2006-06-18 04:52:15 +0200
1236 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/mm/fault.c 2006-11-08 04:57:42 +0100
1237 @@ -213,8 +213,9 @@ bad_area:
1239 #ifdef PRINT_USER_FAULTS
1240 printk(KERN_DEBUG "\n");
1241 - printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n",
1242 - tsk->pid, tsk->comm, code, address);
1243 + printk(KERN_DEBUG "do_page_fault() pid=%d:#%u "
1244 + "command='%s' type=%lu address=0x%08lx\n",
1245 + tsk->pid, tsk->xid, tsk->comm, code, address);
1247 printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n",
1248 vma->vm_start, vma->vm_end);
1249 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/powerpc/Kconfig
1250 --- linux-2.6.19.1/arch/powerpc/Kconfig 2006-11-30 21:18:31 +0100
1251 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/Kconfig 2006-11-20 21:12:32 +0100
1252 @@ -1102,6 +1102,8 @@ endmenu
1254 source "arch/powerpc/Kconfig.debug"
1256 +source "kernel/vserver/Kconfig"
1258 source "security/Kconfig"
1261 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/asm-offsets.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/asm-offsets.c
1262 --- linux-2.6.19.1/arch/powerpc/kernel/asm-offsets.c 2006-11-30 21:18:31 +0100
1263 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/asm-offsets.c 2006-11-08 04:57:50 +0100
1264 @@ -243,6 +243,7 @@ int main(void)
1266 DEFINE(CLONE_VM, CLONE_VM);
1267 DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
1268 + DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
1270 #ifndef CONFIG_PPC64
1271 DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
1272 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/irq.c
1273 --- linux-2.6.19.1/arch/powerpc/kernel/irq.c 2006-11-30 21:18:31 +0100
1274 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/irq.c 2006-11-30 18:27:23 +0100
1276 #include <linux/mutex.h>
1277 #include <linux/bootmem.h>
1278 #include <linux/pci.h>
1279 +#include <linux/vs_context.h>
1281 #include <asm/uaccess.h>
1282 #include <asm/system.h>
1283 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/misc_32.S linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/misc_32.S
1284 --- linux-2.6.19.1/arch/powerpc/kernel/misc_32.S 2006-11-30 21:18:31 +0100
1285 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/misc_32.S 2006-11-08 04:57:50 +0100
1286 @@ -749,7 +749,7 @@ _GLOBAL(kernel_thread)
1287 mr r30,r3 /* function */
1288 mr r31,r4 /* argument */
1289 ori r3,r5,CLONE_VM /* flags */
1290 - oris r3,r3,CLONE_UNTRACED>>16
1291 + oris r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
1292 li r4,0 /* new sp (unused) */
1295 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/misc_64.S linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/misc_64.S
1296 --- linux-2.6.19.1/arch/powerpc/kernel/misc_64.S 2006-11-30 21:18:31 +0100
1297 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/misc_64.S 2006-11-08 04:57:50 +0100
1298 @@ -394,7 +394,7 @@ _GLOBAL(kernel_thread)
1301 ori r3,r5,CLONE_VM /* flags */
1302 - oris r3,r3,(CLONE_UNTRACED>>16)
1303 + oris r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
1304 li r4,0 /* new sp (unused) */
1307 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/process.c
1308 --- linux-2.6.19.1/arch/powerpc/kernel/process.c 2006-11-30 21:18:31 +0100
1309 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/process.c 2006-11-08 04:57:42 +0100
1310 @@ -425,8 +425,9 @@ void show_regs(struct pt_regs * regs)
1312 if (trap == 0x300 || trap == 0x600)
1313 printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
1314 - printk("TASK = %p[%d] '%s' THREAD: %p",
1315 - current, current->pid, current->comm, task_thread_info(current));
1316 + printk("TASK = %p[%d,#%u] '%s' THREAD: %p",
1317 + current, current->pid, current->xid,
1318 + current->comm, task_thread_info(current));
1321 printk(" CPU: %d", smp_processor_id());
1322 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/sys_ppc32.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/sys_ppc32.c
1323 --- linux-2.6.19.1/arch/powerpc/kernel/sys_ppc32.c 2006-11-30 21:18:31 +0100
1324 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/sys_ppc32.c 2006-11-08 04:57:44 +0100
1325 @@ -275,7 +275,7 @@ asmlinkage long compat_sys_gettimeofday(
1329 - do_gettimeofday(&ktv);
1330 + vx_gettimeofday(&ktv);
1331 if (put_tv32(tv, &ktv))
1334 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/traps.c
1335 --- linux-2.6.19.1/arch/powerpc/kernel/traps.c 2006-11-30 21:18:31 +0100
1336 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/traps.c 2006-11-08 21:52:08 +0100
1337 @@ -888,8 +888,9 @@ void nonrecoverable_exception(struct pt_
1339 void trace_syscall(struct pt_regs *regs)
1341 - printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
1342 - current, current->pid, regs->nip, regs->link, regs->gpr[0],
1343 + printk("Task: %p(%d[#%u]), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
1344 + current, current->pid, current->xid,
1345 + regs->nip, regs->link, regs->gpr[0],
1346 regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
1349 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/vdso.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/vdso.c
1350 --- linux-2.6.19.1/arch/powerpc/kernel/vdso.c 2006-11-30 21:18:31 +0100
1351 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/vdso.c 2006-11-08 04:57:47 +0100
1353 #include <linux/elf.h>
1354 #include <linux/security.h>
1355 #include <linux/bootmem.h>
1356 +#include <linux/vs_memory.h>
1358 #include <asm/pgtable.h>
1359 #include <asm/system.h>
1360 @@ -295,7 +296,7 @@ int arch_setup_additional_pages(struct l
1362 /* Put vDSO base into mm struct and account for memory usage */
1363 current->mm->context.vdso_base = vdso_base;
1364 - mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
1365 + vx_vmpages_add(mm, (vma->vm_end - vma->vm_start) >> PAGE_SHIFT);
1366 up_write(&mm->mmap_sem);
1369 diff -NurpP --minimal linux-2.6.19.1/arch/ppc/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/ppc/Kconfig
1370 --- linux-2.6.19.1/arch/ppc/Kconfig 2006-11-30 21:18:32 +0100
1371 +++ linux-2.6.19.1-vs2.3.0.6/arch/ppc/Kconfig 2006-11-08 04:57:40 +0100
1372 @@ -1421,6 +1421,8 @@ source "arch/powerpc/oprofile/Kconfig"
1374 source "arch/ppc/Kconfig.debug"
1376 +source "kernel/vserver/Kconfig"
1378 source "security/Kconfig"
1380 source "crypto/Kconfig"
1381 diff -NurpP --minimal linux-2.6.19.1/arch/ppc/kernel/asm-offsets.c linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/asm-offsets.c
1382 --- linux-2.6.19.1/arch/ppc/kernel/asm-offsets.c 2006-09-20 16:58:01 +0200
1383 +++ linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/asm-offsets.c 2006-11-08 04:57:50 +0100
1384 @@ -121,6 +121,7 @@ main(void)
1385 DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
1386 DEFINE(CLONE_VM, CLONE_VM);
1387 DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
1388 + DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
1389 DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
1391 /* About the CPU features table */
1392 diff -NurpP --minimal linux-2.6.19.1/arch/ppc/kernel/misc.S linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/misc.S
1393 --- linux-2.6.19.1/arch/ppc/kernel/misc.S 2006-11-30 21:18:32 +0100
1394 +++ linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/misc.S 2006-11-08 04:57:50 +0100
1395 @@ -848,7 +848,7 @@ _GLOBAL(kernel_thread)
1396 mr r30,r3 /* function */
1397 mr r31,r4 /* argument */
1398 ori r3,r5,CLONE_VM /* flags */
1399 - oris r3,r3,CLONE_UNTRACED>>16
1400 + oris r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
1401 li r4,0 /* new sp (unused) */
1404 diff -NurpP --minimal linux-2.6.19.1/arch/ppc/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/traps.c
1405 --- linux-2.6.19.1/arch/ppc/kernel/traps.c 2006-11-30 21:18:32 +0100
1406 +++ linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/traps.c 2006-11-08 21:52:08 +0100
1407 @@ -748,8 +748,9 @@ void nonrecoverable_exception(struct pt_
1409 void trace_syscall(struct pt_regs *regs)
1411 - printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
1412 - current, current->pid, regs->nip, regs->link, regs->gpr[0],
1413 + printk("Task: %p(%d[#%u]), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
1414 + current, current->pid, current->xid,
1415 + regs->nip, regs->link, regs->gpr[0],
1416 regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
1419 diff -NurpP --minimal linux-2.6.19.1/arch/s390/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/s390/Kconfig
1420 --- linux-2.6.19.1/arch/s390/Kconfig 2006-11-30 21:18:32 +0100
1421 +++ linux-2.6.19.1-vs2.3.0.6/arch/s390/Kconfig 2006-11-08 21:52:08 +0100
1422 @@ -519,6 +519,8 @@ endmenu
1424 source "arch/s390/Kconfig.debug"
1426 +source "kernel/vserver/Kconfig"
1428 source "security/Kconfig"
1430 source "crypto/Kconfig"
1431 diff -NurpP --minimal linux-2.6.19.1/arch/s390/kernel/compat_linux.c linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/compat_linux.c
1432 --- linux-2.6.19.1/arch/s390/kernel/compat_linux.c 2006-11-30 21:18:32 +0100
1433 +++ linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/compat_linux.c 2006-11-08 04:57:44 +0100
1434 @@ -600,7 +600,7 @@ asmlinkage long sys32_gettimeofday(struc
1438 - do_gettimeofday(&ktv);
1439 + vx_gettimeofday(&ktv);
1440 if (put_tv32(tv, &ktv))
1443 diff -NurpP --minimal linux-2.6.19.1/arch/s390/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/process.c
1444 --- linux-2.6.19.1/arch/s390/kernel/process.c 2006-11-30 21:18:32 +0100
1445 +++ linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/process.c 2006-11-08 04:57:50 +0100
1446 @@ -165,9 +165,9 @@ void show_regs(struct pt_regs *regs)
1447 struct task_struct *tsk = current;
1449 printk("CPU: %d %s\n", task_thread_info(tsk)->cpu, print_tainted());
1450 - printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
1451 - current->comm, current->pid, (void *) tsk,
1452 - (void *) tsk->thread.ksp);
1453 + printk("Process %s (pid: %d[#%u], task: %p, ksp: %p)\n",
1454 + current->comm, current->pid, current->xid,
1455 + (void *) tsk, (void *) tsk->thread.ksp);
1457 show_registers(regs);
1458 /* Show stack backtrace if pt_regs is from kernel mode */
1459 @@ -198,7 +198,7 @@ int kernel_thread(int (*fn)(void *), voi
1460 regs.orig_gpr2 = -1;
1462 /* Ok, create the new process.. */
1463 - return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
1464 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
1465 0, ®s, 0, NULL, NULL);
1468 diff -NurpP --minimal linux-2.6.19.1/arch/s390/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/ptrace.c
1469 --- linux-2.6.19.1/arch/s390/kernel/ptrace.c 2006-06-18 04:52:33 +0200
1470 +++ linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/ptrace.c 2006-11-30 18:53:18 +0100
1472 #include <linux/security.h>
1473 #include <linux/audit.h>
1474 #include <linux/signal.h>
1475 +#include <linux/vs_base.h>
1477 #include <asm/segment.h>
1478 #include <asm/page.h>
1479 @@ -723,7 +724,13 @@ sys_ptrace(long request, long pid, long
1483 + if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT)) {
1488 ret = do_ptrace(child, request, addr, data);
1490 put_task_struct(child);
1493 diff -NurpP --minimal linux-2.6.19.1/arch/s390/kernel/syscalls.S linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/syscalls.S
1494 --- linux-2.6.19.1/arch/s390/kernel/syscalls.S 2006-11-30 21:18:32 +0100
1495 +++ linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/syscalls.S 2006-11-08 04:57:41 +0100
1496 @@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,sys_clock_sett
1497 SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper) /* 260 */
1498 SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper)
1499 SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper)
1500 -NI_SYSCALL /* reserved for vserver */
1501 +SYSCALL(sys_vserver,sys_vserver,sys32_vserver)
1502 SYSCALL(s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper)
1503 SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper)
1504 SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper)
1505 diff -NurpP --minimal linux-2.6.19.1/arch/sh/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/sh/Kconfig
1506 --- linux-2.6.19.1/arch/sh/Kconfig 2006-11-30 21:18:32 +0100
1507 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh/Kconfig 2006-11-08 04:57:40 +0100
1508 @@ -627,6 +627,8 @@ source "arch/sh/oprofile/Kconfig"
1510 source "arch/sh/Kconfig.debug"
1512 +source "kernel/vserver/Kconfig"
1514 source "security/Kconfig"
1516 source "crypto/Kconfig"
1517 diff -NurpP --minimal linux-2.6.19.1/arch/sh/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/irq.c
1518 --- linux-2.6.19.1/arch/sh/kernel/irq.c 2006-11-30 21:18:34 +0100
1519 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/irq.c 2006-11-30 18:27:47 +0100
1521 #include <linux/kernel_stat.h>
1522 #include <linux/seq_file.h>
1523 #include <linux/io.h>
1524 +#include <linux/vs_context.h>
1525 #include <asm/irq.h>
1526 #include <asm/processor.h>
1527 #include <asm/uaccess.h>
1528 diff -NurpP --minimal linux-2.6.19.1/arch/sh/kernel/kgdb_stub.c linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/kgdb_stub.c
1529 --- linux-2.6.19.1/arch/sh/kernel/kgdb_stub.c 2006-11-30 21:18:34 +0100
1530 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/kgdb_stub.c 2006-11-08 04:57:52 +0100
1531 @@ -389,7 +389,7 @@ static struct task_struct *get_thread(in
1532 if (pid == PID_MAX) pid = 0;
1534 /* First check via PID */
1535 - thread = find_task_by_pid(pid);
1536 + thread = find_task_by_real_pid(pid);
1540 diff -NurpP --minimal linux-2.6.19.1/arch/sh/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/process.c
1541 --- linux-2.6.19.1/arch/sh/kernel/process.c 2006-11-30 21:18:34 +0100
1542 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/process.c 2006-11-08 04:57:50 +0100
1543 @@ -104,7 +104,8 @@ void machine_power_off(void)
1544 void show_regs(struct pt_regs * regs)
1547 - printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
1548 + printk("Pid : %d:#%u, Comm: %20s\n",
1549 + current->pid, current->xid, current->comm);
1550 print_symbol("PC is at %s\n", instruction_pointer(regs));
1551 printk("PC : %08lx SP : %08lx SR : %08lx ",
1552 regs->pc, regs->regs[15], regs->sr);
1553 @@ -164,7 +165,8 @@ int kernel_thread(int (*fn)(void *), voi
1554 regs.sr = (1 << 30);
1556 /* Ok, create the new process.. */
1557 - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
1558 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
1559 + 0, ®s, 0, NULL, NULL);
1563 diff -NurpP --minimal linux-2.6.19.1/arch/sh/kernel/vsyscall/vsyscall.c linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/vsyscall/vsyscall.c
1564 --- linux-2.6.19.1/arch/sh/kernel/vsyscall/vsyscall.c 2006-11-30 21:18:34 +0100
1565 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/vsyscall/vsyscall.c 2006-12-02 01:37:05 +0100
1567 #include <linux/gfp.h>
1568 #include <linux/module.h>
1569 #include <linux/elf.h>
1570 +#include <linux/vs_memory.h>
1573 * Should the kernel map a VDSO page into processes and pass its
1574 @@ -120,7 +121,7 @@ int arch_setup_additional_pages(struct l
1576 current->mm->context.vdso = (void *)addr;
1579 + vx_vmpages_inc(mm);
1581 up_write(&mm->mmap_sem);
1583 diff -NurpP --minimal linux-2.6.19.1/arch/sh64/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/sh64/kernel/process.c
1584 --- linux-2.6.19.1/arch/sh64/kernel/process.c 2006-11-30 21:18:35 +0100
1585 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh64/kernel/process.c 2006-11-08 04:57:50 +0100
1586 @@ -400,8 +400,8 @@ int kernel_thread(int (*fn)(void *), voi
1587 regs.pc = (unsigned long)kernel_thread_helper;
1588 regs.sr = (1 << 30);
1590 - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
1591 - ®s, 0, NULL, NULL);
1592 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
1593 + 0, ®s, 0, NULL, NULL);
1597 diff -NurpP --minimal linux-2.6.19.1/arch/sh64/mm/fault.c linux-2.6.19.1-vs2.3.0.6/arch/sh64/mm/fault.c
1598 --- linux-2.6.19.1/arch/sh64/mm/fault.c 2006-11-30 21:18:35 +0100
1599 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh64/mm/fault.c 2006-11-08 04:57:42 +0100
1600 @@ -82,7 +82,7 @@ static inline void print_vma(struct vm_a
1602 static inline void print_task(struct task_struct *tsk)
1604 - printk("Task pid %d\n", tsk->pid);
1605 + printk("Task pid %d:#%u\n", tsk->pid, tsk->xid);
1608 static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address)
1609 diff -NurpP --minimal linux-2.6.19.1/arch/sparc/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/sparc/Kconfig
1610 --- linux-2.6.19.1/arch/sparc/Kconfig 2006-11-30 21:18:35 +0100
1611 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc/Kconfig 2006-11-08 04:57:40 +0100
1612 @@ -298,6 +298,8 @@ endmenu
1614 source "arch/sparc/Kconfig.debug"
1616 +source "kernel/vserver/Kconfig"
1618 source "security/Kconfig"
1620 source "crypto/Kconfig"
1621 diff -NurpP --minimal linux-2.6.19.1/arch/sparc/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/process.c
1622 --- linux-2.6.19.1/arch/sparc/kernel/process.c 2006-09-20 16:58:01 +0200
1623 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/process.c 2006-11-08 04:57:50 +0100
1624 @@ -705,7 +705,8 @@ pid_t kernel_thread(int (*fn)(void *), v
1625 /* Notreached by child. */
1626 "1: mov %%o0, %0\n\t" :
1628 - "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED),
1629 + "i" (__NR_clone), "r" (flags |
1630 + CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD),
1631 "i" (__NR_exit), "r" (fn), "r" (arg) :
1632 "g1", "g2", "g3", "o0", "o1", "memory", "cc");
1634 diff -NurpP --minimal linux-2.6.19.1/arch/sparc/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/ptrace.c
1635 --- linux-2.6.19.1/arch/sparc/kernel/ptrace.c 2006-04-09 13:49:44 +0200
1636 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/ptrace.c 2006-11-30 18:53:18 +0100
1638 #include <linux/smp_lock.h>
1639 #include <linux/security.h>
1640 #include <linux/signal.h>
1641 +#include <linux/vs_base.h>
1643 #include <asm/pgtable.h>
1644 #include <asm/system.h>
1645 @@ -299,6 +300,10 @@ asmlinkage void do_ptrace(struct pt_regs
1646 pt_error_return(regs, -ret);
1649 + if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT)) {
1650 + pt_error_return(regs, ESRCH);
1654 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
1655 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
1656 diff -NurpP --minimal linux-2.6.19.1/arch/sparc/kernel/systbls.S linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/systbls.S
1657 --- linux-2.6.19.1/arch/sparc/kernel/systbls.S 2006-11-30 21:18:35 +0100
1658 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/systbls.S 2006-11-08 21:52:08 +0100
1659 @@ -71,7 +71,7 @@ sys_call_table:
1660 /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
1661 /*255*/ .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
1662 /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
1663 -/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
1664 +/*265*/ .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
1665 /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
1666 /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
1667 /*280*/ .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
1668 diff -NurpP --minimal linux-2.6.19.1/arch/sparc/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/traps.c
1669 --- linux-2.6.19.1/arch/sparc/kernel/traps.c 2006-09-20 16:58:06 +0200
1670 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/traps.c 2006-11-08 04:57:42 +0100
1671 @@ -99,7 +99,8 @@ void die_if_kernel(char *str, struct pt_
1675 - printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
1676 + printk("%s(%d[#%u]): %s [#%d]\n", current->comm,
1677 + current->pid, current->xid, str, ++die_counter);
1680 __SAVE; __SAVE; __SAVE; __SAVE;
1681 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/sparc64/Kconfig
1682 --- linux-2.6.19.1/arch/sparc64/Kconfig 2006-11-30 21:18:35 +0100
1683 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/Kconfig 2006-11-08 04:57:40 +0100
1684 @@ -431,6 +431,8 @@ endmenu
1686 source "arch/sparc64/Kconfig.debug"
1688 +source "kernel/vserver/Kconfig"
1690 source "security/Kconfig"
1692 source "crypto/Kconfig"
1693 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/binfmt_aout32.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/binfmt_aout32.c
1694 --- linux-2.6.19.1/arch/sparc64/kernel/binfmt_aout32.c 2006-06-18 04:52:34 +0200
1695 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/binfmt_aout32.c 2006-11-08 04:57:40 +0100
1697 #include <linux/binfmts.h>
1698 #include <linux/personality.h>
1699 #include <linux/init.h>
1700 +#include <linux/vs_memory.h>
1702 #include <asm/system.h>
1703 #include <asm/uaccess.h>
1704 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/process.c
1705 --- linux-2.6.19.1/arch/sparc64/kernel/process.c 2006-09-20 16:58:06 +0200
1706 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/process.c 2006-11-08 04:57:50 +0100
1707 @@ -696,7 +696,8 @@ pid_t kernel_thread(int (*fn)(void *), v
1708 /* Notreached by child. */
1711 - "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED),
1712 + "i" (__NR_clone), "r" (flags |
1713 + CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD),
1714 "i" (__NR_exit), "r" (fn), "r" (arg) :
1715 "g1", "g2", "g3", "o0", "o1", "memory", "cc");
1717 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/ptrace.c
1718 --- linux-2.6.19.1/arch/sparc64/kernel/ptrace.c 2006-06-18 04:52:35 +0200
1719 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/ptrace.c 2006-11-30 18:53:18 +0100
1721 #include <linux/seccomp.h>
1722 #include <linux/audit.h>
1723 #include <linux/signal.h>
1724 +#include <linux/vs_base.h>
1726 #include <asm/asi.h>
1727 #include <asm/pgtable.h>
1728 @@ -212,6 +213,10 @@ asmlinkage void do_ptrace(struct pt_regs
1729 pt_error_return(regs, -ret);
1732 + if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT)) {
1733 + pt_error_return(regs, ESRCH);
1737 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
1738 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
1739 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/sys_sparc32.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/sys_sparc32.c
1740 --- linux-2.6.19.1/arch/sparc64/kernel/sys_sparc32.c 2006-11-30 21:18:35 +0100
1741 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/sys_sparc32.c 2006-11-08 04:57:44 +0100
1742 @@ -793,7 +793,7 @@ asmlinkage long sys32_gettimeofday(struc
1746 - do_gettimeofday(&ktv);
1747 + vx_gettimeofday(&ktv);
1748 if (put_tv32(tv, &ktv))
1751 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/systbls.S linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/systbls.S
1752 --- linux-2.6.19.1/arch/sparc64/kernel/systbls.S 2006-11-30 21:18:35 +0100
1753 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/systbls.S 2006-11-08 21:52:08 +0100
1754 @@ -72,7 +72,7 @@ sys_call_table32:
1755 /*250*/ .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
1756 .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
1757 /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
1758 - .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
1759 + .word sys_timer_delete, compat_sys_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy
1760 /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
1761 .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
1762 /*280*/ .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
1763 @@ -142,7 +142,7 @@ sys_call_table:
1764 /*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
1765 .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
1766 /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
1767 - .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
1768 + .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
1769 /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
1770 .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
1771 /*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
1772 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/traps.c
1773 --- linux-2.6.19.1/arch/sparc64/kernel/traps.c 2006-11-30 21:18:35 +0100
1774 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/traps.c 2006-11-08 21:52:08 +0100
1775 @@ -2223,7 +2223,8 @@ void die_if_kernel(char *str, struct pt_
1779 - printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
1780 + printk("%s(%d[#%u]): %s [#%d]\n", current->comm,
1781 + current->pid, current->xid, str, ++die_counter);
1782 notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
1783 __asm__ __volatile__("flushw");
1785 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/solaris/fs.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/solaris/fs.c
1786 --- linux-2.6.19.1/arch/sparc64/solaris/fs.c 2006-11-30 21:18:35 +0100
1787 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/solaris/fs.c 2006-11-08 04:57:52 +0100
1788 @@ -368,7 +368,7 @@ static int report_statvfs(struct vfsmoun
1792 - if (IS_RDONLY(inode)) i = 1;
1793 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
1794 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
1795 if (!sysv_valid_dev(inode->i_sb->s_dev))
1797 @@ -404,7 +404,7 @@ static int report_statvfs64(struct vfsmo
1801 - if (IS_RDONLY(inode)) i = 1;
1802 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
1803 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
1804 if (!sysv_valid_dev(inode->i_sb->s_dev))
1806 diff -NurpP --minimal linux-2.6.19.1/arch/um/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/um/Kconfig
1807 --- linux-2.6.19.1/arch/um/Kconfig 2006-11-30 21:18:35 +0100
1808 +++ linux-2.6.19.1-vs2.3.0.6/arch/um/Kconfig 2006-11-08 04:57:40 +0100
1809 @@ -306,6 +306,8 @@ source "drivers/connector/Kconfig"
1813 +source "kernel/vserver/Kconfig"
1815 source "security/Kconfig"
1817 source "crypto/Kconfig"
1818 diff -NurpP --minimal linux-2.6.19.1/arch/um/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/um/kernel/irq.c
1819 --- linux-2.6.19.1/arch/um/kernel/irq.c 2006-11-30 21:18:36 +0100
1820 +++ linux-2.6.19.1-vs2.3.0.6/arch/um/kernel/irq.c 2006-11-30 18:28:41 +0100
1821 @@ -357,6 +357,7 @@ void forward_interrupts(int pid)
1822 unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
1824 struct pt_regs *old_regs = set_irq_regs((struct pt_regs *)regs);
1829 diff -NurpP --minimal linux-2.6.19.1/arch/um/kernel/syscall.c linux-2.6.19.1-vs2.3.0.6/arch/um/kernel/syscall.c
1830 --- linux-2.6.19.1/arch/um/kernel/syscall.c 2006-11-30 21:18:36 +0100
1831 +++ linux-2.6.19.1-vs2.3.0.6/arch/um/kernel/syscall.c 2006-12-02 01:37:05 +0100
1833 #include "linux/unistd.h"
1834 #include "linux/slab.h"
1835 #include "linux/utime.h"
1837 #include "asm/mman.h"
1838 #include "asm/uaccess.h"
1839 #include "kern_util.h"
1840 @@ -118,6 +119,7 @@ long sys_uname(struct old_utsname __user
1841 long sys_olduname(struct oldold_utsname __user * name)
1844 + struct new_utsname *ptr;
1848 diff -NurpP --minimal linux-2.6.19.1/arch/v850/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/v850/Kconfig
1849 --- linux-2.6.19.1/arch/v850/Kconfig 2006-06-18 04:52:42 +0200
1850 +++ linux-2.6.19.1-vs2.3.0.6/arch/v850/Kconfig 2006-11-08 04:57:40 +0100
1851 @@ -326,6 +326,8 @@ source "drivers/usb/Kconfig"
1853 source "arch/v850/Kconfig.debug"
1855 +source "kernel/vserver/Kconfig"
1857 source "security/Kconfig"
1859 source "crypto/Kconfig"
1860 diff -NurpP --minimal linux-2.6.19.1/arch/v850/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/v850/kernel/process.c
1861 --- linux-2.6.19.1/arch/v850/kernel/process.c 2006-09-20 16:58:06 +0200
1862 +++ linux-2.6.19.1-vs2.3.0.6/arch/v850/kernel/process.c 2006-11-08 04:57:50 +0100
1863 @@ -83,7 +83,7 @@ int kernel_thread (int (*fn)(void *), vo
1864 /* Clone this thread. Note that we don't pass the clone syscall's
1865 second argument -- it's ignored for calls from kernel mode (the
1866 child's SP is always set to the top of the kernel stack). */
1867 - arg0 = flags | CLONE_VM;
1868 + arg0 = flags | CLONE_VM | CLONE_KTHREAD;
1869 syscall = __NR_clone;
1870 asm volatile ("trap " SYSCALL_SHORT_TRAP
1871 : "=r" (ret), "=r" (syscall)
1872 diff -NurpP --minimal linux-2.6.19.1/arch/v850/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/v850/kernel/ptrace.c
1873 --- linux-2.6.19.1/arch/v850/kernel/ptrace.c 2006-04-09 13:49:44 +0200
1874 +++ linux-2.6.19.1-vs2.3.0.6/arch/v850/kernel/ptrace.c 2006-11-30 18:53:18 +0100
1876 #include <linux/smp_lock.h>
1877 #include <linux/ptrace.h>
1878 #include <linux/signal.h>
1879 +#include <linux/vs_base.h>
1881 #include <asm/errno.h>
1882 #include <asm/ptrace.h>
1883 @@ -117,6 +118,9 @@ long arch_ptrace(struct task_struct *chi
1887 + if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT))
1891 unsigned long val, copied;
1893 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/x86_64/Kconfig
1894 --- linux-2.6.19.1/arch/x86_64/Kconfig 2006-11-30 21:18:36 +0100
1895 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/Kconfig 2006-11-08 04:57:40 +0100
1896 @@ -701,6 +701,8 @@ endmenu
1898 source "arch/x86_64/Kconfig.debug"
1900 +source "kernel/vserver/Kconfig"
1902 source "security/Kconfig"
1904 source "crypto/Kconfig"
1905 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/ia32/ia32_aout.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32_aout.c
1906 --- linux-2.6.19.1/arch/x86_64/ia32/ia32_aout.c 2006-11-30 21:18:37 +0100
1907 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32_aout.c 2006-11-08 04:57:40 +0100
1909 #include <linux/binfmts.h>
1910 #include <linux/personality.h>
1911 #include <linux/init.h>
1912 +#include <linux/vs_memory.h>
1914 #include <asm/system.h>
1915 #include <asm/uaccess.h>
1916 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32_binfmt.c
1917 --- linux-2.6.19.1/arch/x86_64/ia32/ia32_binfmt.c 2006-11-30 21:18:37 +0100
1918 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32_binfmt.c 2006-11-08 04:57:47 +0100
1919 @@ -375,7 +375,8 @@ int ia32_setup_arg_pages(struct linux_bi
1920 kmem_cache_free(vm_area_cachep, mpnt);
1923 - mm->stack_vm = mm->total_vm = vma_pages(mpnt);
1924 + vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
1925 + mm->stack_vm = mm->total_vm;
1928 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
1929 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/ia32/ia32entry.S linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32entry.S
1930 --- linux-2.6.19.1/arch/x86_64/ia32/ia32entry.S 2006-11-30 21:18:37 +0100
1931 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32entry.S 2006-11-08 04:57:41 +0100
1932 @@ -672,7 +672,7 @@ ia32_sys_call_table:
1933 .quad sys_tgkill /* 270 */
1934 .quad compat_sys_utimes
1935 .quad sys32_fadvise64_64
1936 - .quad quiet_ni_syscall /* sys_vserver */
1937 + .quad sys32_vserver
1939 .quad compat_sys_get_mempolicy /* 275 */
1940 .quad sys_set_mempolicy
1941 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/ia32/sys_ia32.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/sys_ia32.c
1942 --- linux-2.6.19.1/arch/x86_64/ia32/sys_ia32.c 2006-11-30 21:18:37 +0100
1943 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/sys_ia32.c 2006-12-02 01:37:05 +0100
1944 @@ -454,7 +454,7 @@ sys32_gettimeofday(struct compat_timeval
1948 - do_gettimeofday(&ktv);
1949 + vx_gettimeofday(&ktv);
1950 if (put_tv32(tv, &ktv))
1953 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/ia32/syscall32.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/syscall32.c
1954 --- linux-2.6.19.1/arch/x86_64/ia32/syscall32.c 2005-10-28 20:49:18 +0200
1955 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/syscall32.c 2006-11-08 04:57:47 +0100
1957 #include <linux/init.h>
1958 #include <linux/stringify.h>
1959 #include <linux/security.h>
1960 +#include <linux/vs_memory.h>
1961 #include <asm/proto.h>
1962 #include <asm/tlbflush.h>
1963 #include <asm/ia32_unistd.h>
1964 @@ -70,7 +71,7 @@ int syscall32_setup_pages(struct linux_b
1965 kmem_cache_free(vm_area_cachep, vma);
1968 - mm->total_vm += npages;
1969 + vx_vmpages_add(mm, npages);
1970 up_write(&mm->mmap_sem);
1973 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/irq.c
1974 --- linux-2.6.19.1/arch/x86_64/kernel/irq.c 2006-11-30 21:18:37 +0100
1975 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/irq.c 2006-11-30 18:28:58 +0100
1976 @@ -123,7 +123,6 @@ asmlinkage unsigned int do_IRQ(struct pt
1978 printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
1979 __func__, smp_processor_id(), vector);
1983 set_irq_regs(old_regs);
1984 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/process.c
1985 --- linux-2.6.19.1/arch/x86_64/kernel/process.c 2006-11-30 21:18:37 +0100
1986 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/process.c 2006-11-30 20:55:45 +0100
1989 asmlinkage extern void ret_from_fork(void);
1991 -unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
1992 +unsigned long kernel_thread_flags =
1993 + CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
1995 unsigned long boot_option_idle_override = 0;
1996 EXPORT_SYMBOL(boot_option_idle_override);
1997 @@ -301,8 +302,8 @@ void __show_regs(struct pt_regs * regs)
2001 - printk("Pid: %d, comm: %.20s %s %s %.*s\n",
2002 - current->pid, current->comm, print_tainted(),
2003 + printk("Pid: %d:#%u, comm: %.20s %s %s %.*s\n",
2004 + current->pid, current->xid, current->comm, print_tainted(),
2005 init_utsname()->release,
2006 (int)strcspn(init_utsname()->version, " "),
2007 init_utsname()->version);
2008 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/traps.c
2009 --- linux-2.6.19.1/arch/x86_64/kernel/traps.c 2006-11-30 21:18:37 +0100
2010 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/traps.c 2006-11-30 20:55:45 +0100
2011 @@ -487,8 +487,9 @@ void show_registers(struct pt_regs *regs
2013 printk("CPU %d ", cpu);
2015 - printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
2016 - cur->comm, cur->pid, task_thread_info(cur), cur);
2017 + printk("Process %s (pid: %d[#%u], threadinfo %p, task %p)\n",
2018 + cur->comm, cur->pid, cur->xid,
2019 + task_thread_info(cur), cur);
2022 * When in-kernel, we also print out the stack and code at the
2023 @@ -657,8 +658,8 @@ static void __kprobes do_trap(int trapnr
2024 if (user_mode(regs)) {
2025 if (exception_trace && unhandled_signal(tsk, signr))
2027 - "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
2028 - tsk->comm, tsk->pid, str,
2029 + "%s[%d:#%u] trap %s rip:%lx rsp:%lx error:%lx\n",
2030 + tsk->comm, tsk->pid, tsk->xid, str,
2031 regs->rip, regs->rsp, error_code);
2034 @@ -758,8 +759,8 @@ asmlinkage void __kprobes do_general_pro
2035 if (user_mode(regs)) {
2036 if (exception_trace && unhandled_signal(tsk, SIGSEGV))
2038 - "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
2039 - tsk->comm, tsk->pid,
2040 + "%s[%d:#%u] general protection rip:%lx rsp:%lx error:%lx\n",
2041 + tsk->comm, tsk->pid, tsk->xid,
2042 regs->rip, regs->rsp, error_code);
2044 force_sig(SIGSEGV, tsk);
2045 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/mm/fault.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/mm/fault.c
2046 --- linux-2.6.19.1/arch/x86_64/mm/fault.c 2006-11-30 21:18:37 +0100
2047 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/mm/fault.c 2006-11-08 04:57:42 +0100
2048 @@ -514,10 +514,10 @@ bad_area_nosemaphore:
2050 if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
2052 - "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
2053 + "%s%s[%d:#%u]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
2054 tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
2055 - tsk->comm, tsk->pid, address, regs->rip,
2056 - regs->rsp, error_code);
2057 + tsk->comm, tsk->pid, tsk->xid, address,
2058 + regs->rip, regs->rsp, error_code);
2061 tsk->thread.cr2 = address;
2062 diff -NurpP --minimal linux-2.6.19.1/arch/xtensa/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/xtensa/kernel/irq.c
2063 --- linux-2.6.19.1/arch/xtensa/kernel/irq.c 2006-09-20 16:58:06 +0200
2064 +++ linux-2.6.19.1-vs2.3.0.6/arch/xtensa/kernel/irq.c 2006-11-30 18:29:29 +0100
2065 @@ -63,9 +63,7 @@ unsigned int do_IRQ(int irq, struct pt_
2066 sp - sizeof(struct thread_info));
2070 __do_IRQ(irq, regs);
2075 diff -NurpP --minimal linux-2.6.19.1/arch/xtensa/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/xtensa/kernel/process.c
2076 --- linux-2.6.19.1/arch/xtensa/kernel/process.c 2006-09-20 16:58:06 +0200
2077 +++ linux-2.6.19.1-vs2.3.0.6/arch/xtensa/kernel/process.c 2006-11-08 04:57:50 +0100
2078 @@ -206,7 +206,7 @@ int kernel_thread(int (*fn)(void *), voi
2080 :"i" (__NR_clone), "i" (__NR_exit),
2081 "r" (arg), "r" (fn),
2082 - "r" (flags | CLONE_VM)
2083 + "r" (flags | CLONE_VM | CLONE_KTHREAD)
2084 : "a2", "a3", "a4", "a5", "a6" );
2087 diff -NurpP --minimal linux-2.6.19.1/block/cfq-iosched.c linux-2.6.19.1-vs2.3.0.6/block/cfq-iosched.c
2088 --- linux-2.6.19.1/block/cfq-iosched.c 2006-11-30 21:18:37 +0100
2089 +++ linux-2.6.19.1-vs2.3.0.6/block/cfq-iosched.c 2006-11-08 21:52:08 +0100
2090 @@ -221,6 +221,8 @@ static int cfq_queue_empty(request_queue
2092 static inline pid_t cfq_queue_pid(struct task_struct *task, int rw)
2095 + return task->xid + (1 << 16);
2096 if (rw == READ || rw == WRITE_SYNC)
2099 diff -NurpP --minimal linux-2.6.19.1/drivers/block/Kconfig linux-2.6.19.1-vs2.3.0.6/drivers/block/Kconfig
2100 --- linux-2.6.19.1/drivers/block/Kconfig 2006-12-13 07:46:36 +0100
2101 +++ linux-2.6.19.1-vs2.3.0.6/drivers/block/Kconfig 2006-12-13 09:16:31 +0100
2102 @@ -317,6 +317,13 @@ config BLK_DEV_CRYPTOLOOP
2103 instead, which can be configured to be on-disk compatible with the
2106 +config BLK_DEV_VROOT
2107 + tristate "Virtual Root device support"
2108 + depends on QUOTACTL
2110 + Saying Y here will allow you to use quota/fs ioctls on a shared
2111 + partition within a virtual server without compromising security.
2114 tristate "Network block device support"
2116 diff -NurpP --minimal linux-2.6.19.1/drivers/block/Makefile linux-2.6.19.1-vs2.3.0.6/drivers/block/Makefile
2117 --- linux-2.6.19.1/drivers/block/Makefile 2006-06-18 04:52:46 +0200
2118 +++ linux-2.6.19.1-vs2.3.0.6/drivers/block/Makefile 2006-11-08 04:57:51 +0100
2119 @@ -29,4 +29,5 @@ obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryp
2120 obj-$(CONFIG_VIODASD) += viodasd.o
2121 obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
2122 obj-$(CONFIG_BLK_DEV_UB) += ub.o
2123 +obj-$(CONFIG_BLK_DEV_VROOT) += vroot.o
2125 diff -NurpP --minimal linux-2.6.19.1/drivers/block/loop.c linux-2.6.19.1-vs2.3.0.6/drivers/block/loop.c
2126 --- linux-2.6.19.1/drivers/block/loop.c 2006-11-30 21:18:39 +0100
2127 +++ linux-2.6.19.1-vs2.3.0.6/drivers/block/loop.c 2006-11-30 18:53:18 +0100
2129 #include <linux/highmem.h>
2130 #include <linux/gfp.h>
2131 #include <linux/kthread.h>
2132 +#include <linux/vs_context.h>
2134 #include <asm/uaccess.h>
2136 @@ -795,6 +796,7 @@ static int loop_set_fd(struct loop_devic
2137 lo->lo_blocksize = lo_blocksize;
2138 lo->lo_device = bdev;
2139 lo->lo_flags = lo_flags;
2140 + lo->lo_xid = vx_current_xid();
2141 lo->lo_backing_file = file;
2142 lo->transfer = transfer_none;
2144 @@ -935,7 +937,7 @@ loop_set_status(struct loop_device *lo,
2145 struct loop_func_table *xfer;
2147 if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
2148 - !capable(CAP_SYS_ADMIN))
2149 + !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP))
2151 if (lo->lo_state != Lo_bound)
2153 @@ -1015,7 +1017,8 @@ loop_get_status(struct loop_device *lo,
2154 memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
2155 info->lo_encrypt_type =
2156 lo->lo_encryption ? lo->lo_encryption->number : 0;
2157 - if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
2158 + if (lo->lo_encrypt_key_size &&
2159 + vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) {
2160 info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
2161 memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
2162 lo->lo_encrypt_key_size);
2163 @@ -1326,6 +1329,9 @@ static int lo_open(struct inode *inode,
2165 struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
2167 + if (!vx_check(lo->lo_xid, VS_WATCH_P|VS_IDENT))
2170 mutex_lock(&lo->lo_ctl_mutex);
2172 mutex_unlock(&lo->lo_ctl_mutex);
2173 diff -NurpP --minimal linux-2.6.19.1/drivers/block/vroot.c linux-2.6.19.1-vs2.3.0.6/drivers/block/vroot.c
2174 --- linux-2.6.19.1/drivers/block/vroot.c 1970-01-01 01:00:00 +0100
2175 +++ linux-2.6.19.1-vs2.3.0.6/drivers/block/vroot.c 2006-11-30 19:40:17 +0100
2178 + * linux/drivers/block/vroot.c
2180 + * written by Herbert Pötzl, 9/11/2002
2181 + * ported to 2.6.10 by Herbert Pötzl, 30/12/2004
2183 + * based on the loop.c code by Theodore Ts'o.
2185 + * Copyright (C) 2002-2006 by Herbert Pötzl.
2186 + * Redistribution of this file is permitted under the
2187 + * GNU General Public License.
2191 +#include <linux/module.h>
2192 +#include <linux/moduleparam.h>
2193 +#include <linux/file.h>
2194 +#include <linux/major.h>
2195 +#include <linux/blkdev.h>
2197 +#include <linux/vroot.h>
2198 +#include <linux/vs_context.h>
2201 +static int max_vroot = 8;
2203 +static struct vroot_device *vroot_dev;
2204 +static struct gendisk **disks;
2207 +static int vroot_set_dev(
2208 + struct vroot_device *vr,
2209 + struct file *vr_file,
2210 + struct block_device *bdev,
2213 + struct block_device *real_bdev;
2214 + struct file *file;
2215 + struct inode *inode;
2219 + if (vr->vr_state != Vr_unbound)
2228 + inode = file->f_dentry->d_inode;
2231 + if (S_ISBLK(inode->i_mode)) {
2232 + real_bdev = inode->i_bdev;
2233 + vr->vr_device = real_bdev;
2234 + __iget(real_bdev->bd_inode);
2238 + vxdprintk(VXD_CBIT(misc, 0),
2239 + "vroot[%d]_set_dev: dev=" VXF_DEV,
2240 + vr->vr_number, VXD_DEV(real_bdev));
2242 + vr->vr_state = Vr_bound;
2251 +static int vroot_clr_dev(
2252 + struct vroot_device *vr,
2253 + struct file *vr_file,
2254 + struct block_device *bdev)
2256 + struct block_device *real_bdev;
2258 + if (vr->vr_state != Vr_bound)
2260 + if (vr->vr_refcnt > 1) /* we needed one fd for the ioctl */
2263 + real_bdev = vr->vr_device;
2265 + vxdprintk(VXD_CBIT(misc, 0),
2266 + "vroot[%d]_clr_dev: dev=" VXF_DEV,
2267 + vr->vr_number, VXD_DEV(real_bdev));
2270 + vr->vr_state = Vr_unbound;
2271 + vr->vr_device = NULL;
2276 +static int vr_ioctl(struct inode * inode, struct file * file,
2277 + unsigned int cmd, unsigned long arg)
2279 + struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
2282 + down(&vr->vr_ctl_mutex);
2284 + case VROOT_SET_DEV:
2285 + err = vroot_set_dev(vr, file, inode->i_bdev, arg);
2287 + case VROOT_CLR_DEV:
2288 + err = vroot_clr_dev(vr, file, inode->i_bdev);
2294 + up(&vr->vr_ctl_mutex);
2298 +static int vr_open(struct inode *inode, struct file *file)
2300 + struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
2302 + down(&vr->vr_ctl_mutex);
2304 + up(&vr->vr_ctl_mutex);
2308 +static int vr_release(struct inode *inode, struct file *file)
2310 + struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
2312 + down(&vr->vr_ctl_mutex);
2314 + up(&vr->vr_ctl_mutex);
2318 +static struct block_device_operations vr_fops = {
2319 + .owner = THIS_MODULE,
2321 + .release = vr_release,
2322 + .ioctl = vr_ioctl,
2325 +struct block_device *__vroot_get_real_bdev(struct block_device *bdev)
2327 + struct inode *inode = bdev->bd_inode;
2328 + struct vroot_device *vr;
2329 + struct block_device *real_bdev;
2330 + int minor = iminor(inode);
2332 + vr = &vroot_dev[minor];
2333 + real_bdev = vr->vr_device;
2335 + vxdprintk(VXD_CBIT(misc, 0),
2336 + "vroot[%d]_get_real_bdev: dev=" VXF_DEV,
2337 + vr->vr_number, VXD_DEV(real_bdev));
2339 + if (vr->vr_state != Vr_bound)
2340 + return ERR_PTR(-ENXIO);
2342 + __iget(real_bdev->bd_inode);
2347 + * And now the modules code and kernel interface.
2350 +module_param(max_vroot, int, 0);
2352 +MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)");
2353 +MODULE_LICENSE("GPL");
2354 +MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR);
2356 +MODULE_AUTHOR ("Herbert Pötzl");
2357 +MODULE_DESCRIPTION ("Virtual Root Device Mapper");
2360 +int __init vroot_init(void)
2364 + if (max_vroot < 1 || max_vroot > 256) {
2365 + max_vroot = MAX_VROOT_DEFAULT;
2366 + printk(KERN_WARNING "vroot: invalid max_vroot "
2367 + "(must be between 1 and 256), "
2368 + "using default (%d)\n", max_vroot);
2371 + if (register_blkdev(VROOT_MAJOR, "vroot"))
2375 + vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL);
2378 + memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device));
2380 + disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL);
2384 + for (i = 0; i < max_vroot; i++) {
2385 + disks[i] = alloc_disk(1);
2390 + for (i = 0; i < max_vroot; i++) {
2391 + struct vroot_device *vr = &vroot_dev[i];
2392 + struct gendisk *disk = disks[i];
2394 + memset(vr, 0, sizeof(*vr));
2395 + init_MUTEX(&vr->vr_ctl_mutex);
2396 + vr->vr_number = i;
2397 + disk->major = VROOT_MAJOR;
2398 + disk->first_minor = i;
2399 + disk->fops = &vr_fops;
2400 + sprintf(disk->disk_name, "vroot%d", i);
2401 + disk->private_data = vr;
2404 + err = register_vroot_grb(&__vroot_get_real_bdev);
2408 + for (i = 0; i < max_vroot; i++)
2409 + add_disk(disks[i]);
2410 + printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot);
2415 + put_disk(disks[i]);
2420 + unregister_blkdev(VROOT_MAJOR, "vroot");
2421 + printk(KERN_ERR "vroot: ran out of memory\n");
2425 +void vroot_exit(void)
2429 + if (unregister_vroot_grb(&__vroot_get_real_bdev))
2430 + printk(KERN_WARNING "vroot: cannot unregister grb\n");
2432 + for (i = 0; i < max_vroot; i++) {
2433 + del_gendisk(disks[i]);
2434 + put_disk(disks[i]);
2436 + if (unregister_blkdev(VROOT_MAJOR, "vroot"))
2437 + printk(KERN_WARNING "vroot: cannot unregister blkdev\n");
2443 +module_init(vroot_init);
2444 +module_exit(vroot_exit);
2448 +static int __init max_vroot_setup(char *str)
2450 + max_vroot = simple_strtol(str, NULL, 0);
2454 +__setup("max_vroot=", max_vroot_setup);
2458 diff -NurpP --minimal linux-2.6.19.1/drivers/char/random.c linux-2.6.19.1-vs2.3.0.6/drivers/char/random.c
2459 --- linux-2.6.19.1/drivers/char/random.c 2006-11-30 21:18:40 +0100
2460 +++ linux-2.6.19.1-vs2.3.0.6/drivers/char/random.c 2006-11-08 04:57:40 +0100
2461 @@ -1178,7 +1178,7 @@ static char sysctl_bootid[16];
2462 static int proc_do_uuid(ctl_table *table, int write, struct file *filp,
2463 void __user *buffer, size_t *lenp, loff_t *ppos)
2465 - ctl_table fake_table;
2466 + ctl_table fake_table = {0};
2467 unsigned char buf[64], tmp_uuid[16], *uuid;
2470 diff -NurpP --minimal linux-2.6.19.1/drivers/char/sysrq.c linux-2.6.19.1-vs2.3.0.6/drivers/char/sysrq.c
2471 --- linux-2.6.19.1/drivers/char/sysrq.c 2006-11-30 21:18:41 +0100
2472 +++ linux-2.6.19.1-vs2.3.0.6/drivers/char/sysrq.c 2006-12-02 01:37:05 +0100
2474 #include <linux/workqueue.h>
2475 #include <linux/kexec.h>
2476 #include <linux/irq.h>
2477 +#include <linux/vserver/debug.h>
2479 #include <asm/ptrace.h>
2480 #include <asm/irq_regs.h>
2481 @@ -260,6 +261,21 @@ static struct sysrq_key_op sysrq_unrt_op
2482 .enable_mask = SYSRQ_ENABLE_RTNICE,
2486 +#ifdef CONFIG_VSERVER_DEBUG
2487 +static void sysrq_handle_vxinfo(int key, struct tty_struct *tty)
2489 + dump_vx_info_inactive((key == 'x')?0:1);
2492 +static struct sysrq_key_op sysrq_showvxinfo_op = {
2493 + .handler = sysrq_handle_vxinfo,
2494 + .help_msg = "conteXt",
2495 + .action_msg = "Show Context Info",
2496 + .enable_mask = SYSRQ_ENABLE_DUMP,
2500 /* Key Operations table and lock */
2501 static DEFINE_SPINLOCK(sysrq_key_table_lock);
2503 @@ -304,7 +320,11 @@ static struct sysrq_key_op *sysrq_key_ta
2504 /* May be assigned at init time by SMP VOYAGER */
2507 +#ifdef CONFIG_VSERVER_DEBUG
2508 + &sysrq_showvxinfo_op, /* x */
2515 @@ -318,6 +338,8 @@ static int sysrq_key_table_key2index(int
2517 else if ((key >= 'a') && (key <= 'z'))
2518 retval = key + 10 - 'a';
2519 + else if ((key >= 'A') && (key <= 'Z'))
2520 + retval = key + 10 - 'A';
2524 diff -NurpP --minimal linux-2.6.19.1/drivers/char/tty_io.c linux-2.6.19.1-vs2.3.0.6/drivers/char/tty_io.c
2525 --- linux-2.6.19.1/drivers/char/tty_io.c 2006-11-30 21:18:41 +0100
2526 +++ linux-2.6.19.1-vs2.3.0.6/drivers/char/tty_io.c 2006-11-08 04:57:52 +0100
2528 #include <linux/selection.h>
2530 #include <linux/kmod.h>
2531 +#include <linux/vs_pid.h>
2533 #undef TTY_DEBUG_HANGUP
2535 @@ -2941,13 +2942,16 @@ static int tiocsctty(struct tty_struct *
2537 static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
2541 * (tty == real_tty) is a cheap way of
2542 * testing if the tty is NOT a master pty.
2544 if (tty == real_tty && current->signal->tty != real_tty)
2546 - return put_user(real_tty->pgrp, p);
2548 + pgrp = vx_map_pid(real_tty->pgrp);
2549 + return put_user(pgrp, p);
2553 @@ -2977,6 +2981,8 @@ static int tiocspgrp(struct tty_struct *
2555 if (get_user(pgrp, p))
2558 + pgrp = vx_rmap_pid(pgrp);
2561 if (session_of_pgrp(pgrp) != current->signal->session)
2562 diff -NurpP --minimal linux-2.6.19.1/drivers/infiniband/core/uverbs_mem.c linux-2.6.19.1-vs2.3.0.6/drivers/infiniband/core/uverbs_mem.c
2563 --- linux-2.6.19.1/drivers/infiniband/core/uverbs_mem.c 2006-06-18 04:53:04 +0200
2564 +++ linux-2.6.19.1-vs2.3.0.6/drivers/infiniband/core/uverbs_mem.c 2006-11-08 04:57:47 +0100
2567 #include <linux/mm.h>
2568 #include <linux/dma-mapping.h>
2569 +#include <linux/vs_memory.h>
2573 @@ -161,7 +162,7 @@ out:
2575 __ib_umem_release(dev, mem, 0);
2577 - current->mm->locked_vm = locked;
2578 + vx_vmlocked_sub(current->mm, current->mm->locked_vm - locked);
2580 up_write(¤t->mm->mmap_sem);
2581 free_page((unsigned long) page_list);
2582 @@ -174,8 +175,8 @@ void ib_umem_release(struct ib_device *d
2583 __ib_umem_release(dev, umem, 1);
2585 down_write(¤t->mm->mmap_sem);
2586 - current->mm->locked_vm -=
2587 - PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
2588 + vx_vmlocked_sub(current->mm,
2589 + PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT);
2590 up_write(¤t->mm->mmap_sem);
2593 @@ -184,7 +185,7 @@ static void ib_umem_account(void *work_p
2594 struct ib_umem_account_work *work = work_ptr;
2596 down_write(&work->mm->mmap_sem);
2597 - work->mm->locked_vm -= work->diff;
2598 + vx_vmlocked_sub(work->mm, work->diff);
2599 up_write(&work->mm->mmap_sem);
2602 diff -NurpP --minimal linux-2.6.19.1/drivers/infiniband/hw/ipath/ipath_user_pages.c linux-2.6.19.1-vs2.3.0.6/drivers/infiniband/hw/ipath/ipath_user_pages.c
2603 --- linux-2.6.19.1/drivers/infiniband/hw/ipath/ipath_user_pages.c 2006-11-30 21:18:44 +0100
2604 +++ linux-2.6.19.1-vs2.3.0.6/drivers/infiniband/hw/ipath/ipath_user_pages.c 2006-11-08 04:57:47 +0100
2607 #include <linux/mm.h>
2608 #include <linux/device.h>
2609 +#include <linux/vs_memory.h>
2611 #include "ipath_kernel.h"
2613 @@ -61,7 +62,8 @@ static int __get_user_pages(unsigned lon
2614 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
2617 - if (num_pages > lock_limit) {
2618 + if (num_pages > lock_limit ||
2619 + !vx_vmlocked_avail(current->mm, num_pages)) {
2623 @@ -78,7 +80,7 @@ static int __get_user_pages(unsigned lon
2627 - current->mm->locked_vm += num_pages;
2628 + vx_vmlocked_add(current->mm, num_pages);
2632 @@ -203,7 +205,7 @@ void ipath_release_user_pages(struct pag
2634 __ipath_release_user_pages(p, num_pages, 1);
2636 - current->mm->locked_vm -= num_pages;
2637 + vx_vmlocked_sub(current->mm, num_pages);
2639 up_write(¤t->mm->mmap_sem);
2641 @@ -219,7 +221,7 @@ static void user_pages_account(void *ptr
2642 struct ipath_user_pages_work *work = ptr;
2644 down_write(&work->mm->mmap_sem);
2645 - work->mm->locked_vm -= work->num_pages;
2646 + vx_vmlocked_sub(work->mm, work->num_pages);
2647 up_write(&work->mm->mmap_sem);
2650 diff -NurpP --minimal linux-2.6.19.1/drivers/md/dm-ioctl.c linux-2.6.19.1-vs2.3.0.6/drivers/md/dm-ioctl.c
2651 --- linux-2.6.19.1/drivers/md/dm-ioctl.c 2006-11-30 21:18:46 +0100
2652 +++ linux-2.6.19.1-vs2.3.0.6/drivers/md/dm-ioctl.c 2006-11-30 19:57:46 +0100
2654 #include <linux/slab.h>
2655 #include <linux/dm-ioctl.h>
2656 #include <linux/hdreg.h>
2657 +#include <linux/vs_context.h>
2659 #include <asm/uaccess.h>
2661 @@ -100,7 +101,8 @@ static struct hash_cell *__get_name_cell
2662 unsigned int h = hash_str(str);
2664 list_for_each_entry (hc, _name_buckets + h, name_list)
2665 - if (!strcmp(hc->name, str)) {
2666 + if (vx_check(dm_get_xid(hc->md), VS_WATCH_P|VS_IDENT) &&
2667 + !strcmp(hc->name, str)) {
2671 @@ -114,7 +116,8 @@ static struct hash_cell *__get_uuid_cell
2672 unsigned int h = hash_str(str);
2674 list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
2675 - if (!strcmp(hc->uuid, str)) {
2676 + if (vx_check(dm_get_xid(hc->md), VS_WATCH_P|VS_IDENT) &&
2677 + !strcmp(hc->uuid, str)) {
2681 @@ -349,6 +352,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl
2683 static int remove_all(struct dm_ioctl *param, size_t param_size)
2685 + if (!vx_check(0, VS_ADMIN))
2688 dm_hash_remove_all(1);
2689 param->data_size = 0;
2691 @@ -396,6 +402,8 @@ static int list_devices(struct dm_ioctl
2693 for (i = 0; i < NUM_BUCKETS; i++) {
2694 list_for_each_entry (hc, _name_buckets + i, name_list) {
2695 + if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P|VS_IDENT))
2697 needed += sizeof(struct dm_name_list);
2698 needed += strlen(hc->name) + 1;
2699 needed += ALIGN_MASK;
2700 @@ -419,6 +427,8 @@ static int list_devices(struct dm_ioctl
2702 for (i = 0; i < NUM_BUCKETS; i++) {
2703 list_for_each_entry (hc, _name_buckets + i, name_list) {
2704 + if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P|VS_IDENT))
2707 old_nl->next = (uint32_t) ((void *) nl -
2709 @@ -609,10 +619,11 @@ static struct hash_cell *__find_device_h
2713 - mdptr = dm_get_mdptr(md);
2714 + if (vx_check(dm_get_xid(md), VS_WATCH_P|VS_IDENT))
2715 + mdptr = dm_get_mdptr(md);
2723 @@ -1405,8 +1416,8 @@ static int ctl_ioctl(struct inode *inode
2727 - /* only root can play with this */
2728 - if (!capable(CAP_SYS_ADMIN))
2729 + /* only root and certain contexts can play with this */
2730 + if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER))
2733 if (_IOC_TYPE(command) != DM_IOCTL)
2734 diff -NurpP --minimal linux-2.6.19.1/drivers/md/dm.c linux-2.6.19.1-vs2.3.0.6/drivers/md/dm.c
2735 --- linux-2.6.19.1/drivers/md/dm.c 2006-11-30 21:18:46 +0100
2736 +++ linux-2.6.19.1-vs2.3.0.6/drivers/md/dm.c 2006-11-30 18:53:18 +0100
2738 #include <linux/hdreg.h>
2739 #include <linux/blktrace_api.h>
2740 #include <linux/smp_lock.h>
2741 +#include <linux/vs_base.h>
2743 #define DM_MSG_PREFIX "core"
2745 @@ -75,6 +76,7 @@ struct mapped_device {
2748 atomic_t open_count;
2751 unsigned long flags;
2753 @@ -220,6 +222,7 @@ static void __exit dm_exit(void)
2754 static int dm_blk_open(struct inode *inode, struct file *file)
2756 struct mapped_device *md;
2759 spin_lock(&_minor_lock);
2761 @@ -228,18 +231,19 @@ static int dm_blk_open(struct inode *ino
2764 if (test_bit(DMF_FREEING, &md->flags) ||
2765 - test_bit(DMF_DELETING, &md->flags)) {
2767 + test_bit(DMF_DELETING, &md->flags))
2771 + if (!vx_check(md->xid, VS_IDENT))
2776 atomic_inc(&md->open_count);
2780 spin_unlock(&_minor_lock);
2782 - return md ? 0 : -ENXIO;
2786 static int dm_blk_close(struct inode *inode, struct file *file)
2787 @@ -435,6 +439,14 @@ int dm_set_geometry(struct mapped_device
2792 + * Get the xid associated with a dm device
2794 +xid_t dm_get_xid(struct mapped_device *md)
2799 /*-----------------------------------------------------------------
2801 * A more elegant soln is in the works that uses the queue
2802 @@ -952,6 +964,7 @@ static struct mapped_device *alloc_dev(i
2803 atomic_set(&md->holders, 1);
2804 atomic_set(&md->open_count, 0);
2805 atomic_set(&md->event_nr, 0);
2806 + md->xid = vx_current_xid();
2808 md->queue = blk_alloc_queue(GFP_KERNEL);
2810 diff -NurpP --minimal linux-2.6.19.1/drivers/md/dm.h linux-2.6.19.1-vs2.3.0.6/drivers/md/dm.h
2811 --- linux-2.6.19.1/drivers/md/dm.h 2006-11-30 21:18:46 +0100
2812 +++ linux-2.6.19.1-vs2.3.0.6/drivers/md/dm.h 2006-11-08 04:57:52 +0100
2813 @@ -72,6 +72,8 @@ void dm_put_target_type(struct target_ty
2814 int dm_target_iterate(void (*iter_func)(struct target_type *tt,
2815 void *param), void *param);
2817 +xid_t dm_get_xid(struct mapped_device *md);
2819 /*-----------------------------------------------------------------
2821 *---------------------------------------------------------------*/
2822 diff -NurpP --minimal linux-2.6.19.1/fs/attr.c linux-2.6.19.1-vs2.3.0.6/fs/attr.c
2823 --- linux-2.6.19.1/fs/attr.c 2006-04-09 13:49:53 +0200
2824 +++ linux-2.6.19.1-vs2.3.0.6/fs/attr.c 2006-11-30 19:40:56 +0100
2826 #include <linux/fcntl.h>
2827 #include <linux/quotaops.h>
2828 #include <linux/security.h>
2829 +#include <linux/proc_fs.h>
2830 +#include <linux/devpts_fs.h>
2831 +#include <linux/vs_base.h>
2833 /* Taken over from the old code... */
2835 @@ -56,6 +59,30 @@ int inode_change_ok(struct inode *inode,
2836 if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
2840 + /* Check for evil vserver activity */
2841 + if (vx_check(0, VS_ADMIN))
2844 + if (IS_BARRIER(inode)) {
2845 + vxwprintk(1, "xid=%d messing with the barrier.",
2846 + vx_current_xid());
2849 + switch (inode->i_sb->s_magic) {
2850 + case PROC_SUPER_MAGIC:
2851 + /* maybe allow that in the future? */
2852 + vxwprintk(1, "xid=%d messing with the procfs.",
2853 + vx_current_xid());
2855 + case DEVPTS_SUPER_MAGIC:
2856 + /* devpts is xid tagged */
2857 + if (vx_check((xid_t)inode->i_tag, VS_IDENT))
2859 + vxwprintk(1, "xid=%d messing with the devpts.",
2860 + vx_current_xid());
2866 @@ -79,6 +106,8 @@ int inode_setattr(struct inode * inode,
2867 inode->i_uid = attr->ia_uid;
2868 if (ia_valid & ATTR_GID)
2869 inode->i_gid = attr->ia_gid;
2870 + if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode))
2871 + inode->i_tag = attr->ia_tag;
2872 if (ia_valid & ATTR_ATIME)
2873 inode->i_atime = timespec_trunc(attr->ia_atime,
2874 inode->i_sb->s_time_gran);
2875 @@ -153,7 +182,8 @@ int notify_change(struct dentry * dentry
2876 error = security_inode_setattr(dentry, attr);
2878 if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
2879 - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
2880 + (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
2881 + (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag))
2882 error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
2884 error = inode_setattr(inode, attr);
2885 diff -NurpP --minimal linux-2.6.19.1/fs/binfmt_aout.c linux-2.6.19.1-vs2.3.0.6/fs/binfmt_aout.c
2886 --- linux-2.6.19.1/fs/binfmt_aout.c 2006-11-30 21:19:18 +0100
2887 +++ linux-2.6.19.1-vs2.3.0.6/fs/binfmt_aout.c 2006-11-08 04:57:40 +0100
2889 #include <linux/binfmts.h>
2890 #include <linux/personality.h>
2891 #include <linux/init.h>
2892 +#include <linux/vs_memory.h>
2894 #include <asm/system.h>
2895 #include <asm/uaccess.h>
2896 diff -NurpP --minimal linux-2.6.19.1/fs/binfmt_elf.c linux-2.6.19.1-vs2.3.0.6/fs/binfmt_elf.c
2897 --- linux-2.6.19.1/fs/binfmt_elf.c 2006-11-30 21:19:18 +0100
2898 +++ linux-2.6.19.1-vs2.3.0.6/fs/binfmt_elf.c 2006-12-02 01:37:05 +0100
2900 #include <linux/syscalls.h>
2901 #include <linux/random.h>
2902 #include <linux/elf.h>
2903 +#include <linux/vs_memory.h>
2904 #include <asm/uaccess.h>
2905 #include <asm/param.h>
2906 #include <asm/page.h>
2907 diff -NurpP --minimal linux-2.6.19.1/fs/binfmt_flat.c linux-2.6.19.1-vs2.3.0.6/fs/binfmt_flat.c
2908 --- linux-2.6.19.1/fs/binfmt_flat.c 2006-09-20 16:58:34 +0200
2909 +++ linux-2.6.19.1-vs2.3.0.6/fs/binfmt_flat.c 2006-11-08 04:57:40 +0100
2911 #include <linux/init.h>
2912 #include <linux/flat.h>
2913 #include <linux/syscalls.h>
2914 +#include <linux/vs_memory.h>
2916 #include <asm/byteorder.h>
2917 #include <asm/system.h>
2918 diff -NurpP --minimal linux-2.6.19.1/fs/binfmt_som.c linux-2.6.19.1-vs2.3.0.6/fs/binfmt_som.c
2919 --- linux-2.6.19.1/fs/binfmt_som.c 2006-11-30 21:19:19 +0100
2920 +++ linux-2.6.19.1-vs2.3.0.6/fs/binfmt_som.c 2006-11-08 04:57:40 +0100
2922 #include <linux/shm.h>
2923 #include <linux/personality.h>
2924 #include <linux/init.h>
2925 +#include <linux/vs_memory.h>
2927 #include <asm/a.out.h>
2928 #include <asm/uaccess.h>
2929 diff -NurpP --minimal linux-2.6.19.1/fs/dcache.c linux-2.6.19.1-vs2.3.0.6/fs/dcache.c
2930 --- linux-2.6.19.1/fs/dcache.c 2006-11-30 21:19:19 +0100
2931 +++ linux-2.6.19.1-vs2.3.0.6/fs/dcache.c 2006-11-08 04:57:48 +0100
2933 #include <linux/seqlock.h>
2934 #include <linux/swap.h>
2935 #include <linux/bootmem.h>
2936 +#include <linux/vs_limit.h>
2937 #include "internal.h"
2940 @@ -147,6 +148,7 @@ void dput(struct dentry *dentry)
2944 + vx_dentry_dec(dentry);
2946 if (atomic_read(&dentry->d_count) == 1)
2948 @@ -160,6 +162,8 @@ repeat:
2952 + vx_dentry_dec(dentry);
2955 * AV: ->d_delete() is _NOT_ allowed to block now.
2957 @@ -270,6 +274,7 @@ static inline struct dentry * __dget_loc
2958 if (!list_empty(&dentry->d_lru)) {
2959 dentry_stat.nr_unused--;
2960 list_del_init(&dentry->d_lru);
2961 + vx_dentry_inc(dentry);
2965 @@ -861,6 +866,9 @@ struct dentry *d_alloc(struct dentry * p
2966 struct dentry *dentry;
2969 + if (!vx_dentry_avail(1))
2972 dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
2975 @@ -909,6 +917,7 @@ struct dentry *d_alloc(struct dentry * p
2977 list_add(&dentry->d_u.d_child, &parent->d_subdirs);
2978 dentry_stat.nr_dentry++;
2979 + vx_dentry_inc(dentry);
2980 spin_unlock(&dcache_lock);
2983 @@ -1258,6 +1267,7 @@ struct dentry * __d_lookup(struct dentry
2985 if (!d_unhashed(dentry)) {
2986 atomic_inc(&dentry->d_count);
2987 + vx_dentry_inc(dentry);
2990 spin_unlock(&dentry->d_lock);
2991 diff -NurpP --minimal linux-2.6.19.1/fs/devpts/inode.c linux-2.6.19.1-vs2.3.0.6/fs/devpts/inode.c
2992 --- linux-2.6.19.1/fs/devpts/inode.c 2006-11-30 21:19:19 +0100
2993 +++ linux-2.6.19.1-vs2.3.0.6/fs/devpts/inode.c 2006-11-30 18:53:18 +0100
2995 #include <linux/tty.h>
2996 #include <linux/devpts_fs.h>
2997 #include <linux/parser.h>
2998 +#include <linux/vs_base.h>
3000 -#define DEVPTS_SUPER_MAGIC 0x1cd1
3002 +static int devpts_permission(struct inode *inode, int mask, struct nameidata *nd)
3004 + int ret = -EACCES;
3006 + /* devpts is xid tagged */
3007 + if (vx_check((xid_t)inode->i_tag, VS_WATCH_P|VS_IDENT))
3008 + ret = generic_permission(inode, mask, NULL);
3012 +static struct inode_operations devpts_file_inode_operations = {
3013 + .permission = devpts_permission,
3016 static struct vfsmount *devpts_mnt;
3017 static struct dentry *devpts_root;
3018 @@ -91,6 +105,25 @@ static int devpts_remount(struct super_b
3022 +static int devpts_filter(struct dentry *de)
3024 + /* devpts is xid tagged */
3025 + return vx_check((xid_t)de->d_inode->i_tag, VS_WATCH_P|VS_IDENT);
3028 +static int devpts_readdir(struct file * filp, void * dirent, filldir_t filldir)
3030 + return dcache_readdir_filter(filp, dirent, filldir, devpts_filter);
3033 +static struct file_operations devpts_dir_operations = {
3034 + .open = dcache_dir_open,
3035 + .release = dcache_dir_close,
3036 + .llseek = dcache_dir_lseek,
3037 + .read = generic_read_dir,
3038 + .readdir = devpts_readdir,
3041 static struct super_operations devpts_sops = {
3042 .statfs = simple_statfs,
3043 .remount_fs = devpts_remount,
3044 @@ -116,8 +149,10 @@ devpts_fill_super(struct super_block *s,
3045 inode->i_uid = inode->i_gid = 0;
3046 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
3047 inode->i_op = &simple_dir_inode_operations;
3048 - inode->i_fop = &simple_dir_operations;
3049 + inode->i_fop = &devpts_dir_operations;
3051 + /* devpts is xid tagged */
3052 + inode->i_tag = (tag_t)vx_current_xid();
3054 devpts_root = s->s_root = d_alloc_root(inode);
3056 @@ -175,6 +210,9 @@ int devpts_pty_new(struct tty_struct *tt
3057 inode->i_gid = config.setgid ? config.gid : current->fsgid;
3058 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
3059 init_special_inode(inode, S_IFCHR|config.mode, device);
3060 + /* devpts is xid tagged */
3061 + inode->i_tag = (tag_t)vx_current_xid();
3062 + inode->i_op = &devpts_file_inode_operations;
3063 inode->i_private = tty;
3065 dentry = get_node(number);
3066 diff -NurpP --minimal linux-2.6.19.1/fs/dquot.c linux-2.6.19.1-vs2.3.0.6/fs/dquot.c
3067 --- linux-2.6.19.1/fs/dquot.c 2006-11-30 21:19:19 +0100
3068 +++ linux-2.6.19.1-vs2.3.0.6/fs/dquot.c 2006-11-30 19:41:09 +0100
3069 @@ -185,7 +185,7 @@ static void put_quota_format(struct quot
3071 * Dquot List Management:
3072 * The quota code uses three lists for dquot management: the inuse_list,
3073 - * free_dquots, and dquot_hash[] array. A single dquot structure may be
3074 + * free_dquots, and hash->dqh_hash[] array. A single dquot structure may be
3075 * on all three lists, depending on its current state.
3077 * All dquots are placed to the end of inuse_list when first created, and this
3078 @@ -198,7 +198,7 @@ static void put_quota_format(struct quot
3079 * dquot is invalidated it's completely released from memory.
3081 * Dquots with a specific identity (device, type and id) are placed on
3082 - * one of the dquot_hash[] hash chains. The provides an efficient search
3083 + * one of the hash->dqh_hash[] hash chains. The provides an efficient search
3084 * mechanism to locate a specific dquot.
3087 @@ -212,36 +212,44 @@ struct dqstats dqstats;
3088 static void dqput(struct dquot *dquot);
3090 static inline unsigned int
3091 -hashfn(const struct super_block *sb, unsigned int id, int type)
3092 +hashfn(struct dqhash *hash, unsigned int id, int type)
3096 - tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type);
3097 + tmp = (((unsigned long)hash >> L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type);
3098 return (tmp + (tmp >> dq_hash_bits)) & dq_hash_mask;
3102 * Following list functions expect dq_list_lock to be held
3104 -static inline void insert_dquot_hash(struct dquot *dquot)
3105 +static inline void insert_dquot_hash(struct dqhash *hash, struct dquot *dquot)
3107 - struct hlist_head *head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
3108 + struct hlist_head *head = dquot_hash +
3109 + hashfn(hash, dquot->dq_id, dquot->dq_type);
3110 + /* struct hlist_head *head = hash->dqh_hash +
3111 + hashfn(dquot->dq_dqh, dquot->dq_id, dquot->dq_type); */
3112 hlist_add_head(&dquot->dq_hash, head);
3113 + dquot->dq_dqh = dqhget(hash);
3116 static inline void remove_dquot_hash(struct dquot *dquot)
3118 hlist_del_init(&dquot->dq_hash);
3119 + dqhput(dquot->dq_dqh);
3120 + dquot->dq_dqh = NULL;
3123 -static inline struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, unsigned int id, int type)
3124 +static inline struct dquot *find_dquot(struct dqhash *hash,
3125 + unsigned int hashent, unsigned int id, int type)
3127 struct hlist_node *node;
3128 struct dquot *dquot;
3130 - hlist_for_each (node, dquot_hash+hashent) {
3131 + /* hlist_for_each (node, hash->dqh_hash + hashent) { */
3132 + hlist_for_each (node, dquot_hash + hashent) {
3133 dquot = hlist_entry(node, struct dquot, dq_hash);
3134 - if (dquot->dq_sb == sb && dquot->dq_id == id && dquot->dq_type == type)
3135 + if (dquot->dq_dqh == hash && dquot->dq_id == id && dquot->dq_type == type)
3139 @@ -285,13 +293,13 @@ static void wait_on_dquot(struct dquot *
3140 mutex_unlock(&dquot->dq_lock);
3143 -#define mark_dquot_dirty(dquot) ((dquot)->dq_sb->dq_op->mark_dirty(dquot))
3144 +#define mark_dquot_dirty(dquot) ((dquot)->dq_dqh->dqh_qop->mark_dirty(dquot))
3146 int dquot_mark_dquot_dirty(struct dquot *dquot)
3148 spin_lock(&dq_list_lock);
3149 if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags))
3150 - list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)->
3151 + list_add(&dquot->dq_dirty, &dqh_dqopt(dquot->dq_dqh)->
3152 info[dquot->dq_type].dqi_dirty_list);
3153 spin_unlock(&dq_list_lock);
3155 @@ -306,9 +314,9 @@ static inline int clear_dquot_dirty(stru
3159 -void mark_info_dirty(struct super_block *sb, int type)
3160 +void mark_info_dirty(struct dqhash *hash, int type)
3162 - set_bit(DQF_INFO_DIRTY_B, &sb_dqopt(sb)->info[type].dqi_flags);
3163 + set_bit(DQF_INFO_DIRTY_B, &dqh_dqopt(hash)->info[type].dqi_flags);
3165 EXPORT_SYMBOL(mark_info_dirty);
3167 @@ -319,7 +327,7 @@ EXPORT_SYMBOL(mark_info_dirty);
3168 int dquot_acquire(struct dquot *dquot)
3170 int ret = 0, ret2 = 0;
3171 - struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
3172 + struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh);
3174 mutex_lock(&dquot->dq_lock);
3175 mutex_lock(&dqopt->dqio_mutex);
3176 @@ -333,7 +341,7 @@ int dquot_acquire(struct dquot *dquot)
3177 ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
3178 /* Write the info if needed */
3179 if (info_dirty(&dqopt->info[dquot->dq_type]))
3180 - ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
3181 + ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type);
3185 @@ -354,7 +362,7 @@ out_iolock:
3186 int dquot_commit(struct dquot *dquot)
3188 int ret = 0, ret2 = 0;
3189 - struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
3190 + struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh);
3192 mutex_lock(&dqopt->dqio_mutex);
3193 spin_lock(&dq_list_lock);
3194 @@ -368,7 +376,7 @@ int dquot_commit(struct dquot *dquot)
3195 if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
3196 ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
3197 if (info_dirty(&dqopt->info[dquot->dq_type]))
3198 - ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
3199 + ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type);
3203 @@ -383,7 +391,7 @@ out_sem:
3204 int dquot_release(struct dquot *dquot)
3206 int ret = 0, ret2 = 0;
3207 - struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
3208 + struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh);
3210 mutex_lock(&dquot->dq_lock);
3211 /* Check whether we are not racing with some other dqget() */
3212 @@ -394,7 +402,7 @@ int dquot_release(struct dquot *dquot)
3213 ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);
3214 /* Write the info */
3215 if (info_dirty(&dqopt->info[dquot->dq_type]))
3216 - ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
3217 + ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type);
3221 @@ -411,14 +419,14 @@ out_dqlock:
3222 * just deleted or pruned by prune_icache() (those are not attached to any
3223 * list). We have to wait for such users.
3225 -static void invalidate_dquots(struct super_block *sb, int type)
3226 +static void invalidate_dquots(struct dqhash *hash, int type)
3228 struct dquot *dquot, *tmp;
3231 spin_lock(&dq_list_lock);
3232 list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
3233 - if (dquot->dq_sb != sb)
3234 + if (dquot->dq_dqh != hash)
3236 if (dquot->dq_type != type)
3238 @@ -458,18 +466,18 @@ restart:
3239 spin_unlock(&dq_list_lock);
3242 -int vfs_quota_sync(struct super_block *sb, int type)
3243 +int vfs_quota_sync(struct dqhash *hash, int type)
3245 struct list_head *dirty;
3246 struct dquot *dquot;
3247 - struct quota_info *dqopt = sb_dqopt(sb);
3248 + struct quota_info *dqopt = dqh_dqopt(hash);
3251 mutex_lock(&dqopt->dqonoff_mutex);
3252 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
3253 if (type != -1 && cnt != type)
3255 - if (!sb_has_quota_enabled(sb, cnt))
3256 + if (!dqh_has_quota_enabled(hash, cnt))
3258 spin_lock(&dq_list_lock);
3259 dirty = &dqopt->info[cnt].dqi_dirty_list;
3260 @@ -486,7 +494,7 @@ int vfs_quota_sync(struct super_block *s
3261 atomic_inc(&dquot->dq_count);
3263 spin_unlock(&dq_list_lock);
3264 - sb->dq_op->write_dquot(dquot);
3265 + hash->dqh_qop->write_dquot(dquot);
3267 spin_lock(&dq_list_lock);
3269 @@ -494,9 +502,10 @@ int vfs_quota_sync(struct super_block *s
3272 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3273 - if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt)
3274 + if ((cnt == type || type == -1)
3275 + && dqh_has_quota_enabled(hash, cnt)
3276 && info_dirty(&dqopt->info[cnt]))
3277 - sb->dq_op->write_info(sb, cnt);
3278 + hash->dqh_qop->write_info(hash, cnt);
3279 spin_lock(&dq_list_lock);
3281 spin_unlock(&dq_list_lock);
3282 @@ -551,7 +560,7 @@ static void dqput(struct dquot *dquot)
3283 if (!atomic_read(&dquot->dq_count)) {
3284 printk("VFS: dqput: trying to free free dquot\n");
3285 printk("VFS: device %s, dquot of %s %d\n",
3286 - dquot->dq_sb->s_id,
3287 + dquot->dq_dqh->dqh_sb->s_id,
3288 quotatypes[dquot->dq_type],
3291 @@ -567,7 +576,7 @@ we_slept:
3292 /* We have more than one user... nothing to do */
3293 atomic_dec(&dquot->dq_count);
3294 /* Releasing dquot during quotaoff phase? */
3295 - if (!sb_has_quota_enabled(dquot->dq_sb, dquot->dq_type) &&
3296 + if (!dqh_has_quota_enabled(dquot->dq_dqh, dquot->dq_type) &&
3297 atomic_read(&dquot->dq_count) == 1)
3298 wake_up(&dquot->dq_wait_unused);
3299 spin_unlock(&dq_list_lock);
3300 @@ -577,14 +586,14 @@ we_slept:
3301 if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) {
3302 spin_unlock(&dq_list_lock);
3303 /* Commit dquot before releasing */
3304 - dquot->dq_sb->dq_op->write_dquot(dquot);
3305 + dquot->dq_dqh->dqh_qop->write_dquot(dquot);
3308 /* Clear flag in case dquot was inactive (something bad happened) */
3309 clear_dquot_dirty(dquot);
3310 if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
3311 spin_unlock(&dq_list_lock);
3312 - dquot->dq_sb->dq_op->release_dquot(dquot);
3313 + dquot->dq_dqh->dqh_qop->release_dquot(dquot);
3316 atomic_dec(&dquot->dq_count);
3317 @@ -596,7 +605,7 @@ we_slept:
3318 spin_unlock(&dq_list_lock);
3321 -static struct dquot *get_empty_dquot(struct super_block *sb, int type)
3322 +static struct dquot *get_empty_dquot(int type)
3324 struct dquot *dquot;
3326 @@ -611,7 +620,7 @@ static struct dquot *get_empty_dquot(str
3327 INIT_HLIST_NODE(&dquot->dq_hash);
3328 INIT_LIST_HEAD(&dquot->dq_dirty);
3329 init_waitqueue_head(&dquot->dq_wait_unused);
3330 - dquot->dq_sb = sb;
3331 + dquot->dq_dqh = NULL;
3332 dquot->dq_type = type;
3333 atomic_set(&dquot->dq_count, 1);
3335 @@ -622,19 +631,19 @@ static struct dquot *get_empty_dquot(str
3336 * Get reference to dquot
3337 * MUST be called with either dqptr_sem or dqonoff_mutex held
3339 -static struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
3340 +static struct dquot *dqget(struct dqhash *hash, unsigned int id, int type)
3342 - unsigned int hashent = hashfn(sb, id, type);
3343 + unsigned int hashent = hashfn(hash, id, type);
3344 struct dquot *dquot, *empty = NODQUOT;
3346 - if (!sb_has_quota_enabled(sb, type))
3347 + if (!dqh_has_quota_enabled(hash, type))
3350 spin_lock(&dq_list_lock);
3351 - if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) {
3352 + if ((dquot = find_dquot(hash, hashent, id, type)) == NODQUOT) {
3353 if (empty == NODQUOT) {
3354 spin_unlock(&dq_list_lock);
3355 - if ((empty = get_empty_dquot(sb, type)) == NODQUOT)
3356 + if ((empty = get_empty_dquot(type)) == NODQUOT)
3357 schedule(); /* Try to wait for a moment... */
3360 @@ -643,7 +652,7 @@ we_slept:
3361 /* all dquots go on the inuse_list */
3363 /* hash it first so it can be found */
3364 - insert_dquot_hash(dquot);
3365 + insert_dquot_hash(hash, dquot);
3367 spin_unlock(&dq_list_lock);
3369 @@ -660,12 +669,13 @@ we_slept:
3370 * finished or it will be canceled due to dq_count > 1 test */
3371 wait_on_dquot(dquot);
3372 /* Read the dquot and instantiate it (everything done only if needed) */
3373 - if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) {
3374 + if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) &&
3375 + hash->dqh_qop->acquire_dquot(dquot) < 0) {
3379 #ifdef __DQUOT_PARANOIA
3380 - BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */
3381 + BUG_ON(!dquot->dq_dqh); /* Has somebody invalidated entry under us? */
3385 @@ -686,9 +696,10 @@ static int dqinit_needed(struct inode *i
3388 /* This routine is guarded by dqonoff_mutex mutex */
3389 -static void add_dquot_ref(struct super_block *sb, int type)
3390 +static void add_dquot_ref(struct dqhash *hash, int type)
3392 struct list_head *p;
3393 + struct super_block *sb = hash->dqh_sb;
3397 @@ -698,7 +709,7 @@ restart:
3398 if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
3399 struct dentry *dentry = dget(filp->f_dentry);
3401 - sb->dq_op->initialize(inode, type);
3402 + hash->dqh_qop->initialize(inode, type);
3404 /* As we may have blocked we had better restart... */
3406 @@ -757,13 +768,13 @@ static void put_dquot_list(struct list_h
3409 /* Gather all references from inodes and drop them */
3410 -static void drop_dquot_ref(struct super_block *sb, int type)
3411 +static void drop_dquot_ref(struct dqhash *hash, int type)
3413 LIST_HEAD(tofree_head);
3415 - down_write(&sb_dqopt(sb)->dqptr_sem);
3416 - remove_dquot_ref(sb, type, &tofree_head);
3417 - up_write(&sb_dqopt(sb)->dqptr_sem);
3418 + down_write(&dqh_dqopt(hash)->dqptr_sem);
3419 + remove_dquot_ref(hash, type, &tofree_head);
3420 + up_write(&dqh_dqopt(hash)->dqptr_sem);
3421 put_dquot_list(&tofree_head);
3424 @@ -837,7 +848,7 @@ static void print_warning(struct dquot *
3425 mutex_lock(&tty_mutex);
3426 if (!current->signal->tty)
3428 - tty_write_message(current->signal->tty, dquot->dq_sb->s_id);
3429 + tty_write_message(current->signal->tty, dquot->dq_dqh->dqh_sb->s_id);
3430 if (warntype == ISOFTWARN || warntype == BSOFTWARN)
3431 tty_write_message(current->signal->tty, ": warning, ");
3433 @@ -879,7 +890,7 @@ static inline void flush_warnings(struct
3435 static inline char ignore_hardlimit(struct dquot *dquot)
3437 - struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
3438 + struct mem_dqinfo *info = &dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type];
3440 return capable(CAP_SYS_RESOURCE) &&
3441 (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || !(info->dqi_flags & V1_DQF_RSQUASH));
3442 @@ -911,7 +922,7 @@ static int check_idq(struct dquot *dquot
3443 (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
3444 dquot->dq_dqb.dqb_itime == 0) {
3445 *warntype = ISOFTWARN;
3446 - dquot->dq_dqb.dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
3447 + dquot->dq_dqb.dqb_itime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_igrace;
3451 @@ -946,7 +957,7 @@ static int check_bdq(struct dquot *dquot
3452 dquot->dq_dqb.dqb_btime == 0) {
3454 *warntype = BSOFTWARN;
3455 - dquot->dq_dqb.dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
3456 + dquot->dq_dqb.dqb_btime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_bgrace;
3460 @@ -972,7 +983,7 @@ int dquot_initialize(struct inode *inode
3461 * re-enter the quota code and are already holding the mutex */
3462 if (IS_NOQUOTA(inode))
3464 - down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3465 + down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3466 /* Having dqptr_sem we know NOQUOTA flags can't be altered... */
3467 if (IS_NOQUOTA(inode))
3469 @@ -988,11 +999,11 @@ int dquot_initialize(struct inode *inode
3473 - inode->i_dquot[cnt] = dqget(inode->i_sb, id, cnt);
3474 + inode->i_dquot[cnt] = dqget(inode->i_dqh, id, cnt);
3478 - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3479 + up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3483 @@ -1004,14 +1015,14 @@ int dquot_drop(struct inode *inode)
3487 - down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3488 + down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3489 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
3490 if (inode->i_dquot[cnt] != NODQUOT) {
3491 dqput(inode->i_dquot[cnt]);
3492 inode->i_dquot[cnt] = NODQUOT;
3495 - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3496 + up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3500 @@ -1042,9 +1053,9 @@ out_add:
3501 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3502 warntype[cnt] = NOWARN;
3504 - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3505 + down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3506 if (IS_NOQUOTA(inode)) { /* Now we can do reliable test... */
3507 - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3508 + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3511 spin_lock(&dq_data_lock);
3512 @@ -1069,7 +1080,7 @@ warn_put_all:
3513 if (inode->i_dquot[cnt])
3514 mark_dquot_dirty(inode->i_dquot[cnt]);
3515 flush_warnings(inode->i_dquot, warntype);
3516 - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3517 + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3521 @@ -1087,9 +1098,9 @@ int dquot_alloc_inode(const struct inode
3523 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3524 warntype[cnt] = NOWARN;
3525 - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3526 + down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3527 if (IS_NOQUOTA(inode)) {
3528 - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3529 + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3532 spin_lock(&dq_data_lock);
3533 @@ -1114,7 +1125,7 @@ warn_put_all:
3534 if (inode->i_dquot[cnt])
3535 mark_dquot_dirty(inode->i_dquot[cnt]);
3536 flush_warnings((struct dquot **)inode->i_dquot, warntype);
3537 - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3538 + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3542 @@ -1132,10 +1143,10 @@ out_sub:
3543 inode_sub_bytes(inode, number);
3546 - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3547 + down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3548 /* Now recheck reliably when holding dqptr_sem */
3549 if (IS_NOQUOTA(inode)) {
3550 - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3551 + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3554 spin_lock(&dq_data_lock);
3555 @@ -1150,7 +1161,7 @@ out_sub:
3556 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3557 if (inode->i_dquot[cnt])
3558 mark_dquot_dirty(inode->i_dquot[cnt]);
3559 - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3560 + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3564 @@ -1165,10 +1176,10 @@ int dquot_free_inode(const struct inode
3565 * re-enter the quota code and are already holding the mutex */
3566 if (IS_NOQUOTA(inode))
3568 - down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3569 + down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3570 /* Now recheck reliably when holding dqptr_sem */
3571 if (IS_NOQUOTA(inode)) {
3572 - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3573 + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3576 spin_lock(&dq_data_lock);
3577 @@ -1182,7 +1193,7 @@ int dquot_free_inode(const struct inode
3578 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3579 if (inode->i_dquot[cnt])
3580 mark_dquot_dirty(inode->i_dquot[cnt]);
3581 - up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3582 + up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3586 @@ -1197,6 +1208,7 @@ int dquot_transfer(struct inode *inode,
3588 struct dquot *transfer_from[MAXQUOTAS];
3589 struct dquot *transfer_to[MAXQUOTAS];
3590 + struct dqhash *dqh = inode->i_sb->s_dqh;
3591 int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid,
3592 chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid;
3593 char warntype[MAXQUOTAS];
3594 @@ -1210,10 +1222,10 @@ int dquot_transfer(struct inode *inode,
3595 transfer_to[cnt] = transfer_from[cnt] = NODQUOT;
3596 warntype[cnt] = NOWARN;
3598 - down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3599 + down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3600 /* Now recheck reliably when holding dqptr_sem */
3601 if (IS_NOQUOTA(inode)) { /* File without quota accounting? */
3602 - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3603 + up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3606 /* First build the transfer_to list - here we can block on
3607 @@ -1224,12 +1236,12 @@ int dquot_transfer(struct inode *inode,
3611 - transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
3612 + transfer_to[cnt] = dqget(dqh, iattr->ia_uid, cnt);
3617 - transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
3618 + transfer_to[cnt] = dqget(dqh, iattr->ia_gid, cnt);
3622 @@ -1284,20 +1296,20 @@ warn_put_all:
3623 if (ret == NO_QUOTA && transfer_to[cnt] != NODQUOT)
3624 dqput(transfer_to[cnt]);
3626 - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3627 + up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3632 * Write info of quota file to disk
3634 -int dquot_commit_info(struct super_block *sb, int type)
3635 +int dquot_commit_info(struct dqhash *hash, int type)
3638 - struct quota_info *dqopt = sb_dqopt(sb);
3639 + struct quota_info *dqopt = dqh_dqopt(hash);
3641 mutex_lock(&dqopt->dqio_mutex);
3642 - ret = dqopt->ops[type]->write_file_info(sb, type);
3643 + ret = dqopt->ops[type]->write_file_info(hash, type);
3644 mutex_unlock(&dqopt->dqio_mutex);
3647 @@ -1347,10 +1359,10 @@ static inline void reset_enable_flags(st
3649 * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
3651 -int vfs_quota_off(struct super_block *sb, int type)
3652 +int vfs_quota_off(struct dqhash *hash, int type)
3655 - struct quota_info *dqopt = sb_dqopt(sb);
3656 + struct quota_info *dqopt = dqh_dqopt(hash);
3657 struct inode *toputinode[MAXQUOTAS];
3659 /* We need to serialize quota_off() for device */
3660 @@ -1359,21 +1371,21 @@ int vfs_quota_off(struct super_block *sb
3661 toputinode[cnt] = NULL;
3662 if (type != -1 && cnt != type)
3664 - if (!sb_has_quota_enabled(sb, cnt))
3665 + if (!dqh_has_quota_enabled(hash, cnt))
3667 reset_enable_flags(dqopt, cnt);
3669 /* Note: these are blocking operations */
3670 - drop_dquot_ref(sb, cnt);
3671 - invalidate_dquots(sb, cnt);
3672 + drop_dquot_ref(hash, cnt);
3673 + invalidate_dquots(hash, cnt);
3675 * Now all dquots should be invalidated, all writes done so we should be only
3676 * users of the info. No locks needed.
3678 if (info_dirty(&dqopt->info[cnt]))
3679 - sb->dq_op->write_info(sb, cnt);
3680 + hash->dqh_qop->write_info(hash, cnt);
3681 if (dqopt->ops[cnt]->free_file_info)
3682 - dqopt->ops[cnt]->free_file_info(sb, cnt);
3683 + dqopt->ops[cnt]->free_file_info(hash, cnt);
3684 put_quota_format(dqopt->info[cnt].dqi_format);
3686 toputinode[cnt] = dqopt->files[cnt];
3687 @@ -1386,9 +1398,9 @@ int vfs_quota_off(struct super_block *sb
3688 mutex_unlock(&dqopt->dqonoff_mutex);
3689 /* Sync the superblock so that buffers with quota data are written to
3690 * disk (and so userspace sees correct data afterwards). */
3691 - if (sb->s_op->sync_fs)
3692 - sb->s_op->sync_fs(sb, 1);
3693 - sync_blockdev(sb->s_bdev);
3694 + if (hash->dqh_sb->s_op->sync_fs)
3695 + hash->dqh_sb->s_op->sync_fs(hash->dqh_sb, 1);
3696 + sync_blockdev(hash->dqh_sb->s_bdev);
3697 /* Now the quota files are just ordinary files and we can set the
3698 * inode flags back. Moreover we discard the pagecache so that
3699 * userspace sees the writes we did bypassing the pagecache. We
3700 @@ -1399,7 +1411,7 @@ int vfs_quota_off(struct super_block *sb
3701 mutex_lock(&dqopt->dqonoff_mutex);
3702 /* If quota was reenabled in the meantime, we have
3704 - if (!sb_has_quota_enabled(sb, cnt)) {
3705 + if (!dqh_has_quota_enabled(hash, cnt)) {
3706 mutex_lock(&toputinode[cnt]->i_mutex);
3707 toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
3708 S_NOATIME | S_NOQUOTA);
3709 @@ -1410,8 +1422,8 @@ int vfs_quota_off(struct super_block *sb
3711 mutex_unlock(&dqopt->dqonoff_mutex);
3714 - invalidate_bdev(sb->s_bdev, 0);
3715 + if (hash->dqh_sb->s_bdev)
3716 + invalidate_bdev(hash->dqh_sb->s_bdev, 0);
3720 @@ -1424,7 +1436,8 @@ static int vfs_quota_on_inode(struct ino
3722 struct quota_format_type *fmt = find_quota_format(format_id);
3723 struct super_block *sb = inode->i_sb;
3724 - struct quota_info *dqopt = sb_dqopt(sb);
3725 + struct dqhash *hash = inode->i_dqh;
3726 + struct quota_info *dqopt = dqh_dqopt(hash);
3730 @@ -1450,7 +1463,7 @@ static int vfs_quota_on_inode(struct ino
3731 invalidate_bdev(sb->s_bdev, 0);
3732 mutex_lock(&inode->i_mutex);
3733 mutex_lock(&dqopt->dqonoff_mutex);
3734 - if (sb_has_quota_enabled(sb, type)) {
3735 + if (dqh_has_quota_enabled(hash, type)) {
3739 @@ -1461,21 +1474,21 @@ static int vfs_quota_on_inode(struct ino
3740 oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA);
3741 inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
3742 up_write(&dqopt->dqptr_sem);
3743 - sb->dq_op->drop(inode);
3744 + hash->dqh_qop->drop(inode);
3747 dqopt->files[type] = igrab(inode);
3748 if (!dqopt->files[type])
3751 - if (!fmt->qf_ops->check_quota_file(sb, type))
3752 + if (!fmt->qf_ops->check_quota_file(hash, type))
3755 dqopt->ops[type] = fmt->qf_ops;
3756 dqopt->info[type].dqi_format = fmt;
3757 INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
3758 mutex_lock(&dqopt->dqio_mutex);
3759 - if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) {
3760 + if ((error = dqopt->ops[type]->read_file_info(hash, type)) < 0) {
3761 mutex_unlock(&dqopt->dqio_mutex);
3764 @@ -1483,7 +1496,7 @@ static int vfs_quota_on_inode(struct ino
3765 mutex_unlock(&inode->i_mutex);
3766 set_enable_flags(dqopt, type);
3768 - add_dquot_ref(sb, type);
3769 + add_dquot_ref(hash, type);
3770 mutex_unlock(&dqopt->dqonoff_mutex);
3773 @@ -1509,7 +1522,7 @@ out_fmt:
3776 /* Actual function called from quotactl() */
3777 -int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
3778 +int vfs_quota_on(struct dqhash *hash, int type, int format_id, char *path)
3780 struct nameidata nd;
3782 @@ -1521,7 +1534,7 @@ int vfs_quota_on(struct super_block *sb,
3785 /* Quota file not on the same filesystem? */
3786 - if (nd.mnt->mnt_sb != sb)
3787 + if (nd.mnt->mnt_sb != hash->dqh_sb)
3790 error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id);
3791 @@ -1534,13 +1547,13 @@ out_path:
3792 * This function is used when filesystem needs to initialize quotas
3793 * during mount time.
3795 -int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
3796 +int vfs_quota_on_mount(struct dqhash *hash, char *qf_name,
3797 int format_id, int type)
3799 struct dentry *dentry;
3802 - dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name));
3803 + dentry = lookup_one_len(qf_name, hash->dqh_sb->s_root, strlen(qf_name));
3805 return PTR_ERR(dentry);
3807 @@ -1576,18 +1589,18 @@ static void do_get_dqblk(struct dquot *d
3808 spin_unlock(&dq_data_lock);
3811 -int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
3812 +int vfs_get_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di)
3814 struct dquot *dquot;
3816 - mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
3817 - if (!(dquot = dqget(sb, id, type))) {
3818 - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3819 + mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
3820 + if (!(dquot = dqget(hash, id, type))) {
3821 + mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3824 do_get_dqblk(dquot, di);
3826 - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3827 + mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3831 @@ -1627,7 +1640,7 @@ static void do_set_dqblk(struct dquot *d
3832 clear_bit(DQ_BLKS_B, &dquot->dq_flags);
3834 else if (!(di->dqb_valid & QIF_BTIME)) /* Set grace only if user hasn't provided his own... */
3835 - dm->dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
3836 + dm->dqb_btime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_bgrace;
3839 if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) {
3840 @@ -1635,7 +1648,7 @@ static void do_set_dqblk(struct dquot *d
3841 clear_bit(DQ_INODES_B, &dquot->dq_flags);
3843 else if (!(di->dqb_valid & QIF_ITIME)) /* Set grace only if user hasn't provided his own... */
3844 - dm->dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
3845 + dm->dqb_itime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_igrace;
3847 if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit)
3848 clear_bit(DQ_FAKE_B, &dquot->dq_flags);
3849 @@ -1645,53 +1658,53 @@ static void do_set_dqblk(struct dquot *d
3850 mark_dquot_dirty(dquot);
3853 -int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
3854 +int vfs_set_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di)
3856 struct dquot *dquot;
3858 - mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
3859 - if (!(dquot = dqget(sb, id, type))) {
3860 - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3861 + mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
3862 + if (!(dquot = dqget(hash, id, type))) {
3863 + mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3866 do_set_dqblk(dquot, di);
3868 - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3869 + mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3873 /* Generic routine for getting common part of quota file information */
3874 -int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
3875 +int vfs_get_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii)
3877 struct mem_dqinfo *mi;
3879 - mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
3880 - if (!sb_has_quota_enabled(sb, type)) {
3881 - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3882 + mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
3883 + if (!dqh_has_quota_enabled(hash, type)) {
3884 + mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3887 - mi = sb_dqopt(sb)->info + type;
3888 + mi = dqh_dqopt(hash)->info + type;
3889 spin_lock(&dq_data_lock);
3890 ii->dqi_bgrace = mi->dqi_bgrace;
3891 ii->dqi_igrace = mi->dqi_igrace;
3892 ii->dqi_flags = mi->dqi_flags & DQF_MASK;
3893 ii->dqi_valid = IIF_ALL;
3894 spin_unlock(&dq_data_lock);
3895 - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3896 + mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3900 /* Generic routine for setting common part of quota file information */
3901 -int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
3902 +int vfs_set_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii)
3904 struct mem_dqinfo *mi;
3906 - mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
3907 - if (!sb_has_quota_enabled(sb, type)) {
3908 - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3909 + mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
3910 + if (!dqh_has_quota_enabled(hash, type)) {
3911 + mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3914 - mi = sb_dqopt(sb)->info + type;
3915 + mi = dqh_dqopt(hash)->info + type;
3916 spin_lock(&dq_data_lock);
3917 if (ii->dqi_valid & IIF_BGRACE)
3918 mi->dqi_bgrace = ii->dqi_bgrace;
3919 @@ -1700,10 +1713,10 @@ int vfs_set_dqinfo(struct super_block *s
3920 if (ii->dqi_valid & IIF_FLAGS)
3921 mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK);
3922 spin_unlock(&dq_data_lock);
3923 - mark_info_dirty(sb, type);
3924 + mark_info_dirty(hash, type);
3925 /* Force write to disk */
3926 - sb->dq_op->write_info(sb, type);
3927 - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3928 + hash->dqh_qop->write_info(hash, type);
3929 + mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3933 diff -NurpP --minimal linux-2.6.19.1/fs/exec.c linux-2.6.19.1-vs2.3.0.6/fs/exec.c
3934 --- linux-2.6.19.1/fs/exec.c 2006-12-13 07:46:36 +0100
3935 +++ linux-2.6.19.1-vs2.3.0.6/fs/exec.c 2006-12-13 09:16:31 +0100
3937 #include <linux/tsacct_kern.h>
3938 #include <linux/cn_proc.h>
3939 #include <linux/audit.h>
3940 +#include <linux/vs_memory.h>
3942 #include <asm/uaccess.h>
3943 #include <asm/mmu_context.h>
3944 @@ -436,7 +437,8 @@ int setup_arg_pages(struct linux_binprm
3945 kmem_cache_free(vm_area_cachep, mpnt);
3948 - mm->stack_vm = mm->total_vm = vma_pages(mpnt);
3949 + vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
3950 + mm->stack_vm = mm->total_vm;
3953 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
3954 @@ -1306,7 +1308,7 @@ static void format_corename(char *corena
3955 /* UNIX time of coredump */
3958 - do_gettimeofday(&tv);
3959 + vx_gettimeofday(&tv);
3960 rc = snprintf(out_ptr, out_end - out_ptr,
3962 if (rc > out_end - out_ptr)
3963 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/balloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/balloc.c
3964 --- linux-2.6.19.1/fs/ext2/balloc.c 2006-09-20 16:58:34 +0200
3965 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/balloc.c 2006-12-01 23:38:46 +0100
3967 #include <linux/sched.h>
3968 #include <linux/buffer_head.h>
3969 #include <linux/capability.h>
3970 +#include <linux/vs_dlimit.h>
3971 +#include <linux/vs_tag.h>
3974 * balloc.c contains the blocks allocation and deallocation routines
3975 @@ -102,12 +104,13 @@ static int reserve_blocks(struct super_b
3977 struct ext2_sb_info *sbi = EXT2_SB(sb);
3978 struct ext2_super_block *es = sbi->s_es;
3979 - unsigned free_blocks;
3980 - unsigned root_blocks;
3981 + unsigned long long free_blocks, root_blocks;
3983 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
3984 root_blocks = le32_to_cpu(es->s_r_blocks_count);
3986 + DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
3988 if (free_blocks < count)
3989 count = free_blocks;
3991 @@ -258,6 +261,7 @@ do_more:
3995 + DLIMIT_FREE_BLOCK(inode, freed);
3996 release_blocks(sb, freed);
3997 DQUOT_FREE_BLOCK(inode, freed);
3999 @@ -361,6 +365,10 @@ int ext2_new_block(struct inode *inode,
4003 + if (DLIMIT_ALLOC_BLOCK(inode, es_alloc)) {
4008 ext2_debug ("goal=%lu.\n", goal);
4010 @@ -508,6 +516,8 @@ got_block:
4013 group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);
4014 + DLIMIT_FREE_BLOCK(inode, es_alloc);
4016 release_blocks(sb, es_alloc);
4018 DQUOT_FREE_BLOCK(inode, dq_alloc);
4019 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/ext2.h linux-2.6.19.1-vs2.3.0.6/fs/ext2/ext2.h
4020 --- linux-2.6.19.1/fs/ext2/ext2.h 2006-11-30 21:19:19 +0100
4021 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/ext2.h 2006-11-08 04:57:46 +0100
4022 @@ -166,6 +166,7 @@ extern const struct file_operations ext2
4023 extern const struct address_space_operations ext2_aops;
4024 extern const struct address_space_operations ext2_aops_xip;
4025 extern const struct address_space_operations ext2_nobh_aops;
4026 +extern int ext2_sync_flags(struct inode *inode);
4029 extern struct inode_operations ext2_dir_inode_operations;
4030 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/file.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/file.c
4031 --- linux-2.6.19.1/fs/ext2/file.c 2006-11-30 21:19:19 +0100
4032 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/file.c 2006-11-08 04:57:51 +0100
4033 @@ -54,6 +54,7 @@ const struct file_operations ext2_file_o
4034 .release = ext2_release_file,
4035 .fsync = ext2_sync_file,
4036 .sendfile = generic_file_sendfile,
4037 + .sendpage = generic_file_sendpage,
4038 .splice_read = generic_file_splice_read,
4039 .splice_write = generic_file_splice_write,
4041 @@ -85,4 +86,5 @@ struct inode_operations ext2_file_inode_
4043 .setattr = ext2_setattr,
4044 .permission = ext2_permission,
4045 + .sync_flags = ext2_sync_flags,
4047 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/ialloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/ialloc.c
4048 --- linux-2.6.19.1/fs/ext2/ialloc.c 2006-11-30 21:19:19 +0100
4049 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/ialloc.c 2006-11-08 04:57:50 +0100
4051 #include <linux/backing-dev.h>
4052 #include <linux/buffer_head.h>
4053 #include <linux/random.h>
4054 +#include <linux/vs_dlimit.h>
4055 +#include <linux/vs_tag.h>
4059 @@ -125,6 +127,7 @@ void ext2_free_inode (struct inode * ino
4060 ext2_xattr_delete_inode(inode);
4061 DQUOT_FREE_INODE(inode);
4063 + DLIMIT_FREE_INODE(inode);
4066 es = EXT2_SB(sb)->s_es;
4067 @@ -464,6 +467,11 @@ struct inode *ext2_new_inode(struct inod
4069 return ERR_PTR(-ENOMEM);
4071 + inode->i_tag = dx_current_fstag(sb);
4072 + if (DLIMIT_ALLOC_INODE(inode)) {
4079 @@ -577,7 +585,8 @@ got:
4080 inode->i_blocks = 0;
4081 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
4082 memset(ei->i_data, 0, sizeof(ei->i_data));
4083 - ei->i_flags = EXT2_I(dir)->i_flags & ~EXT2_BTREE_FL;
4084 + ei->i_flags = EXT2_I(dir)->i_flags &
4085 + ~(EXT2_BTREE_FL|EXT2_IUNLINK_FL|EXT2_BARRIER_FL);
4087 ei->i_flags &= ~(EXT2_IMMUTABLE_FL|EXT2_APPEND_FL);
4088 /* dirsync is only applied to directories */
4089 @@ -625,12 +634,15 @@ fail_free_drop:
4093 + DLIMIT_FREE_INODE(inode);
4094 inode->i_flags |= S_NOQUOTA;
4097 return ERR_PTR(err);
4100 + DLIMIT_FREE_INODE(inode);
4102 make_bad_inode(inode);
4104 return ERR_PTR(err);
4105 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/inode.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/inode.c
4106 --- linux-2.6.19.1/fs/ext2/inode.c 2006-11-30 21:19:19 +0100
4107 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/inode.c 2006-11-30 18:53:18 +0100
4109 #include <linux/writeback.h>
4110 #include <linux/buffer_head.h>
4111 #include <linux/mpage.h>
4112 +#include <linux/vs_tag.h>
4116 @@ -913,7 +914,7 @@ void ext2_truncate (struct inode * inode
4118 if (ext2_inode_is_fast_symlink(inode))
4120 - if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
4121 + if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
4124 ext2_discard_prealloc(inode);
4125 @@ -1042,25 +1043,70 @@ void ext2_set_inode_flags(struct inode *
4127 unsigned int flags = EXT2_I(inode)->i_flags;
4129 - inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
4130 + inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
4131 + S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
4133 + if (flags & EXT2_IMMUTABLE_FL)
4134 + inode->i_flags |= S_IMMUTABLE;
4135 + if (flags & EXT2_IUNLINK_FL)
4136 + inode->i_flags |= S_IUNLINK;
4137 + if (flags & EXT2_BARRIER_FL)
4138 + inode->i_flags |= S_BARRIER;
4140 if (flags & EXT2_SYNC_FL)
4141 inode->i_flags |= S_SYNC;
4142 if (flags & EXT2_APPEND_FL)
4143 inode->i_flags |= S_APPEND;
4144 - if (flags & EXT2_IMMUTABLE_FL)
4145 - inode->i_flags |= S_IMMUTABLE;
4146 if (flags & EXT2_NOATIME_FL)
4147 inode->i_flags |= S_NOATIME;
4148 if (flags & EXT2_DIRSYNC_FL)
4149 inode->i_flags |= S_DIRSYNC;
4152 +int ext2_sync_flags(struct inode *inode)
4154 + unsigned int oldflags, newflags;
4156 + oldflags = EXT2_I(inode)->i_flags;
4157 + newflags = oldflags & ~(EXT2_APPEND_FL |
4158 + EXT2_IMMUTABLE_FL | EXT2_IUNLINK_FL |
4159 + EXT2_BARRIER_FL | EXT2_NOATIME_FL |
4160 + EXT2_SYNC_FL | EXT2_DIRSYNC_FL);
4162 + if (IS_APPEND(inode))
4163 + newflags |= EXT2_APPEND_FL;
4164 + if (IS_IMMUTABLE(inode))
4165 + newflags |= EXT2_IMMUTABLE_FL;
4166 + if (IS_IUNLINK(inode))
4167 + newflags |= EXT2_IUNLINK_FL;
4168 + if (IS_BARRIER(inode))
4169 + newflags |= EXT2_BARRIER_FL;
4171 + /* we do not want to copy superblock flags */
4172 + if (inode->i_flags & S_NOATIME)
4173 + newflags |= EXT2_NOATIME_FL;
4174 + if (inode->i_flags & S_SYNC)
4175 + newflags |= EXT2_SYNC_FL;
4176 + if (inode->i_flags & S_DIRSYNC)
4177 + newflags |= EXT2_DIRSYNC_FL;
4179 + if (oldflags ^ newflags) {
4180 + EXT2_I(inode)->i_flags = newflags;
4181 + inode->i_ctime = CURRENT_TIME;
4182 + mark_inode_dirty(inode);
4188 void ext2_read_inode (struct inode * inode)
4190 struct ext2_inode_info *ei = EXT2_I(inode);
4191 ino_t ino = inode->i_ino;
4192 struct buffer_head * bh;
4193 struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
4198 #ifdef CONFIG_EXT2_FS_POSIX_ACL
4199 @@ -1071,12 +1117,17 @@ void ext2_read_inode (struct inode * ino
4202 inode->i_mode = le16_to_cpu(raw_inode->i_mode);
4203 - inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4204 - inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4205 + uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4206 + gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4207 if (!(test_opt (inode->i_sb, NO_UID32))) {
4208 - inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
4209 - inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
4210 + uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
4211 + gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
4213 + inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
4214 + inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
4215 + inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
4216 + le16_to_cpu(raw_inode->i_raw_tag));
4218 inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
4219 inode->i_size = le32_to_cpu(raw_inode->i_size);
4220 inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
4221 @@ -1173,8 +1224,8 @@ static int ext2_update_inode(struct inod
4222 struct ext2_inode_info *ei = EXT2_I(inode);
4223 struct super_block *sb = inode->i_sb;
4224 ino_t ino = inode->i_ino;
4225 - uid_t uid = inode->i_uid;
4226 - gid_t gid = inode->i_gid;
4227 + uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
4228 + gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
4229 struct buffer_head * bh;
4230 struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
4232 @@ -1209,6 +1260,9 @@ static int ext2_update_inode(struct inod
4233 raw_inode->i_uid_high = 0;
4234 raw_inode->i_gid_high = 0;
4236 +#ifdef CONFIG_TAGGING_INTERN
4237 + raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
4239 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
4240 raw_inode->i_size = cpu_to_le32(inode->i_size);
4241 raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
4242 @@ -1295,7 +1349,8 @@ int ext2_setattr(struct dentry *dentry,
4245 if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
4246 - (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
4247 + (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) ||
4248 + (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) {
4249 error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0;
4252 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/ioctl.c
4253 --- linux-2.6.19.1/fs/ext2/ioctl.c 2006-11-30 21:19:19 +0100
4254 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/ioctl.c 2006-11-08 04:57:52 +0100
4256 #include <linux/sched.h>
4257 #include <linux/compat.h>
4258 #include <linux/smp_lock.h>
4259 +#include <linux/mount.h>
4260 #include <asm/current.h>
4261 #include <asm/uaccess.h>
4263 @@ -32,7 +33,8 @@ int ext2_ioctl (struct inode * inode, st
4264 case EXT2_IOC_SETFLAGS: {
4265 unsigned int oldflags;
4267 - if (IS_RDONLY(inode))
4268 + if (IS_RDONLY(inode) ||
4269 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4272 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4273 @@ -52,7 +54,9 @@ int ext2_ioctl (struct inode * inode, st
4275 * This test looks nicer. Thanks to Pauline Middelink
4277 - if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
4278 + if ((oldflags & EXT2_IMMUTABLE_FL) ||
4279 + ((flags ^ oldflags) & (EXT2_APPEND_FL |
4280 + EXT2_IMMUTABLE_FL | EXT2_IUNLINK_FL))) {
4281 if (!capable(CAP_LINUX_IMMUTABLE))
4284 @@ -71,7 +75,8 @@ int ext2_ioctl (struct inode * inode, st
4285 case EXT2_IOC_SETVERSION:
4286 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4288 - if (IS_RDONLY(inode))
4289 + if (IS_RDONLY(inode) ||
4290 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4292 if (get_user(inode->i_generation, (int __user *) arg))
4294 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/namei.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/namei.c
4295 --- linux-2.6.19.1/fs/ext2/namei.c 2006-11-30 21:19:19 +0100
4296 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/namei.c 2006-11-30 18:53:18 +0100
4300 #include <linux/pagemap.h>
4301 +#include <linux/vs_tag.h>
4305 @@ -66,6 +67,7 @@ static struct dentry *ext2_lookup(struct
4306 inode = iget(dir->i_sb, ino);
4308 return ERR_PTR(-EACCES);
4309 + dx_propagate_tag(nd, inode);
4311 return d_splice_alias(inode, dentry);
4313 @@ -391,6 +393,7 @@ struct inode_operations ext2_dir_inode_o
4315 .setattr = ext2_setattr,
4316 .permission = ext2_permission,
4317 + .sync_flags = ext2_sync_flags,
4320 struct inode_operations ext2_special_inode_operations = {
4321 @@ -402,4 +405,5 @@ struct inode_operations ext2_special_ino
4323 .setattr = ext2_setattr,
4324 .permission = ext2_permission,
4325 + .sync_flags = ext2_sync_flags,
4327 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/super.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/super.c
4328 --- linux-2.6.19.1/fs/ext2/super.c 2006-11-30 21:19:19 +0100
4329 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/super.c 2006-11-08 04:57:51 +0100
4330 @@ -227,8 +227,8 @@ static int ext2_show_options(struct seq_
4334 -static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off);
4335 -static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off);
4336 +static ssize_t ext2_quota_read(struct dqhash *hash, int type, char *data, size_t len, loff_t off);
4337 +static ssize_t ext2_quota_write(struct dqhash *hash, int type, const char *data, size_t len, loff_t off);
4340 static struct super_operations ext2_sops = {
4341 @@ -324,7 +324,7 @@ enum {
4342 Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
4343 Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
4344 Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
4345 - Opt_usrquota, Opt_grpquota
4346 + Opt_usrquota, Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid
4349 static match_table_t tokens = {
4350 @@ -352,6 +352,10 @@ static match_table_t tokens = {
4352 {Opt_noacl, "noacl"},
4355 + {Opt_notag, "notag"},
4356 + {Opt_tagid, "tagid=%u"},
4357 + {Opt_tag, "tagxid"},
4358 {Opt_grpquota, "grpquota"},
4359 {Opt_ignore, "noquota"},
4360 {Opt_quota, "quota"},
4361 @@ -420,6 +424,20 @@ static int parse_options (char * options
4363 set_opt (sbi->s_mount_opt, NO_UID32);
4365 +#ifndef CONFIG_TAGGING_NONE
4367 + set_opt (sbi->s_mount_opt, TAGGED);
4370 + clear_opt (sbi->s_mount_opt, TAGGED);
4373 +#ifdef CONFIG_PROPAGATE
4376 + set_opt (sbi->s_mount_opt, TAGGED);
4380 clear_opt (sbi->s_mount_opt, CHECK);
4382 @@ -728,6 +746,8 @@ static int ext2_fill_super(struct super_
4383 if (!parse_options ((char *) data, sbi))
4386 + if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED)
4387 + sb->s_flags |= MS_TAGGED;
4388 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
4389 ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
4391 @@ -1036,6 +1056,13 @@ static int ext2_remount (struct super_bl
4395 + if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) &&
4396 + !(sb->s_flags & MS_TAGGED)) {
4397 + printk("EXT2-fs: %s: tagging not permitted on remount.\n",
4402 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
4403 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
4405 @@ -1148,10 +1175,11 @@ static int ext2_get_sb(struct file_syste
4406 * acquiring the locks... As quota files are never truncated and quota code
4407 * itself serializes the operations (and noone else should touch the files)
4408 * we don't have to be afraid of races */
4409 -static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data,
4410 +static ssize_t ext2_quota_read(struct dqhash *hash, int type, char *data,
4411 size_t len, loff_t off)
4413 - struct inode *inode = sb_dqopt(sb)->files[type];
4414 + struct inode *inode = dqh_dqopt(hash)->files[type];
4415 + struct super_block *sb = hash->dqh_sb;
4416 sector_t blk = off >> EXT2_BLOCK_SIZE_BITS(sb);
4418 int offset = off & (sb->s_blocksize - 1);
4419 @@ -1192,10 +1220,11 @@ static ssize_t ext2_quota_read(struct su
4422 /* Write to quotafile */
4423 -static ssize_t ext2_quota_write(struct super_block *sb, int type,
4424 +static ssize_t ext2_quota_write(struct dqhash *hash, int type,
4425 const char *data, size_t len, loff_t off)
4427 - struct inode *inode = sb_dqopt(sb)->files[type];
4428 + struct inode *inode = dqh_dqopt(hash)->files[type];
4429 + struct super_block *sb = hash->dqh_sb;
4430 sector_t blk = off >> EXT2_BLOCK_SIZE_BITS(sb);
4432 int offset = off & (sb->s_blocksize - 1);
4433 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/symlink.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/symlink.c
4434 --- linux-2.6.19.1/fs/ext2/symlink.c 2005-08-29 22:25:30 +0200
4435 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/symlink.c 2006-11-08 04:57:46 +0100
4436 @@ -38,6 +38,7 @@ struct inode_operations ext2_symlink_ino
4437 .listxattr = ext2_listxattr,
4438 .removexattr = generic_removexattr,
4440 + .sync_flags = ext2_sync_flags,
4443 struct inode_operations ext2_fast_symlink_inode_operations = {
4444 @@ -49,4 +50,5 @@ struct inode_operations ext2_fast_symlin
4445 .listxattr = ext2_listxattr,
4446 .removexattr = generic_removexattr,
4448 + .sync_flags = ext2_sync_flags,
4450 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/xattr.c
4451 --- linux-2.6.19.1/fs/ext2/xattr.c 2006-11-30 21:19:19 +0100
4452 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/xattr.c 2006-11-08 04:57:50 +0100
4454 #include <linux/mbcache.h>
4455 #include <linux/quotaops.h>
4456 #include <linux/rwsem.h>
4457 +#include <linux/vs_dlimit.h>
4461 @@ -644,8 +645,12 @@ ext2_xattr_set2(struct inode *inode, str
4463 ea_bdebug(new_bh, "reusing block");
4466 + if (DLIMIT_ALLOC_BLOCK(inode, 1))
4469 if (DQUOT_ALLOC_BLOCK(inode, 1)) {
4470 + DLIMIT_FREE_BLOCK(inode, 1);
4471 unlock_buffer(new_bh);
4474 @@ -739,6 +744,7 @@ ext2_xattr_set2(struct inode *inode, str
4475 le32_to_cpu(HDR(old_bh)->h_refcount) - 1);
4477 mb_cache_entry_release(ce);
4478 + DLIMIT_FREE_BLOCK(inode, 1);
4479 DQUOT_FREE_BLOCK(inode, 1);
4480 mark_buffer_dirty(old_bh);
4481 ea_bdebug(old_bh, "refcount now=%d",
4482 @@ -803,6 +809,7 @@ ext2_xattr_delete_inode(struct inode *in
4483 mark_buffer_dirty(bh);
4485 sync_dirty_buffer(bh);
4486 + DLIMIT_FREE_BLOCK(inode, 1);
4487 DQUOT_FREE_BLOCK(inode, 1);
4489 EXT2_I(inode)->i_file_acl = 0;
4490 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/balloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/balloc.c
4491 --- linux-2.6.19.1/fs/ext3/balloc.c 2006-11-30 21:19:19 +0100
4492 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/balloc.c 2006-12-01 23:41:10 +0100
4494 #include <linux/ext3_jbd.h>
4495 #include <linux/quotaops.h>
4496 #include <linux/buffer_head.h>
4497 +#include <linux/vs_dlimit.h>
4498 +#include <linux/vs_tag.h>
4501 * balloc.c contains the blocks allocation and deallocation routines
4502 @@ -613,8 +615,10 @@ void ext3_free_blocks(handle_t *handle,
4505 ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
4506 - if (dquot_freed_blocks)
4507 + if (dquot_freed_blocks) {
4508 + DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks);
4509 DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
4514 @@ -1349,18 +1353,33 @@ out:
4516 * Check if filesystem has at least 1 free block available for allocation.
4518 -static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
4519 +static int ext3_has_free_blocks(struct super_block *sb)
4521 - ext3_fsblk_t free_blocks, root_blocks;
4522 + struct ext3_sb_info *sbi = EXT3_SB(sb);
4523 + unsigned long long free_blocks, root_blocks;
4526 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
4527 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
4528 - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
4530 + vxdprintk(VXD_CBIT(dlim, 3),
4531 + "ext3_has_free_blocks(%p): free=%llu, root=%llu",
4532 + sb, free_blocks, root_blocks);
4534 + DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
4536 + cond = (free_blocks < root_blocks + 1 &&
4537 + !capable(CAP_SYS_RESOURCE) &&
4538 sbi->s_resuid != current->fsuid &&
4539 - (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
4543 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
4545 + vxdprintk(VXD_CBIT(dlim, 3),
4546 + "ext3_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
4547 + sb, free_blocks, root_blocks,
4548 + !capable(CAP_SYS_RESOURCE)?'1':'0',
4549 + sbi->s_resuid, current->fsuid, cond?0:1);
4551 + return (cond ? 0 : 1);
4555 @@ -1377,7 +1396,7 @@ static int ext3_has_free_blocks(struct e
4557 int ext3_should_retry_alloc(struct super_block *sb, int *retries)
4559 - if (!ext3_has_free_blocks(EXT3_SB(sb)) || (*retries)++ > 3)
4560 + if (!ext3_has_free_blocks(sb) || (*retries)++ > 3)
4563 jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
4564 @@ -1440,6 +1459,8 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h
4568 + if (DLIMIT_ALLOC_BLOCK(inode, 1))
4572 es = EXT3_SB(sb)->s_es;
4573 @@ -1456,7 +1477,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h
4574 if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
4575 my_rsv = &block_i->rsv_window_node;
4577 - if (!ext3_has_free_blocks(sbi)) {
4578 + if (!ext3_has_free_blocks(sb)) {
4582 @@ -1650,6 +1671,9 @@ allocated:
4586 + if (!performed_allocation)
4587 + DLIMIT_FREE_BLOCK(inode, 1);
4591 ext3_std_error(sb, fatal);
4592 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/file.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/file.c
4593 --- linux-2.6.19.1/fs/ext3/file.c 2006-11-30 21:19:19 +0100
4594 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/file.c 2006-11-08 04:57:51 +0100
4595 @@ -121,6 +121,7 @@ const struct file_operations ext3_file_o
4596 .release = ext3_release_file,
4597 .fsync = ext3_sync_file,
4598 .sendfile = generic_file_sendfile,
4599 + .sendpage = generic_file_sendpage,
4600 .splice_read = generic_file_splice_read,
4601 .splice_write = generic_file_splice_write,
4603 @@ -135,5 +136,6 @@ struct inode_operations ext3_file_inode_
4604 .removexattr = generic_removexattr,
4606 .permission = ext3_permission,
4607 + .sync_flags = ext3_sync_flags,
4610 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/ialloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/ialloc.c
4611 --- linux-2.6.19.1/fs/ext3/ialloc.c 2006-11-30 21:19:19 +0100
4612 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/ialloc.c 2006-11-08 04:57:50 +0100
4614 #include <linux/buffer_head.h>
4615 #include <linux/random.h>
4616 #include <linux/bitops.h>
4617 +#include <linux/vs_dlimit.h>
4618 +#include <linux/vs_tag.h>
4620 #include <asm/byteorder.h>
4622 @@ -127,6 +129,7 @@ void ext3_free_inode (handle_t *handle,
4623 ext3_xattr_delete_inode(handle, inode);
4624 DQUOT_FREE_INODE(inode);
4626 + DLIMIT_FREE_INODE(inode);
4628 is_directory = S_ISDIR(inode->i_mode);
4630 @@ -445,6 +448,12 @@ struct inode *ext3_new_inode(handle_t *h
4631 inode = new_inode(sb);
4633 return ERR_PTR(-ENOMEM);
4635 + inode->i_tag = dx_current_fstag(sb);
4636 + if (DLIMIT_ALLOC_INODE(inode)) {
4643 @@ -566,7 +575,8 @@ got:
4644 ei->i_dir_start_lookup = 0;
4647 - ei->i_flags = EXT3_I(dir)->i_flags & ~EXT3_INDEX_FL;
4648 + ei->i_flags = EXT3_I(dir)->i_flags &
4649 + ~(EXT3_INDEX_FL|EXT3_IUNLINK_FL|EXT3_BARRIER_FL);
4651 ei->i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
4652 /* dirsync only applies to directories */
4653 @@ -621,6 +631,8 @@ got:
4655 ext3_std_error(sb, err);
4657 + DLIMIT_FREE_INODE(inode);
4662 @@ -632,6 +644,7 @@ fail_free_drop:
4666 + DLIMIT_FREE_INODE(inode);
4667 inode->i_flags |= S_NOQUOTA;
4670 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/inode.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/inode.c
4671 --- linux-2.6.19.1/fs/ext3/inode.c 2006-11-30 21:19:19 +0100
4672 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/inode.c 2006-11-30 19:02:16 +0100
4674 #include <linux/mpage.h>
4675 #include <linux/uio.h>
4676 #include <linux/bio.h>
4677 +#include <linux/vs_tag.h>
4681 @@ -2246,7 +2247,7 @@ void ext3_truncate(struct inode *inode)
4683 if (ext3_inode_is_fast_symlink(inode))
4685 - if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
4686 + if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
4690 @@ -2568,19 +2569,77 @@ void ext3_set_inode_flags(struct inode *
4692 unsigned int flags = EXT3_I(inode)->i_flags;
4694 - inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
4695 + inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
4696 + S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
4698 + if (flags & EXT3_IMMUTABLE_FL)
4699 + inode->i_flags |= S_IMMUTABLE;
4700 + if (flags & EXT3_IUNLINK_FL)
4701 + inode->i_flags |= S_IUNLINK;
4702 + if (flags & EXT3_BARRIER_FL)
4703 + inode->i_flags |= S_BARRIER;
4705 if (flags & EXT3_SYNC_FL)
4706 inode->i_flags |= S_SYNC;
4707 if (flags & EXT3_APPEND_FL)
4708 inode->i_flags |= S_APPEND;
4709 - if (flags & EXT3_IMMUTABLE_FL)
4710 - inode->i_flags |= S_IMMUTABLE;
4711 if (flags & EXT3_NOATIME_FL)
4712 inode->i_flags |= S_NOATIME;
4713 if (flags & EXT3_DIRSYNC_FL)
4714 inode->i_flags |= S_DIRSYNC;
4717 +int ext3_sync_flags(struct inode *inode)
4719 + unsigned int oldflags, newflags;
4722 + oldflags = EXT3_I(inode)->i_flags;
4723 + newflags = oldflags & ~(EXT3_APPEND_FL |
4724 + EXT3_IMMUTABLE_FL | EXT3_IUNLINK_FL |
4725 + EXT3_BARRIER_FL | EXT3_NOATIME_FL |
4726 + EXT3_SYNC_FL | EXT3_DIRSYNC_FL);
4728 + if (IS_APPEND(inode))
4729 + newflags |= EXT3_APPEND_FL;
4730 + if (IS_IMMUTABLE(inode))
4731 + newflags |= EXT3_IMMUTABLE_FL;
4732 + if (IS_IUNLINK(inode))
4733 + newflags |= EXT3_IUNLINK_FL;
4734 + if (IS_BARRIER(inode))
4735 + newflags |= EXT3_BARRIER_FL;
4737 + /* we do not want to copy superblock flags */
4738 + if (inode->i_flags & S_NOATIME)
4739 + newflags |= EXT3_NOATIME_FL;
4740 + if (inode->i_flags & S_SYNC)
4741 + newflags |= EXT3_SYNC_FL;
4742 + if (inode->i_flags & S_DIRSYNC)
4743 + newflags |= EXT3_DIRSYNC_FL;
4745 + if (oldflags ^ newflags) {
4747 + struct ext3_iloc iloc;
4749 + handle = ext3_journal_start(inode, 1);
4750 + if (IS_ERR(handle))
4751 + return PTR_ERR(handle);
4752 + if (IS_SYNC(inode))
4753 + handle->h_sync = 1;
4754 + err = ext3_reserve_inode_write(handle, inode, &iloc);
4758 + EXT3_I(inode)->i_flags = newflags;
4759 + inode->i_ctime = CURRENT_TIME;
4761 + err = ext3_mark_iloc_dirty(handle, inode, &iloc);
4763 + ext3_journal_stop(handle);
4768 void ext3_read_inode(struct inode * inode)
4770 struct ext3_iloc iloc;
4771 @@ -2588,6 +2647,8 @@ void ext3_read_inode(struct inode * inod
4772 struct ext3_inode_info *ei = EXT3_I(inode);
4773 struct buffer_head *bh;
4778 #ifdef CONFIG_EXT3_FS_POSIX_ACL
4779 ei->i_acl = EXT3_ACL_NOT_CACHED;
4780 @@ -2600,12 +2661,17 @@ void ext3_read_inode(struct inode * inod
4782 raw_inode = ext3_raw_inode(&iloc);
4783 inode->i_mode = le16_to_cpu(raw_inode->i_mode);
4784 - inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4785 - inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4786 + uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4787 + gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4788 if(!(test_opt (inode->i_sb, NO_UID32))) {
4789 - inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
4790 - inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
4791 + uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
4792 + gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
4794 + inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
4795 + inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
4796 + inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
4797 + le16_to_cpu(raw_inode->i_raw_tag));
4799 inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
4800 inode->i_size = le32_to_cpu(raw_inode->i_size);
4801 inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
4802 @@ -2729,6 +2795,8 @@ static int ext3_do_update_inode(handle_t
4803 struct ext3_inode *raw_inode = ext3_raw_inode(iloc);
4804 struct ext3_inode_info *ei = EXT3_I(inode);
4805 struct buffer_head *bh = iloc->bh;
4806 + uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
4807 + gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
4808 int err = 0, rc, block;
4810 /* For fields not not tracking in the in-memory inode,
4811 @@ -2738,29 +2806,32 @@ static int ext3_do_update_inode(handle_t
4813 raw_inode->i_mode = cpu_to_le16(inode->i_mode);
4814 if(!(test_opt(inode->i_sb, NO_UID32))) {
4815 - raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
4816 - raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
4817 + raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
4818 + raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid));
4820 * Fix up interoperability with old kernels. Otherwise, old inodes get
4821 * re-used with the upper 16 bits of the uid/gid intact
4824 raw_inode->i_uid_high =
4825 - cpu_to_le16(high_16_bits(inode->i_uid));
4826 + cpu_to_le16(high_16_bits(uid));
4827 raw_inode->i_gid_high =
4828 - cpu_to_le16(high_16_bits(inode->i_gid));
4829 + cpu_to_le16(high_16_bits(gid));
4831 raw_inode->i_uid_high = 0;
4832 raw_inode->i_gid_high = 0;
4835 raw_inode->i_uid_low =
4836 - cpu_to_le16(fs_high2lowuid(inode->i_uid));
4837 + cpu_to_le16(fs_high2lowuid(uid));
4838 raw_inode->i_gid_low =
4839 - cpu_to_le16(fs_high2lowgid(inode->i_gid));
4840 + cpu_to_le16(fs_high2lowgid(gid));
4841 raw_inode->i_uid_high = 0;
4842 raw_inode->i_gid_high = 0;
4844 +#ifdef CONFIG_TAGGING_INTERN
4845 + raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
4847 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
4848 raw_inode->i_size = cpu_to_le32(ei->i_disksize);
4849 raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
4850 @@ -2913,7 +2984,8 @@ int ext3_setattr(struct dentry *dentry,
4853 if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
4854 - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
4855 + (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
4856 + (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
4859 /* (user+group)*(old+new) structure, inode write (sb,
4860 @@ -2935,6 +3007,8 @@ int ext3_setattr(struct dentry *dentry,
4861 inode->i_uid = attr->ia_uid;
4862 if (attr->ia_valid & ATTR_GID)
4863 inode->i_gid = attr->ia_gid;
4864 + if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
4865 + inode->i_tag = attr->ia_tag;
4866 error = ext3_mark_inode_dirty(handle, inode);
4867 ext3_journal_stop(handle);
4869 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/ioctl.c
4870 --- linux-2.6.19.1/fs/ext3/ioctl.c 2006-11-30 21:19:19 +0100
4871 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/ioctl.c 2006-12-17 04:30:46 +0100
4875 #include <linux/fs.h>
4876 +#include <linux/mount.h>
4877 #include <linux/jbd.h>
4878 #include <linux/capability.h>
4879 #include <linux/ext3_fs.h>
4881 #include <linux/time.h>
4882 #include <linux/compat.h>
4883 #include <linux/smp_lock.h>
4884 +#include <linux/vs_tag.h>
4885 #include <asm/uaccess.h>
4887 int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
4888 @@ -37,7 +39,8 @@ int ext3_ioctl (struct inode * inode, st
4889 unsigned int oldflags;
4892 - if (IS_RDONLY(inode))
4893 + if (IS_RDONLY(inode) ||
4894 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4897 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4898 @@ -61,7 +64,9 @@ int ext3_ioctl (struct inode * inode, st
4900 * This test looks nicer. Thanks to Pauline Middelink
4902 - if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
4903 + if ((oldflags & EXT3_IMMUTABLE_FL) ||
4904 + ((flags ^ oldflags) & (EXT3_APPEND_FL |
4905 + EXT3_IMMUTABLE_FL | EXT3_IUNLINK_FL))) {
4906 if (!capable(CAP_LINUX_IMMUTABLE)) {
4907 mutex_unlock(&inode->i_mutex);
4909 @@ -123,7 +128,8 @@ flags_err:
4911 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4913 - if (IS_RDONLY(inode))
4914 + if (IS_RDONLY(inode) ||
4915 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4917 if (get_user(generation, (int __user *) arg))
4919 @@ -177,7 +183,8 @@ flags_err:
4920 if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
4923 - if (IS_RDONLY(inode))
4924 + if (IS_RDONLY(inode) ||
4925 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4928 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4929 @@ -212,7 +219,8 @@ flags_err:
4930 if (!capable(CAP_SYS_RESOURCE))
4933 - if (IS_RDONLY(inode))
4934 + if (IS_RDONLY(inode) ||
4935 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4938 if (get_user(n_blocks_count, (__u32 __user *)arg))
4939 @@ -233,7 +241,8 @@ flags_err:
4940 if (!capable(CAP_SYS_RESOURCE))
4943 - if (IS_RDONLY(inode))
4944 + if (IS_RDONLY(inode) ||
4945 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4948 if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg,
4949 @@ -247,8 +256,6 @@ flags_err:
4958 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/namei.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/namei.c
4959 --- linux-2.6.19.1/fs/ext3/namei.c 2006-11-30 21:19:19 +0100
4960 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/namei.c 2006-11-30 18:53:18 +0100
4962 #include <linux/buffer_head.h>
4963 #include <linux/bio.h>
4964 #include <linux/smp_lock.h>
4965 +#include <linux/vs_tag.h>
4969 @@ -1010,6 +1011,7 @@ static struct dentry *ext3_lookup(struct
4972 return ERR_PTR(-EACCES);
4973 + dx_propagate_tag(nd, inode);
4975 return d_splice_alias(inode, dentry);
4977 @@ -2383,6 +2385,7 @@ struct inode_operations ext3_dir_inode_o
4978 .removexattr = generic_removexattr,
4980 .permission = ext3_permission,
4981 + .sync_flags = ext3_sync_flags,
4984 struct inode_operations ext3_special_inode_operations = {
4985 @@ -2394,4 +2397,5 @@ struct inode_operations ext3_special_ino
4986 .removexattr = generic_removexattr,
4988 .permission = ext3_permission,
4989 + .sync_flags = ext3_sync_flags,
4991 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/super.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/super.c
4992 --- linux-2.6.19.1/fs/ext3/super.c 2006-11-30 21:19:19 +0100
4993 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/super.c 2006-11-08 04:57:51 +0100
4994 @@ -605,12 +605,12 @@ static int ext3_write_dquot(struct dquot
4995 static int ext3_acquire_dquot(struct dquot *dquot);
4996 static int ext3_release_dquot(struct dquot *dquot);
4997 static int ext3_mark_dquot_dirty(struct dquot *dquot);
4998 -static int ext3_write_info(struct super_block *sb, int type);
4999 -static int ext3_quota_on(struct super_block *sb, int type, int format_id, char *path);
5000 -static int ext3_quota_on_mount(struct super_block *sb, int type);
5001 -static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
5002 +static int ext3_write_info(struct dqhash *hash, int type);
5003 +static int ext3_quota_on(struct dqhash *hash, int type, int format_id, char *path);
5004 +static int ext3_quota_on_mount(struct dqhash *hash, int type);
5005 +static ssize_t ext3_quota_read(struct dqhash *hash, int type, char *data,
5006 size_t len, loff_t off);
5007 -static ssize_t ext3_quota_write(struct super_block *sb, int type,
5008 +static ssize_t ext3_quota_write(struct dqhash *hash, int type,
5009 const char *data, size_t len, loff_t off);
5011 static struct dquot_operations ext3_quota_operations = {
5012 @@ -677,7 +677,7 @@ enum {
5013 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
5014 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
5015 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
5017 + Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid
5020 static match_table_t tokens = {
5021 @@ -727,6 +727,10 @@ static match_table_t tokens = {
5022 {Opt_quota, "quota"},
5023 {Opt_usrquota, "usrquota"},
5024 {Opt_barrier, "barrier=%u"},
5026 + {Opt_notag, "notag"},
5027 + {Opt_tagid, "tagid=%u"},
5028 + {Opt_tag, "tagxid"},
5030 {Opt_resize, "resize"},
5032 @@ -820,6 +824,20 @@ static int parse_options (char *options,
5034 set_opt (sbi->s_mount_opt, NO_UID32);
5036 +#ifndef CONFIG_TAGGING_NONE
5038 + set_opt (sbi->s_mount_opt, TAGGED);
5041 + clear_opt (sbi->s_mount_opt, TAGGED);
5044 +#ifdef CONFIG_PROPAGATE
5047 + set_opt (sbi->s_mount_opt, TAGGED);
5051 clear_opt (sbi->s_mount_opt, CHECK);
5053 @@ -938,7 +956,7 @@ static int parse_options (char *options,
5057 - if (sb_any_quota_enabled(sb)) {
5058 + if (dqh_any_quota_enabled(sb->s_dqh)) {
5060 "EXT3-fs: Cannot change journalled "
5061 "quota options when quota turned on.\n");
5062 @@ -976,7 +994,7 @@ set_qf_name:
5063 case Opt_offgrpjquota:
5066 - if (sb_any_quota_enabled(sb)) {
5067 + if (dqh_any_quota_enabled(sb->s_dqh)) {
5068 printk(KERN_ERR "EXT3-fs: Cannot change "
5069 "journalled quota options when "
5070 "quota turned on.\n");
5071 @@ -1004,7 +1022,7 @@ clear_qf_name:
5072 set_opt(sbi->s_mount_opt, GRPQUOTA);
5075 - if (sb_any_quota_enabled(sb)) {
5076 + if (dqh_any_quota_enabled(sb->s_dqh)) {
5077 printk(KERN_ERR "EXT3-fs: Cannot change quota "
5078 "options when quota turned on.\n");
5080 @@ -1284,7 +1302,7 @@ static void ext3_orphan_cleanup (struct
5081 /* Turn on quotas so that they are updated correctly */
5082 for (i = 0; i < MAXQUOTAS; i++) {
5083 if (EXT3_SB(sb)->s_qf_names[i]) {
5084 - int ret = ext3_quota_on_mount(sb, i);
5085 + int ret = ext3_quota_on_mount(sb->s_dqh, i);
5088 "EXT3-fs: Cannot turn on journalled "
5089 @@ -1334,8 +1352,8 @@ static void ext3_orphan_cleanup (struct
5091 /* Turn quotas off */
5092 for (i = 0; i < MAXQUOTAS; i++) {
5093 - if (sb_dqopt(sb)->files[i])
5094 - vfs_quota_off(sb, i);
5095 + if (dqh_dqopt(sb->s_dqh)->files[i])
5096 + vfs_quota_off(sb->s_dqh, i);
5099 sb->s_flags = s_flags; /* Restore MS_RDONLY status */
5100 @@ -1482,6 +1500,9 @@ static int ext3_fill_super (struct super
5104 + if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAGGED)
5105 + sb->s_flags |= MS_TAGGED;
5107 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
5108 ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
5110 @@ -1687,8 +1708,8 @@ static int ext3_fill_super (struct super
5111 sb->s_export_op = &ext3_export_ops;
5112 sb->s_xattr = ext3_xattr_handlers;
5114 - sb->s_qcop = &ext3_qctl_operations;
5115 - sb->dq_op = &ext3_quota_operations;
5116 + sb->s_dqh->dqh_qop = &ext3_quota_operations;
5117 + sb->s_dqh->dqh_qcop = &ext3_qctl_operations;
5119 INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
5121 @@ -2297,6 +2318,12 @@ static int ext3_remount (struct super_bl
5123 if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
5124 ext3_abort(sb, __FUNCTION__, "Abort forced by user");
5125 + if ((sbi->s_mount_opt & EXT3_MOUNT_TAGGED) &&
5126 + !(sb->s_flags & MS_TAGGED)) {
5127 + printk("EXT3-fs: %s: tagging not permitted on remount.\n",
5132 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
5133 ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
5134 @@ -2450,7 +2477,7 @@ static int ext3_statfs (struct dentry *
5136 static inline struct inode *dquot_to_inode(struct dquot *dquot)
5138 - return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
5139 + return dqh_dqopt(dquot->dq_dqh)->files[dquot->dq_type];
5142 static int ext3_dquot_initialize(struct inode *inode, int type)
5143 @@ -2493,7 +2520,7 @@ static int ext3_write_dquot(struct dquot
5145 inode = dquot_to_inode(dquot);
5146 handle = ext3_journal_start(inode,
5147 - EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
5148 + EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb));
5150 return PTR_ERR(handle);
5151 ret = dquot_commit(dquot);
5152 @@ -2509,7 +2536,7 @@ static int ext3_acquire_dquot(struct dqu
5155 handle = ext3_journal_start(dquot_to_inode(dquot),
5156 - EXT3_QUOTA_INIT_BLOCKS(dquot->dq_sb));
5157 + EXT3_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb));
5159 return PTR_ERR(handle);
5160 ret = dquot_acquire(dquot);
5161 @@ -2525,7 +2552,7 @@ static int ext3_release_dquot(struct dqu
5164 handle = ext3_journal_start(dquot_to_inode(dquot),
5165 - EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb));
5166 + EXT3_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb));
5168 return PTR_ERR(handle);
5169 ret = dquot_release(dquot);
5170 @@ -2538,8 +2565,8 @@ static int ext3_release_dquot(struct dqu
5171 static int ext3_mark_dquot_dirty(struct dquot *dquot)
5173 /* Are we journalling quotas? */
5174 - if (EXT3_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
5175 - EXT3_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
5176 + if (EXT3_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[USRQUOTA] ||
5177 + EXT3_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[GRPQUOTA]) {
5178 dquot_mark_dquot_dirty(dquot);
5179 return ext3_write_dquot(dquot);
5181 @@ -2547,8 +2574,9 @@ static int ext3_mark_dquot_dirty(struct
5185 -static int ext3_write_info(struct super_block *sb, int type)
5186 +static int ext3_write_info(struct dqhash *hash, int type)
5188 + struct super_block *sb = hash->dqh_sb;
5192 @@ -2556,7 +2584,7 @@ static int ext3_write_info(struct super_
5193 handle = ext3_journal_start(sb->s_root->d_inode, 2);
5195 return PTR_ERR(handle);
5196 - ret = dquot_commit_info(sb, type);
5197 + ret = dquot_commit_info(hash, type);
5198 err = ext3_journal_stop(handle);
5201 @@ -2567,18 +2595,20 @@ static int ext3_write_info(struct super_
5202 * Turn on quotas during mount time - we need to find
5203 * the quota file and such...
5205 -static int ext3_quota_on_mount(struct super_block *sb, int type)
5206 +static int ext3_quota_on_mount(struct dqhash *hash, int type)
5208 - return vfs_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type],
5209 - EXT3_SB(sb)->s_jquota_fmt, type);
5210 + return vfs_quota_on_mount(hash,
5211 + EXT3_SB(hash->dqh_sb)->s_qf_names[type],
5212 + EXT3_SB(hash->dqh_sb)->s_jquota_fmt, type);
5216 * Standard function to be called on quota_on
5218 -static int ext3_quota_on(struct super_block *sb, int type, int format_id,
5219 +static int ext3_quota_on(struct dqhash *hash, int type, int format_id,
5222 + struct super_block *sb = hash->dqh_sb;
5224 struct nameidata nd;
5226 @@ -2587,7 +2617,7 @@ static int ext3_quota_on(struct super_bl
5227 /* Not journalling quota? */
5228 if (!EXT3_SB(sb)->s_qf_names[USRQUOTA] &&
5229 !EXT3_SB(sb)->s_qf_names[GRPQUOTA])
5230 - return vfs_quota_on(sb, type, format_id, path);
5231 + return vfs_quota_on(hash, type, format_id, path);
5232 err = path_lookup(path, LOOKUP_FOLLOW, &nd);
5235 @@ -2602,17 +2632,18 @@ static int ext3_quota_on(struct super_bl
5236 "EXT3-fs: Quota file not on filesystem root. "
5237 "Journalled quota will not work.\n");
5239 - return vfs_quota_on(sb, type, format_id, path);
5240 + return vfs_quota_on(hash, type, format_id, path);
5243 /* Read data from quotafile - avoid pagecache and such because we cannot afford
5244 * acquiring the locks... As quota files are never truncated and quota code
5245 * itself serializes the operations (and noone else should touch the files)
5246 * we don't have to be afraid of races */
5247 -static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
5248 +static ssize_t ext3_quota_read(struct dqhash *hash, int type, char *data,
5249 size_t len, loff_t off)
5251 - struct inode *inode = sb_dqopt(sb)->files[type];
5252 + struct inode *inode = dqh_dqopt(hash)->files[type];
5253 + struct super_block *sb = hash->dqh_sb;
5254 sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
5256 int offset = off & (sb->s_blocksize - 1);
5257 @@ -2647,10 +2678,11 @@ static ssize_t ext3_quota_read(struct su
5259 /* Write to quotafile (we know the transaction is already started and has
5260 * enough credits) */
5261 -static ssize_t ext3_quota_write(struct super_block *sb, int type,
5262 +static ssize_t ext3_quota_write(struct dqhash *hash, int type,
5263 const char *data, size_t len, loff_t off)
5265 - struct inode *inode = sb_dqopt(sb)->files[type];
5266 + struct inode *inode = dqh_dqopt(hash)->files[type];
5267 + struct super_block *sb = hash->dqh_sb;
5268 sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
5270 int offset = off & (sb->s_blocksize - 1);
5271 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/symlink.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/symlink.c
5272 --- linux-2.6.19.1/fs/ext3/symlink.c 2005-08-29 22:25:30 +0200
5273 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/symlink.c 2006-11-08 04:57:46 +0100
5274 @@ -40,6 +40,7 @@ struct inode_operations ext3_symlink_ino
5275 .listxattr = ext3_listxattr,
5276 .removexattr = generic_removexattr,
5278 + .sync_flags = ext3_sync_flags,
5281 struct inode_operations ext3_fast_symlink_inode_operations = {
5282 @@ -51,4 +52,5 @@ struct inode_operations ext3_fast_symlin
5283 .listxattr = ext3_listxattr,
5284 .removexattr = generic_removexattr,
5286 + .sync_flags = ext3_sync_flags,
5288 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/xattr.c
5289 --- linux-2.6.19.1/fs/ext3/xattr.c 2006-11-30 21:19:19 +0100
5290 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/xattr.c 2006-11-08 04:57:50 +0100
5292 #include <linux/mbcache.h>
5293 #include <linux/quotaops.h>
5294 #include <linux/rwsem.h>
5295 +#include <linux/vs_dlimit.h>
5299 @@ -495,6 +496,7 @@ ext3_xattr_release_block(handle_t *handl
5300 ext3_journal_dirty_metadata(handle, bh);
5303 + DLIMIT_FREE_BLOCK(inode, 1);
5304 DQUOT_FREE_BLOCK(inode, 1);
5306 ea_bdebug(bh, "refcount now=%d; releasing",
5307 @@ -763,11 +765,14 @@ inserted:
5308 if (new_bh == bs->bh)
5309 ea_bdebug(new_bh, "keeping");
5312 + if (DLIMIT_ALLOC_BLOCK(inode, 1))
5314 /* The old block is released after updating
5317 if (DQUOT_ALLOC_BLOCK(inode, 1))
5319 + goto cleanup_dlimit;
5320 error = ext3_journal_get_write_access(handle,
5323 @@ -844,6 +849,8 @@ cleanup:
5326 DQUOT_FREE_BLOCK(inode, 1);
5328 + DLIMIT_FREE_BLOCK(inode, 1);
5332 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/balloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/balloc.c
5333 --- linux-2.6.19.1/fs/ext4/balloc.c 2006-11-30 21:19:19 +0100
5334 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/balloc.c 2006-12-02 01:51:51 +0100
5336 #include <linux/ext4_jbd2.h>
5337 #include <linux/quotaops.h>
5338 #include <linux/buffer_head.h>
5339 +#include <linux/vs_dlimit.h>
5340 +#include <linux/vs_tag.h>
5343 * balloc.c contains the blocks allocation and deallocation routines
5344 @@ -630,8 +632,10 @@ void ext4_free_blocks(handle_t *handle,
5347 ext4_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
5348 - if (dquot_freed_blocks)
5349 + if (dquot_freed_blocks) {
5350 + DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks);
5351 DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
5356 @@ -1366,18 +1370,33 @@ out:
5358 * Check if filesystem has at least 1 free block available for allocation.
5360 -static int ext4_has_free_blocks(struct ext4_sb_info *sbi)
5361 +static int ext4_has_free_blocks(struct super_block *sb)
5363 - ext4_fsblk_t free_blocks, root_blocks;
5364 + struct ext4_sb_info *sbi = EXT4_SB(sb);
5365 + ext4_fsblk_t free_blocks, root_blocks;
5368 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
5369 root_blocks = ext4_r_blocks_count(sbi->s_es);
5370 - if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
5372 + vxdprintk(VXD_CBIT(dlim, 3),
5373 + "ext4_has_free_blocks(%p): free=%llu, root=%llu",
5374 + sb, free_blocks, root_blocks);
5376 + DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
5378 + cond = (free_blocks < root_blocks + 1 &&
5379 + !capable(CAP_SYS_RESOURCE) &&
5380 sbi->s_resuid != current->fsuid &&
5381 - (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
5385 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
5387 + vxdprintk(VXD_CBIT(dlim, 3),
5388 + "ext4_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
5389 + sb, free_blocks, root_blocks,
5390 + !capable(CAP_SYS_RESOURCE)?'1':'0',
5391 + sbi->s_resuid, current->fsuid, cond?0:1);
5393 + return (cond ? 0 : 1);
5397 @@ -1394,7 +1413,7 @@ static int ext4_has_free_blocks(struct e
5399 int ext4_should_retry_alloc(struct super_block *sb, int *retries)
5401 - if (!ext4_has_free_blocks(EXT4_SB(sb)) || (*retries)++ > 3)
5402 + if (!ext4_has_free_blocks(sb) || (*retries)++ > 3)
5405 jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
5406 @@ -1457,6 +1476,8 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h
5410 + if (DLIMIT_ALLOC_BLOCK(inode, 1))
5414 es = EXT4_SB(sb)->s_es;
5415 @@ -1473,7 +1494,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h
5416 if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
5417 my_rsv = &block_i->rsv_window_node;
5419 - if (!ext4_has_free_blocks(sbi)) {
5420 + if (!ext4_has_free_blocks(sb)) {
5424 @@ -1664,6 +1685,9 @@ allocated:
5428 + if (!performed_allocation)
5429 + DLIMIT_FREE_BLOCK(inode, 1);
5433 ext4_std_error(sb, fatal);
5434 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/file.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/file.c
5435 --- linux-2.6.19.1/fs/ext4/file.c 2006-11-30 21:19:19 +0100
5436 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/file.c 2006-12-01 23:01:47 +0100
5437 @@ -121,6 +121,7 @@ const struct file_operations ext4_file_o
5438 .release = ext4_release_file,
5439 .fsync = ext4_sync_file,
5440 .sendfile = generic_file_sendfile,
5441 + .sendpage = generic_file_sendpage,
5442 .splice_read = generic_file_splice_read,
5443 .splice_write = generic_file_splice_write,
5445 @@ -135,5 +136,6 @@ struct inode_operations ext4_file_inode_
5446 .removexattr = generic_removexattr,
5448 .permission = ext4_permission,
5449 + .sync_flags = ext4_sync_flags,
5452 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/ialloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/ialloc.c
5453 --- linux-2.6.19.1/fs/ext4/ialloc.c 2006-11-30 21:19:20 +0100
5454 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/ialloc.c 2006-12-01 23:07:02 +0100
5456 #include <linux/random.h>
5457 #include <linux/bitops.h>
5458 #include <linux/blkdev.h>
5459 +#include <linux/vs_dlimit.h>
5460 +#include <linux/vs_tag.h>
5461 #include <asm/byteorder.h>
5464 @@ -127,6 +129,7 @@ void ext4_free_inode (handle_t *handle,
5465 ext4_xattr_delete_inode(handle, inode);
5466 DQUOT_FREE_INODE(inode);
5468 + DLIMIT_FREE_INODE(inode);
5470 is_directory = S_ISDIR(inode->i_mode);
5472 @@ -448,6 +451,12 @@ struct inode *ext4_new_inode(handle_t *h
5473 inode = new_inode(sb);
5475 return ERR_PTR(-ENOMEM);
5477 + inode->i_tag = dx_current_fstag(sb);
5478 + if (DLIMIT_ALLOC_INODE(inode)) {
5485 @@ -569,7 +578,8 @@ got:
5486 ei->i_dir_start_lookup = 0;
5489 - ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL;
5490 + ei->i_flags = EXT4_I(dir)->i_flags &
5491 + ~(EXT4_INDEX_FL|EXT4_IUNLINK_FL|EXT4_BARRIER_FL);
5493 ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL);
5494 /* dirsync only applies to directories */
5495 @@ -635,6 +645,8 @@ got:
5497 ext4_std_error(sb, err);
5499 + DLIMIT_FREE_INODE(inode);
5504 @@ -646,6 +658,7 @@ fail_free_drop:
5508 + DLIMIT_FREE_INODE(inode);
5509 inode->i_flags |= S_NOQUOTA;
5512 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/inode.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/inode.c
5513 --- linux-2.6.19.1/fs/ext4/inode.c 2006-11-30 21:19:20 +0100
5514 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/inode.c 2006-12-01 23:01:47 +0100
5516 #include <linux/mpage.h>
5517 #include <linux/uio.h>
5518 #include <linux/bio.h>
5519 +#include <linux/vs_tag.h>
5523 @@ -2245,7 +2246,7 @@ void ext4_truncate(struct inode *inode)
5525 if (ext4_inode_is_fast_symlink(inode))
5527 - if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
5528 + if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
5532 @@ -2571,19 +2572,77 @@ void ext4_set_inode_flags(struct inode *
5534 unsigned int flags = EXT4_I(inode)->i_flags;
5536 - inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
5537 + inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
5538 + S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
5540 + if (flags & EXT4_IMMUTABLE_FL)
5541 + inode->i_flags |= S_IMMUTABLE;
5542 + if (flags & EXT4_IUNLINK_FL)
5543 + inode->i_flags |= S_IUNLINK;
5544 + if (flags & EXT4_BARRIER_FL)
5545 + inode->i_flags |= S_BARRIER;
5547 if (flags & EXT4_SYNC_FL)
5548 inode->i_flags |= S_SYNC;
5549 if (flags & EXT4_APPEND_FL)
5550 inode->i_flags |= S_APPEND;
5551 - if (flags & EXT4_IMMUTABLE_FL)
5552 - inode->i_flags |= S_IMMUTABLE;
5553 if (flags & EXT4_NOATIME_FL)
5554 inode->i_flags |= S_NOATIME;
5555 if (flags & EXT4_DIRSYNC_FL)
5556 inode->i_flags |= S_DIRSYNC;
5559 +int ext4_sync_flags(struct inode *inode)
5561 + unsigned int oldflags, newflags;
5564 + oldflags = EXT4_I(inode)->i_flags;
5565 + newflags = oldflags & ~(EXT4_APPEND_FL |
5566 + EXT4_IMMUTABLE_FL | EXT4_IUNLINK_FL |
5567 + EXT4_BARRIER_FL | EXT4_NOATIME_FL |
5568 + EXT4_SYNC_FL | EXT4_DIRSYNC_FL);
5570 + if (IS_APPEND(inode))
5571 + newflags |= EXT4_APPEND_FL;
5572 + if (IS_IMMUTABLE(inode))
5573 + newflags |= EXT4_IMMUTABLE_FL;
5574 + if (IS_IUNLINK(inode))
5575 + newflags |= EXT4_IUNLINK_FL;
5576 + if (IS_BARRIER(inode))
5577 + newflags |= EXT4_BARRIER_FL;
5579 + /* we do not want to copy superblock flags */
5580 + if (inode->i_flags & S_NOATIME)
5581 + newflags |= EXT4_NOATIME_FL;
5582 + if (inode->i_flags & S_SYNC)
5583 + newflags |= EXT4_SYNC_FL;
5584 + if (inode->i_flags & S_DIRSYNC)
5585 + newflags |= EXT4_DIRSYNC_FL;
5587 + if (oldflags ^ newflags) {
5589 + struct ext4_iloc iloc;
5591 + handle = ext4_journal_start(inode, 1);
5592 + if (IS_ERR(handle))
5593 + return PTR_ERR(handle);
5594 + if (IS_SYNC(inode))
5595 + handle->h_sync = 1;
5596 + err = ext4_reserve_inode_write(handle, inode, &iloc);
5600 + EXT4_I(inode)->i_flags = newflags;
5601 + inode->i_ctime = CURRENT_TIME;
5603 + err = ext4_mark_iloc_dirty(handle, inode, &iloc);
5605 + ext4_journal_stop(handle);
5610 void ext4_read_inode(struct inode * inode)
5612 struct ext4_iloc iloc;
5613 @@ -2591,6 +2650,8 @@ void ext4_read_inode(struct inode * inod
5614 struct ext4_inode_info *ei = EXT4_I(inode);
5615 struct buffer_head *bh;
5620 #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
5621 ei->i_acl = EXT4_ACL_NOT_CACHED;
5622 @@ -2603,12 +2664,17 @@ void ext4_read_inode(struct inode * inod
5624 raw_inode = ext4_raw_inode(&iloc);
5625 inode->i_mode = le16_to_cpu(raw_inode->i_mode);
5626 - inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
5627 - inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
5628 + uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
5629 + gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
5630 if(!(test_opt (inode->i_sb, NO_UID32))) {
5631 - inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
5632 - inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
5633 + uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
5634 + gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
5636 + inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
5637 + inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
5638 + inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
5639 + le16_to_cpu(raw_inode->i_raw_tag));
5641 inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
5642 inode->i_size = le32_to_cpu(raw_inode->i_size);
5643 inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
5644 @@ -2736,6 +2802,8 @@ static int ext4_do_update_inode(handle_t
5645 struct ext4_inode *raw_inode = ext4_raw_inode(iloc);
5646 struct ext4_inode_info *ei = EXT4_I(inode);
5647 struct buffer_head *bh = iloc->bh;
5648 + uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
5649 + gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
5650 int err = 0, rc, block;
5652 /* For fields not not tracking in the in-memory inode,
5653 @@ -2745,29 +2813,32 @@ static int ext4_do_update_inode(handle_t
5655 raw_inode->i_mode = cpu_to_le16(inode->i_mode);
5656 if(!(test_opt(inode->i_sb, NO_UID32))) {
5657 - raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
5658 - raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
5659 + raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
5660 + raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid));
5662 * Fix up interoperability with old kernels. Otherwise, old inodes get
5663 * re-used with the upper 16 bits of the uid/gid intact
5666 raw_inode->i_uid_high =
5667 - cpu_to_le16(high_16_bits(inode->i_uid));
5668 + cpu_to_le16(high_16_bits(uid));
5669 raw_inode->i_gid_high =
5670 - cpu_to_le16(high_16_bits(inode->i_gid));
5671 + cpu_to_le16(high_16_bits(gid));
5673 raw_inode->i_uid_high = 0;
5674 raw_inode->i_gid_high = 0;
5677 raw_inode->i_uid_low =
5678 - cpu_to_le16(fs_high2lowuid(inode->i_uid));
5679 + cpu_to_le16(fs_high2lowuid(uid));
5680 raw_inode->i_gid_low =
5681 - cpu_to_le16(fs_high2lowgid(inode->i_gid));
5682 + cpu_to_le16(fs_high2lowgid(gid));
5683 raw_inode->i_uid_high = 0;
5684 raw_inode->i_gid_high = 0;
5686 +#ifdef CONFIG_TAGGING_INTERN
5687 + raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
5689 raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
5690 raw_inode->i_size = cpu_to_le32(ei->i_disksize);
5691 raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
5692 @@ -2924,7 +2995,8 @@ int ext4_setattr(struct dentry *dentry,
5695 if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
5696 - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
5697 + (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
5698 + (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
5701 /* (user+group)*(old+new) structure, inode write (sb,
5702 @@ -2946,6 +3018,8 @@ int ext4_setattr(struct dentry *dentry,
5703 inode->i_uid = attr->ia_uid;
5704 if (attr->ia_valid & ATTR_GID)
5705 inode->i_gid = attr->ia_gid;
5706 + if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
5707 + inode->i_tag = attr->ia_tag;
5708 error = ext4_mark_inode_dirty(handle, inode);
5709 ext4_journal_stop(handle);
5711 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/ioctl.c
5712 --- linux-2.6.19.1/fs/ext4/ioctl.c 2006-11-30 21:19:20 +0100
5713 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/ioctl.c 2006-12-17 04:31:01 +0100
5717 #include <linux/fs.h>
5718 +#include <linux/mount.h>
5719 #include <linux/jbd2.h>
5720 #include <linux/capability.h>
5721 #include <linux/ext4_fs.h>
5723 #include <linux/time.h>
5724 #include <linux/compat.h>
5725 #include <linux/smp_lock.h>
5726 +#include <linux/vs_tag.h>
5727 #include <asm/uaccess.h>
5729 int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
5730 @@ -37,7 +39,8 @@ int ext4_ioctl (struct inode * inode, st
5731 unsigned int oldflags;
5734 - if (IS_RDONLY(inode))
5735 + if (IS_RDONLY(inode) ||
5736 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5739 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
5740 @@ -61,7 +64,9 @@ int ext4_ioctl (struct inode * inode, st
5742 * This test looks nicer. Thanks to Pauline Middelink
5744 - if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
5745 + if ((oldflags & EXT4_IMMUTABLE_FL) ||
5746 + ((flags ^ oldflags) & (EXT4_APPEND_FL |
5747 + EXT4_IMMUTABLE_FL | EXT4_IUNLINK_FL))) {
5748 if (!capable(CAP_LINUX_IMMUTABLE)) {
5749 mutex_unlock(&inode->i_mutex);
5751 @@ -123,7 +128,8 @@ flags_err:
5753 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
5755 - if (IS_RDONLY(inode))
5756 + if (IS_RDONLY(inode) ||
5757 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5759 if (get_user(generation, (int __user *) arg))
5761 @@ -177,7 +183,8 @@ flags_err:
5762 if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
5765 - if (IS_RDONLY(inode))
5766 + if (IS_RDONLY(inode) ||
5767 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5770 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
5771 @@ -212,7 +219,8 @@ flags_err:
5772 if (!capable(CAP_SYS_RESOURCE))
5775 - if (IS_RDONLY(inode))
5776 + if (IS_RDONLY(inode) ||
5777 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5780 if (get_user(n_blocks_count, (__u32 __user *)arg))
5781 @@ -233,7 +241,8 @@ flags_err:
5782 if (!capable(CAP_SYS_RESOURCE))
5785 - if (IS_RDONLY(inode))
5786 + if (IS_RDONLY(inode) ||
5787 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5790 if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
5791 @@ -247,7 +256,6 @@ flags_err:
5799 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/namei.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/namei.c
5800 --- linux-2.6.19.1/fs/ext4/namei.c 2006-11-30 21:19:20 +0100
5801 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/namei.c 2006-12-01 23:01:47 +0100
5803 #include <linux/buffer_head.h>
5804 #include <linux/bio.h>
5805 #include <linux/smp_lock.h>
5806 +#include <linux/vs_tag.h>
5810 @@ -1008,6 +1009,7 @@ static struct dentry *ext4_lookup(struct
5813 return ERR_PTR(-EACCES);
5814 + dx_propagate_tag(nd, inode);
5816 return d_splice_alias(inode, dentry);
5818 @@ -2381,6 +2383,7 @@ struct inode_operations ext4_dir_inode_o
5819 .removexattr = generic_removexattr,
5821 .permission = ext4_permission,
5822 + .sync_flags = ext4_sync_flags,
5825 struct inode_operations ext4_special_inode_operations = {
5826 @@ -2392,4 +2395,5 @@ struct inode_operations ext4_special_ino
5827 .removexattr = generic_removexattr,
5829 .permission = ext4_permission,
5830 + .sync_flags = ext4_sync_flags,
5832 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/super.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/super.c
5833 --- linux-2.6.19.1/fs/ext4/super.c 2006-11-30 21:19:20 +0100
5834 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/super.c 2006-12-01 23:17:24 +0100
5835 @@ -656,12 +656,12 @@ static int ext4_write_dquot(struct dquot
5836 static int ext4_acquire_dquot(struct dquot *dquot);
5837 static int ext4_release_dquot(struct dquot *dquot);
5838 static int ext4_mark_dquot_dirty(struct dquot *dquot);
5839 -static int ext4_write_info(struct super_block *sb, int type);
5840 -static int ext4_quota_on(struct super_block *sb, int type, int format_id, char *path);
5841 -static int ext4_quota_on_mount(struct super_block *sb, int type);
5842 -static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
5843 +static int ext4_write_info(struct dqhash *hash, int type);
5844 +static int ext4_quota_on(struct dqhash *hash, int type, int format_id, char *path);
5845 +static int ext4_quota_on_mount(struct dqhash *hash, int type);
5846 +static ssize_t ext4_quota_read(struct dqhash *hash, int type, char *data,
5847 size_t len, loff_t off);
5848 -static ssize_t ext4_quota_write(struct super_block *sb, int type,
5849 +static ssize_t ext4_quota_write(struct dqhash *hash, int type,
5850 const char *data, size_t len, loff_t off);
5852 static struct dquot_operations ext4_quota_operations = {
5853 @@ -728,7 +728,7 @@ enum {
5854 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
5855 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
5856 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
5857 - Opt_grpquota, Opt_extents,
5858 + Opt_grpquota, Opt_extents, Opt_tag, Opt_notag, Opt_tagid
5861 static match_table_t tokens = {
5862 @@ -779,6 +779,10 @@ static match_table_t tokens = {
5863 {Opt_usrquota, "usrquota"},
5864 {Opt_barrier, "barrier=%u"},
5865 {Opt_extents, "extents"},
5867 + {Opt_notag, "notag"},
5868 + {Opt_tagid, "tagid=%u"},
5869 + {Opt_tag, "tagxid"},
5871 {Opt_resize, "resize"},
5873 @@ -872,6 +876,20 @@ static int parse_options (char *options,
5875 set_opt (sbi->s_mount_opt, NO_UID32);
5877 +#ifndef CONFIG_TAGGING_NONE
5879 + set_opt (sbi->s_mount_opt, TAGGED);
5882 + clear_opt (sbi->s_mount_opt, TAGGED);
5885 +#ifdef CONFIG_PROPAGATE
5888 + set_opt (sbi->s_mount_opt, TAGGED);
5892 clear_opt (sbi->s_mount_opt, CHECK);
5894 @@ -990,7 +1008,7 @@ static int parse_options (char *options,
5898 - if (sb_any_quota_enabled(sb)) {
5899 + if (dqh_any_quota_enabled(sb->s_dqh)) {
5901 "EXT4-fs: Cannot change journalled "
5902 "quota options when quota turned on.\n");
5903 @@ -1028,7 +1046,7 @@ set_qf_name:
5904 case Opt_offgrpjquota:
5907 - if (sb_any_quota_enabled(sb)) {
5908 + if (dqh_any_quota_enabled(sb->s_dqh)) {
5909 printk(KERN_ERR "EXT4-fs: Cannot change "
5910 "journalled quota options when "
5911 "quota turned on.\n");
5912 @@ -1056,7 +1074,7 @@ clear_qf_name:
5913 set_opt(sbi->s_mount_opt, GRPQUOTA);
5916 - if (sb_any_quota_enabled(sb)) {
5917 + if (dqh_any_quota_enabled(sb->s_dqh)) {
5918 printk(KERN_ERR "EXT4-fs: Cannot change quota "
5919 "options when quota turned on.\n");
5921 @@ -1341,7 +1359,7 @@ static void ext4_orphan_cleanup (struct
5922 /* Turn on quotas so that they are updated correctly */
5923 for (i = 0; i < MAXQUOTAS; i++) {
5924 if (EXT4_SB(sb)->s_qf_names[i]) {
5925 - int ret = ext4_quota_on_mount(sb, i);
5926 + int ret = ext4_quota_on_mount(sb->s_dqh, i);
5929 "EXT4-fs: Cannot turn on journalled "
5930 @@ -1391,8 +1409,8 @@ static void ext4_orphan_cleanup (struct
5932 /* Turn quotas off */
5933 for (i = 0; i < MAXQUOTAS; i++) {
5934 - if (sb_dqopt(sb)->files[i])
5935 - vfs_quota_off(sb, i);
5936 + if (dqh_dqopt(sb->s_dqh)->files[i])
5937 + vfs_quota_off(sb->s_dqh, i);
5940 sb->s_flags = s_flags; /* Restore MS_RDONLY status */
5941 @@ -1539,6 +1557,9 @@ static int ext4_fill_super (struct super
5945 + if (EXT4_SB(sb)->s_mount_opt & EXT4_MOUNT_TAGGED)
5946 + sb->s_flags |= MS_TAGGED;
5948 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
5949 ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
5951 @@ -1757,8 +1778,8 @@ static int ext4_fill_super (struct super
5952 sb->s_export_op = &ext4_export_ops;
5953 sb->s_xattr = ext4_xattr_handlers;
5955 - sb->s_qcop = &ext4_qctl_operations;
5956 - sb->dq_op = &ext4_quota_operations;
5957 + sb->s_dqh->dqh_qop = &ext4_quota_operations;
5958 + sb->s_dqh->dqh_qcop = &ext4_qctl_operations;
5960 INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
5962 @@ -2370,6 +2391,12 @@ static int ext4_remount (struct super_bl
5964 if (sbi->s_mount_opt & EXT4_MOUNT_ABORT)
5965 ext4_abort(sb, __FUNCTION__, "Abort forced by user");
5966 + if ((sbi->s_mount_opt & EXT4_MOUNT_TAGGED) &&
5967 + !(sb->s_flags & MS_TAGGED)) {
5968 + printk("EXT4-fs: %s: tagging not permitted on remount.\n",
5973 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
5974 ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
5975 @@ -2523,7 +2550,7 @@ static int ext4_statfs (struct dentry *
5977 static inline struct inode *dquot_to_inode(struct dquot *dquot)
5979 - return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
5980 + return dqh_dqopt(dquot->dq_dqh)->files[dquot->dq_type];
5983 static int ext4_dquot_initialize(struct inode *inode, int type)
5984 @@ -2566,7 +2593,7 @@ static int ext4_write_dquot(struct dquot
5986 inode = dquot_to_inode(dquot);
5987 handle = ext4_journal_start(inode,
5988 - EXT4_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
5989 + EXT4_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb));
5991 return PTR_ERR(handle);
5992 ret = dquot_commit(dquot);
5993 @@ -2582,7 +2609,7 @@ static int ext4_acquire_dquot(struct dqu
5996 handle = ext4_journal_start(dquot_to_inode(dquot),
5997 - EXT4_QUOTA_INIT_BLOCKS(dquot->dq_sb));
5998 + EXT4_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb));
6000 return PTR_ERR(handle);
6001 ret = dquot_acquire(dquot);
6002 @@ -2598,7 +2625,7 @@ static int ext4_release_dquot(struct dqu
6005 handle = ext4_journal_start(dquot_to_inode(dquot),
6006 - EXT4_QUOTA_DEL_BLOCKS(dquot->dq_sb));
6007 + EXT4_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb));
6009 return PTR_ERR(handle);
6010 ret = dquot_release(dquot);
6011 @@ -2611,8 +2638,8 @@ static int ext4_release_dquot(struct dqu
6012 static int ext4_mark_dquot_dirty(struct dquot *dquot)
6014 /* Are we journalling quotas? */
6015 - if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
6016 - EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
6017 + if (EXT4_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[USRQUOTA] ||
6018 + EXT4_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[GRPQUOTA]) {
6019 dquot_mark_dquot_dirty(dquot);
6020 return ext4_write_dquot(dquot);
6022 @@ -2620,8 +2647,9 @@ static int ext4_mark_dquot_dirty(struct
6026 -static int ext4_write_info(struct super_block *sb, int type)
6027 +static int ext4_write_info(struct dqhash *hash, int type)
6029 + struct super_block *sb = hash->dqh_sb;
6033 @@ -2629,7 +2657,7 @@ static int ext4_write_info(struct super_
6034 handle = ext4_journal_start(sb->s_root->d_inode, 2);
6036 return PTR_ERR(handle);
6037 - ret = dquot_commit_info(sb, type);
6038 + ret = dquot_commit_info(hash, type);
6039 err = ext4_journal_stop(handle);
6042 @@ -2640,18 +2668,20 @@ static int ext4_write_info(struct super_
6043 * Turn on quotas during mount time - we need to find
6044 * the quota file and such...
6046 -static int ext4_quota_on_mount(struct super_block *sb, int type)
6047 +static int ext4_quota_on_mount(struct dqhash *hash, int type)
6049 - return vfs_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type],
6050 - EXT4_SB(sb)->s_jquota_fmt, type);
6051 + return vfs_quota_on_mount(hash,
6052 + EXT4_SB(hash->dqh_sb)->s_qf_names[type],
6053 + EXT4_SB(hash->dqh_sb)->s_jquota_fmt, type);
6057 * Standard function to be called on quota_on
6059 -static int ext4_quota_on(struct super_block *sb, int type, int format_id,
6060 +static int ext4_quota_on(struct dqhash *hash, int type, int format_id,
6063 + struct super_block *sb = hash->dqh_sb;
6065 struct nameidata nd;
6067 @@ -2660,7 +2690,7 @@ static int ext4_quota_on(struct super_bl
6068 /* Not journalling quota? */
6069 if (!EXT4_SB(sb)->s_qf_names[USRQUOTA] &&
6070 !EXT4_SB(sb)->s_qf_names[GRPQUOTA])
6071 - return vfs_quota_on(sb, type, format_id, path);
6072 + return vfs_quota_on(hash, type, format_id, path);
6073 err = path_lookup(path, LOOKUP_FOLLOW, &nd);
6076 @@ -2675,17 +2705,18 @@ static int ext4_quota_on(struct super_bl
6077 "EXT4-fs: Quota file not on filesystem root. "
6078 "Journalled quota will not work.\n");
6080 - return vfs_quota_on(sb, type, format_id, path);
6081 + return vfs_quota_on(hash, type, format_id, path);
6084 /* Read data from quotafile - avoid pagecache and such because we cannot afford
6085 * acquiring the locks... As quota files are never truncated and quota code
6086 * itself serializes the operations (and noone else should touch the files)
6087 * we don't have to be afraid of races */
6088 -static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
6089 +static ssize_t ext4_quota_read(struct dqhash *hash, int type, char *data,
6090 size_t len, loff_t off)
6092 - struct inode *inode = sb_dqopt(sb)->files[type];
6093 + struct inode *inode = dqh_dqopt(hash)->files[type];
6094 + struct super_block *sb = hash->dqh_sb;
6095 sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
6097 int offset = off & (sb->s_blocksize - 1);
6098 @@ -2720,10 +2751,11 @@ static ssize_t ext4_quota_read(struct su
6100 /* Write to quotafile (we know the transaction is already started and has
6101 * enough credits) */
6102 -static ssize_t ext4_quota_write(struct super_block *sb, int type,
6103 +static ssize_t ext4_quota_write(struct dqhash *hash, int type,
6104 const char *data, size_t len, loff_t off)
6106 - struct inode *inode = sb_dqopt(sb)->files[type];
6107 + struct inode *inode = dqh_dqopt(hash)->files[type];
6108 + struct super_block *sb = hash->dqh_sb;
6109 sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
6111 int offset = off & (sb->s_blocksize - 1);
6112 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/symlink.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/symlink.c
6113 --- linux-2.6.19.1/fs/ext4/symlink.c 2006-11-30 21:19:20 +0100
6114 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/symlink.c 2006-12-01 23:01:47 +0100
6115 @@ -40,6 +40,7 @@ struct inode_operations ext4_symlink_ino
6116 .listxattr = ext4_listxattr,
6117 .removexattr = generic_removexattr,
6119 + .sync_flags = ext4_sync_flags,
6122 struct inode_operations ext4_fast_symlink_inode_operations = {
6123 @@ -51,4 +52,5 @@ struct inode_operations ext4_fast_symlin
6124 .listxattr = ext4_listxattr,
6125 .removexattr = generic_removexattr,
6127 + .sync_flags = ext4_sync_flags,
6129 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/xattr.c
6130 --- linux-2.6.19.1/fs/ext4/xattr.c 2006-11-30 21:19:20 +0100
6131 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/xattr.c 2006-12-01 23:01:47 +0100
6133 #include <linux/mbcache.h>
6134 #include <linux/quotaops.h>
6135 #include <linux/rwsem.h>
6136 +#include <linux/vs_dlimit.h>
6140 @@ -495,6 +496,7 @@ ext4_xattr_release_block(handle_t *handl
6141 ext4_journal_dirty_metadata(handle, bh);
6144 + DLIMIT_FREE_BLOCK(inode, 1);
6145 DQUOT_FREE_BLOCK(inode, 1);
6147 ea_bdebug(bh, "refcount now=%d; releasing",
6148 @@ -763,11 +765,14 @@ inserted:
6149 if (new_bh == bs->bh)
6150 ea_bdebug(new_bh, "keeping");
6153 + if (DLIMIT_ALLOC_BLOCK(inode, 1))
6155 /* The old block is released after updating
6158 if (DQUOT_ALLOC_BLOCK(inode, 1))
6160 + goto cleanup_dlimit;
6161 error = ext4_journal_get_write_access(handle,
6164 @@ -844,6 +849,8 @@ cleanup:
6167 DQUOT_FREE_BLOCK(inode, 1);
6169 + DLIMIT_FREE_BLOCK(inode, 1);
6173 diff -NurpP --minimal linux-2.6.19.1/fs/fcntl.c linux-2.6.19.1-vs2.3.0.6/fs/fcntl.c
6174 --- linux-2.6.19.1/fs/fcntl.c 2006-11-30 21:19:23 +0100
6175 +++ linux-2.6.19.1-vs2.3.0.6/fs/fcntl.c 2006-11-08 04:57:48 +0100
6177 #include <linux/ptrace.h>
6178 #include <linux/signal.h>
6179 #include <linux/rcupdate.h>
6180 +#include <linux/vs_limit.h>
6182 #include <asm/poll.h>
6183 #include <asm/siginfo.h>
6184 @@ -85,6 +86,8 @@ repeat:
6186 if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
6188 + if (!vx_files_avail(1))
6191 error = expand_files(files, newfd);
6193 @@ -125,6 +128,7 @@ static int dupfd(struct file *file, unsi
6194 FD_SET(fd, fdt->open_fds);
6195 FD_CLR(fd, fdt->close_on_exec);
6196 spin_unlock(&files->file_lock);
6197 + vx_openfd_inc(fd);
6198 fd_install(fd, file);
6200 spin_unlock(&files->file_lock);
6201 @@ -177,6 +181,9 @@ asmlinkage long sys_dup2(unsigned int ol
6204 filp_close(tofree, files);
6206 + vx_openfd_inc(newfd); /* fd was unused */
6211 diff -NurpP --minimal linux-2.6.19.1/fs/file_table.c linux-2.6.19.1-vs2.3.0.6/fs/file_table.c
6212 --- linux-2.6.19.1/fs/file_table.c 2006-11-30 21:19:25 +0100
6213 +++ linux-2.6.19.1-vs2.3.0.6/fs/file_table.c 2006-11-08 04:57:48 +0100
6215 #include <linux/fsnotify.h>
6216 #include <linux/sysctl.h>
6217 #include <linux/percpu_counter.h>
6218 +#include <linux/vs_limit.h>
6219 +#include <linux/vs_context.h>
6221 #include <asm/atomic.h>
6223 @@ -120,6 +122,8 @@ struct file *get_empty_filp(void)
6224 f->f_gid = tsk->fsgid;
6225 eventpoll_init_file(f);
6226 /* f->f_version: 0 */
6227 + f->f_xid = vx_current_xid();
6232 @@ -175,6 +179,8 @@ void fastcall __fput(struct file *file)
6233 if (file->f_mode & FMODE_WRITE)
6234 put_write_access(inode);
6235 put_pid(file->f_owner.pid);
6236 + vx_files_dec(file);
6239 file->f_dentry = NULL;
6240 file->f_vfsmnt = NULL;
6241 @@ -240,6 +246,8 @@ void put_filp(struct file *file)
6243 if (atomic_dec_and_test(&file->f_count)) {
6244 security_file_free(file);
6245 + vx_files_dec(file);
6250 diff -NurpP --minimal linux-2.6.19.1/fs/gfs2/log.c linux-2.6.19.1-vs2.3.0.6/fs/gfs2/log.c
6251 --- linux-2.6.19.1/fs/gfs2/log.c 2006-11-30 21:19:25 +0100
6252 +++ linux-2.6.19.1-vs2.3.0.6/fs/gfs2/log.c 2006-11-08 22:48:20 +0100
6253 @@ -319,7 +319,7 @@ static u64 log_bmap(struct gfs2_sbd *sdp
6254 bh_map.b_size = 1 << inode->i_blkbits;
6255 error = gfs2_block_map(inode, lbn, 0, &bh_map);
6256 if (error || !bh_map.b_blocknr)
6257 - printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, bh_map.b_blocknr, lbn);
6258 + printk(KERN_INFO "error=%d, dbn=%lu lbn=%u", error, bh_map.b_blocknr, lbn);
6259 gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr);
6261 return bh_map.b_blocknr;
6262 diff -NurpP --minimal linux-2.6.19.1/fs/hfsplus/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/hfsplus/ioctl.c
6263 --- linux-2.6.19.1/fs/hfsplus/ioctl.c 2006-11-30 21:19:25 +0100
6264 +++ linux-2.6.19.1-vs2.3.0.6/fs/hfsplus/ioctl.c 2006-11-08 04:57:52 +0100
6266 #include <linux/fs.h>
6267 #include <linux/sched.h>
6268 #include <linux/xattr.h>
6269 +#include <linux/mount.h>
6270 #include <asm/uaccess.h>
6271 #include "hfsplus_fs.h"
6273 @@ -35,7 +36,8 @@ int hfsplus_ioctl(struct inode *inode, s
6274 flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */
6275 return put_user(flags, (int __user *)arg);
6276 case HFSPLUS_IOC_EXT2_SETFLAGS: {
6277 - if (IS_RDONLY(inode))
6278 + if (IS_RDONLY(inode) ||
6279 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
6282 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
6283 diff -NurpP --minimal linux-2.6.19.1/fs/inode.c linux-2.6.19.1-vs2.3.0.6/fs/inode.c
6284 --- linux-2.6.19.1/fs/inode.c 2006-11-30 21:19:25 +0100
6285 +++ linux-2.6.19.1-vs2.3.0.6/fs/inode.c 2006-11-08 04:57:53 +0100
6286 @@ -115,6 +115,9 @@ static struct inode *alloc_inode(struct
6287 struct address_space * const mapping = &inode->i_data;
6291 + /* essential because of inode slab reuse */
6293 inode->i_blkbits = sb->s_blocksize_bits;
6295 atomic_set(&inode->i_count, 1);
6296 @@ -126,6 +129,9 @@ static struct inode *alloc_inode(struct
6297 inode->i_blocks = 0;
6299 inode->i_generation = 0;
6300 +#ifdef CONFIG_QUOTACTL
6301 + inode->i_dqh = dqhget(sb->s_dqh);
6304 memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
6306 @@ -172,6 +178,8 @@ void destroy_inode(struct inode *inode)
6308 BUG_ON(inode_has_buffers(inode));
6309 security_inode_free(inode);
6310 + if (dqhash_valid(inode->i_dqh))
6311 + dqhput(inode->i_dqh);
6312 if (inode->i_sb->s_op->destroy_inode)
6313 inode->i_sb->s_op->destroy_inode(inode);
6315 @@ -233,6 +241,8 @@ void __iget(struct inode * inode)
6316 inodes_stat.nr_unused--;
6319 +EXPORT_SYMBOL_GPL(__iget);
6322 * clear_inode - clear an inode
6323 * @inode: inode to clear
6324 @@ -1245,12 +1255,13 @@ EXPORT_SYMBOL(inode_needs_sync);
6325 /* Function back in dquot.c */
6326 int remove_inode_dquot_ref(struct inode *, int, struct list_head *);
6328 -void remove_dquot_ref(struct super_block *sb, int type,
6329 +void remove_dquot_ref(struct dqhash *hash, int type,
6330 struct list_head *tofree_head)
6332 struct inode *inode;
6333 + struct super_block *sb = hash->dqh_sb;
6336 + if (!hash->dqh_qop)
6337 return; /* nothing to do */
6338 spin_lock(&inode_lock); /* This lock is for inodes code */
6340 diff -NurpP --minimal linux-2.6.19.1/fs/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/ioctl.c
6341 --- linux-2.6.19.1/fs/ioctl.c 2006-09-20 16:58:35 +0200
6342 +++ linux-2.6.19.1-vs2.3.0.6/fs/ioctl.c 2006-12-17 04:31:15 +0100
6344 #include <linux/fs.h>
6345 #include <linux/security.h>
6346 #include <linux/module.h>
6347 +#include <linux/proc_fs.h>
6348 +#include <linux/vserver/inode.h>
6349 +#include <linux/vs_tag.h>
6351 #include <asm/uaccess.h>
6352 #include <asm/ioctls.h>
6355 static long do_ioctl(struct file *filp, unsigned int cmd,
6358 diff -NurpP --minimal linux-2.6.19.1/fs/ioprio.c linux-2.6.19.1-vs2.3.0.6/fs/ioprio.c
6359 --- linux-2.6.19.1/fs/ioprio.c 2006-11-30 21:19:25 +0100
6360 +++ linux-2.6.19.1-vs2.3.0.6/fs/ioprio.c 2006-11-30 18:53:18 +0100
6362 #include <linux/capability.h>
6363 #include <linux/syscalls.h>
6364 #include <linux/security.h>
6365 +#include <linux/vs_base.h>
6367 static int set_task_ioprio(struct task_struct *task, int ioprio)
6369 @@ -109,7 +110,7 @@ asmlinkage long sys_ioprio_set(int which
6371 user = current->user;
6373 - user = find_user(who);
6374 + user = find_user(vx_current_xid(), who);
6378 @@ -197,7 +198,7 @@ asmlinkage long sys_ioprio_get(int which
6380 user = current->user;
6382 - user = find_user(who);
6383 + user = find_user(vx_current_xid(), who);
6387 diff -NurpP --minimal linux-2.6.19.1/fs/jffs2/dir.c linux-2.6.19.1-vs2.3.0.6/fs/jffs2/dir.c
6388 --- linux-2.6.19.1/fs/jffs2/dir.c 2006-11-30 21:19:25 +0100
6389 +++ linux-2.6.19.1-vs2.3.0.6/fs/jffs2/dir.c 2006-12-16 10:19:32 +0100
6390 @@ -37,6 +37,8 @@ static int jffs2_mknod (struct inode *,s
6391 static int jffs2_rename (struct inode *, struct dentry *,
6392 struct inode *, struct dentry *);
6394 +extern int jffs2_sync_flags(struct inode *);
6396 const struct file_operations jffs2_dir_operations =
6398 .read = generic_read_dir,
6399 @@ -59,6 +61,7 @@ struct inode_operations jffs2_dir_inode_
6400 .rename = jffs2_rename,
6401 .permission = jffs2_permission,
6402 .setattr = jffs2_setattr,
6403 + .sync_flags = jffs2_sync_flags,
6404 .setxattr = jffs2_setxattr,
6405 .getxattr = jffs2_getxattr,
6406 .listxattr = jffs2_listxattr,
6407 diff -NurpP --minimal linux-2.6.19.1/fs/jffs2/file.c linux-2.6.19.1-vs2.3.0.6/fs/jffs2/file.c
6408 --- linux-2.6.19.1/fs/jffs2/file.c 2006-11-30 21:19:25 +0100
6409 +++ linux-2.6.19.1-vs2.3.0.6/fs/jffs2/file.c 2006-12-16 10:19:32 +0100
6410 @@ -27,6 +27,9 @@ static int jffs2_prepare_write (struct f
6411 unsigned start, unsigned end);
6412 static int jffs2_readpage (struct file *filp, struct page *pg);
6414 +extern int jffs2_sync_flags(struct inode *);
6417 int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
6419 struct inode *inode = dentry->d_inode;
6420 @@ -58,6 +61,7 @@ struct inode_operations jffs2_file_inode
6422 .permission = jffs2_permission,
6423 .setattr = jffs2_setattr,
6424 + .sync_flags = jffs2_sync_flags,
6425 .setxattr = jffs2_setxattr,
6426 .getxattr = jffs2_getxattr,
6427 .listxattr = jffs2_listxattr,
6428 @@ -165,6 +169,7 @@ static int jffs2_prepare_write (struct f
6429 ri.dsize = cpu_to_je32(pageofs - inode->i_size);
6430 ri.csize = cpu_to_je32(0);
6431 ri.compr = JFFS2_COMPR_ZERO;
6432 + ri.flags = cpu_to_je16(f->flags);
6433 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
6434 ri.data_crc = cpu_to_je32(0);
6436 @@ -252,6 +257,7 @@ static int jffs2_commit_write (struct fi
6437 ri->gid = cpu_to_je16(inode->i_gid);
6438 ri->isize = cpu_to_je32((uint32_t)inode->i_size);
6439 ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds());
6440 + ri->flags = cpu_to_je16(f->flags);
6442 /* In 2.4, it was already kmapped by generic_file_write(). Doesn't
6443 hurt to do it again. The alternative is ifdefs, which are ugly. */
6444 diff -NurpP --minimal linux-2.6.19.1/fs/jffs2/fs.c linux-2.6.19.1-vs2.3.0.6/fs/jffs2/fs.c
6445 --- linux-2.6.19.1/fs/jffs2/fs.c 2006-11-30 21:19:25 +0100
6446 +++ linux-2.6.19.1-vs2.3.0.6/fs/jffs2/fs.c 2006-12-16 10:21:01 +0100
6447 @@ -118,6 +118,9 @@ static int jffs2_do_setattr (struct inod
6448 ri->offset = cpu_to_je32(0);
6449 ri->csize = ri->dsize = cpu_to_je32(mdatalen);
6450 ri->compr = JFFS2_COMPR_NONE;
6451 + ri->flags = cpu_to_je16(f->flags);
6452 + printk("··· do set attr flags: %04x\n", f->flags);
6454 if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
6455 /* It's an extension. Make it a hole node */
6456 ri->compr = JFFS2_COMPR_ZERO;
6457 @@ -181,6 +184,52 @@ static int jffs2_do_setattr (struct inod
6461 +void jffs2_set_inode_flags(struct inode *inode)
6463 + struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
6464 + unsigned int flags = f->flags;
6466 + inode->i_flags &= ~(JFFS2_INO_FLAG_IMMUTABLE |
6467 + JFFS2_INO_FLAG_IUNLINK | JFFS2_INO_FLAG_BARRIER);
6469 + if (flags & JFFS2_INO_FLAG_IMMUTABLE)
6470 + inode->i_flags |= S_IMMUTABLE;
6471 + if (flags & JFFS2_INO_FLAG_IUNLINK)
6472 + inode->i_flags |= S_IUNLINK;
6473 + if (flags & JFFS2_INO_FLAG_BARRIER)
6474 + inode->i_flags |= S_BARRIER;
6476 + printk("··· set %p[#%lu] flags: %04x\n", inode, inode->i_ino, flags);
6479 +int jffs2_sync_flags(struct inode *inode)
6481 + struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
6482 + unsigned int oldflags, newflags;
6484 + oldflags = f->flags;
6485 + newflags = oldflags & ~(JFFS2_INO_FLAG_IMMUTABLE |
6486 + JFFS2_INO_FLAG_IUNLINK | JFFS2_INO_FLAG_BARRIER);
6488 + if (IS_IMMUTABLE(inode))
6489 + newflags |= JFFS2_INO_FLAG_IMMUTABLE;
6490 + if (IS_IUNLINK(inode))
6491 + newflags |= JFFS2_INO_FLAG_IUNLINK;
6492 + if (IS_BARRIER(inode))
6493 + newflags |= JFFS2_INO_FLAG_BARRIER;
6495 + if (oldflags ^ newflags) {
6496 + f->flags = newflags;
6497 + inode->i_ctime = CURRENT_TIME;
6498 + /* strange requirement, see jffs2_dirty_inode() */
6499 + inode->i_state |= I_DIRTY_DATASYNC;
6500 + mark_inode_dirty(inode);
6502 + printk("··· sync %p[#%lu] flags: %04x ^ %04x\n",
6503 + inode, inode->i_ino, oldflags, newflags);
6507 int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
6510 @@ -287,6 +336,7 @@ void jffs2_read_inode (struct inode *ino
6512 inode->i_op = &jffs2_dir_inode_operations;
6513 inode->i_fop = &jffs2_dir_operations;
6514 + f->flags = je16_to_cpu(latest_node.flags);
6518 @@ -294,6 +344,7 @@ void jffs2_read_inode (struct inode *ino
6519 inode->i_fop = &jffs2_file_operations;
6520 inode->i_mapping->a_ops = &jffs2_file_address_operations;
6521 inode->i_mapping->nrpages = 0;
6522 + f->flags = je16_to_cpu(latest_node.flags);
6526 @@ -330,7 +381,7 @@ void jffs2_read_inode (struct inode *ino
6528 printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
6531 + jffs2_set_inode_flags(inode);
6534 D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
6535 @@ -451,6 +502,8 @@ struct inode *jffs2_new_inode (struct in
6536 inode->i_blocks = 0;
6539 + f->flags = je16_to_cpu(ri->flags);
6540 + jffs2_set_inode_flags(inode);
6541 insert_inode_hash(inode);
6544 diff -NurpP --minimal linux-2.6.19.1/fs/jffs2/readinode.c linux-2.6.19.1-vs2.3.0.6/fs/jffs2/readinode.c
6545 --- linux-2.6.19.1/fs/jffs2/readinode.c 2006-09-20 16:58:35 +0200
6546 +++ linux-2.6.19.1-vs2.3.0.6/fs/jffs2/readinode.c 2006-12-16 10:19:32 +0100
6547 @@ -759,6 +759,7 @@ static int jffs2_do_read_inode_internal(
6548 latest_node->isize = cpu_to_je32(0);
6549 latest_node->gid = cpu_to_je16(0);
6550 latest_node->uid = cpu_to_je16(0);
6551 + latest_node->flags = cpu_to_je16(0);
6552 if (f->inocache->state == INO_STATE_READING)
6553 jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
6555 diff -NurpP --minimal linux-2.6.19.1/fs/jffs2/write.c linux-2.6.19.1-vs2.3.0.6/fs/jffs2/write.c
6556 --- linux-2.6.19.1/fs/jffs2/write.c 2006-09-20 16:58:35 +0200
6557 +++ linux-2.6.19.1-vs2.3.0.6/fs/jffs2/write.c 2006-12-16 10:19:32 +0100
6558 @@ -46,6 +46,7 @@ int jffs2_do_new_inode(struct jffs2_sb_i
6559 ri->totlen = cpu_to_je32(PAD(sizeof(*ri)));
6560 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
6561 ri->mode = cpu_to_jemode(mode);
6562 + ri->flags = cpu_to_je16(0);
6564 f->highest_version = 1;
6565 ri->version = cpu_to_je32(f->highest_version);
6566 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/acl.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/acl.c
6567 --- linux-2.6.19.1/fs/jfs/acl.c 2006-11-30 21:19:25 +0100
6568 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/acl.c 2006-11-08 04:57:46 +0100
6569 @@ -232,7 +232,8 @@ int jfs_setattr(struct dentry *dentry, s
6572 if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
6573 - (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
6574 + (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) ||
6575 + (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) {
6576 if (DQUOT_TRANSFER(inode, iattr))
6579 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/file.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/file.c
6580 --- linux-2.6.19.1/fs/jfs/file.c 2006-11-30 21:19:25 +0100
6581 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/file.c 2006-11-08 21:52:37 +0100
6582 @@ -98,6 +98,7 @@ struct inode_operations jfs_file_inode_o
6583 .setattr = jfs_setattr,
6584 .permission = jfs_permission,
6586 + .sync_flags = jfs_sync_flags,
6589 const struct file_operations jfs_file_operations = {
6590 @@ -109,6 +110,7 @@ const struct file_operations jfs_file_op
6591 .aio_write = generic_file_aio_write,
6592 .mmap = generic_file_mmap,
6593 .sendfile = generic_file_sendfile,
6594 + .sendpage = generic_file_sendpage,
6595 .splice_read = generic_file_splice_read,
6596 .splice_write = generic_file_splice_write,
6598 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/inode.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/inode.c
6599 --- linux-2.6.19.1/fs/jfs/inode.c 2006-11-30 21:19:25 +0100
6600 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/inode.c 2006-11-08 04:57:50 +0100
6602 #include <linux/buffer_head.h>
6603 #include <linux/pagemap.h>
6604 #include <linux/quotaops.h>
6605 +#include <linux/vs_dlimit.h>
6606 #include "jfs_incore.h"
6607 #include "jfs_inode.h"
6608 #include "jfs_filsys.h"
6609 @@ -144,6 +145,7 @@ void jfs_delete_inode(struct inode *inod
6611 DQUOT_FREE_INODE(inode);
6613 + DLIMIT_FREE_INODE(inode);
6617 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/ioctl.c
6618 --- linux-2.6.19.1/fs/jfs/ioctl.c 2006-11-30 21:19:25 +0100
6619 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/ioctl.c 2006-11-08 04:57:51 +0100
6621 #include <linux/ctype.h>
6622 #include <linux/capability.h>
6623 #include <linux/time.h>
6624 +#include <linux/mount.h>
6625 #include <asm/current.h>
6626 #include <asm/uaccess.h>
6628 @@ -64,7 +65,8 @@ int jfs_ioctl(struct inode * inode, stru
6629 case JFS_IOC_SETFLAGS: {
6630 unsigned int oldflags;
6632 - if (IS_RDONLY(inode))
6633 + if (IS_RDONLY(inode) ||
6634 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
6637 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
6638 @@ -84,8 +86,8 @@ int jfs_ioctl(struct inode * inode, stru
6639 * the relevant capability.
6641 if ((oldflags & JFS_IMMUTABLE_FL) ||
6642 - ((flags ^ oldflags) &
6643 - (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
6644 + ((flags ^ oldflags) & (JFS_APPEND_FL |
6645 + JFS_IMMUTABLE_FL | JFS_IUNLINK_FL))) {
6646 if (!capable(CAP_LINUX_IMMUTABLE))
6649 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_dinode.h linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_dinode.h
6650 --- linux-2.6.19.1/fs/jfs/jfs_dinode.h 2006-11-30 21:19:25 +0100
6651 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_dinode.h 2006-11-08 04:57:51 +0100
6652 @@ -162,9 +162,12 @@ struct dinode {
6653 #define JFS_APPEND_FL 0x01000000 /* writes to file may only append */
6654 #define JFS_IMMUTABLE_FL 0x02000000 /* Immutable file */
6656 -#define JFS_FL_USER_VISIBLE 0x03F80000
6657 +#define JFS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
6658 +#define JFS_IUNLINK_FL 0x08000000 /* Immutable unlink */
6660 +#define JFS_FL_USER_VISIBLE 0x0FF80000
6661 #define JFS_FL_USER_MODIFIABLE 0x03F80000
6662 -#define JFS_FL_INHERIT 0x03C80000
6663 +#define JFS_FL_INHERIT 0x0BC80000
6665 /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
6666 #define JFS_IOC_GETFLAGS _IOR('f', 1, long)
6667 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_dtree.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_dtree.c
6668 --- linux-2.6.19.1/fs/jfs/jfs_dtree.c 2006-11-30 21:19:25 +0100
6669 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_dtree.c 2006-11-08 04:57:50 +0100
6672 #include <linux/fs.h>
6673 #include <linux/quotaops.h>
6674 +#include <linux/vs_dlimit.h>
6675 #include "jfs_incore.h"
6676 #include "jfs_superblock.h"
6677 #include "jfs_filsys.h"
6678 @@ -383,10 +384,10 @@ static u32 add_index(tid_t tid, struct i
6680 if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage))
6682 - if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) {
6683 - DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
6686 + if (DLIMIT_ALLOC_BLOCK(ip, sbi->nbperpage))
6687 + goto clean_up_dquot;
6688 + if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
6689 + goto clean_up_dlimit;
6692 * Save the table, we're going to overwrite it with the
6693 @@ -479,6 +480,12 @@ static u32 add_index(tid_t tid, struct i
6698 + DLIMIT_FREE_BLOCK(ip, sbi->nbperpage);
6701 + DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
6705 jfs_ip->next_index--;
6706 @@ -952,6 +959,7 @@ static int dtSplitUp(tid_t tid,
6709 int quota_allocation = 0;
6710 + int dlimit_allocation = 0;
6712 /* get split page */
6714 @@ -1036,6 +1044,12 @@ static int dtSplitUp(tid_t tid,
6716 quota_allocation += n;
6718 + if (DLIMIT_ALLOC_BLOCK(ip, n)) {
6722 + dlimit_allocation += n;
6724 if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen,
6727 @@ -1309,6 +1323,9 @@ static int dtSplitUp(tid_t tid,
6731 + /* Rollback dlimit allocation */
6732 + if (rc && dlimit_allocation)
6733 + DLIMIT_FREE_BLOCK(ip, dlimit_allocation);
6734 /* Rollback quota allocation */
6735 if (rc && quota_allocation)
6736 DQUOT_FREE_BLOCK(ip, quota_allocation);
6737 @@ -1376,6 +1393,12 @@ static int dtSplitPage(tid_t tid, struct
6738 release_metapage(rmp);
6741 + /* Allocate blocks to dlimit. */
6742 + if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
6743 + DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
6744 + release_metapage(rmp);
6748 jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
6750 @@ -1926,6 +1949,12 @@ static int dtSplitRoot(tid_t tid,
6751 release_metapage(rmp);
6754 + /* Allocate blocks to dlimit. */
6755 + if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
6756 + DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
6757 + release_metapage(rmp);
6761 BT_MARK_DIRTY(rmp, ip);
6763 @@ -2292,6 +2321,8 @@ static int dtDeleteUp(tid_t tid, struct
6765 xlen = lengthPXD(&fp->header.self);
6767 + /* Free dlimit allocation. */
6768 + DLIMIT_FREE_BLOCK(ip, xlen);
6769 /* Free quota allocation. */
6770 DQUOT_FREE_BLOCK(ip, xlen);
6772 @@ -2368,6 +2399,8 @@ static int dtDeleteUp(tid_t tid, struct
6774 xlen = lengthPXD(&p->header.self);
6776 + /* Free dlimit allocation */
6777 + DLIMIT_FREE_BLOCK(ip, xlen);
6778 /* Free quota allocation */
6779 DQUOT_FREE_BLOCK(ip, xlen);
6781 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_extent.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_extent.c
6782 --- linux-2.6.19.1/fs/jfs/jfs_extent.c 2006-11-30 21:19:25 +0100
6783 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_extent.c 2006-11-08 04:57:50 +0100
6786 #include <linux/fs.h>
6787 #include <linux/quotaops.h>
6788 +#include <linux/vs_dlimit.h>
6789 #include "jfs_incore.h"
6790 #include "jfs_inode.h"
6791 #include "jfs_superblock.h"
6792 @@ -147,6 +148,14 @@ extAlloc(struct inode *ip, s64 xlen, s64
6796 + /* Allocate blocks to dlimit. */
6797 + if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
6798 + DQUOT_FREE_BLOCK(ip, nxlen);
6799 + dbFree(ip, nxaddr, (s64) nxlen);
6800 + mutex_unlock(&JFS_IP(ip)->commit_mutex);
6804 /* determine the value of the extent flag */
6805 xflag = abnr ? XAD_NOTRECORDED : 0;
6807 @@ -164,6 +173,7 @@ extAlloc(struct inode *ip, s64 xlen, s64
6810 dbFree(ip, nxaddr, nxlen);
6811 + DLIMIT_FREE_BLOCK(ip, nxlen);
6812 DQUOT_FREE_BLOCK(ip, nxlen);
6813 mutex_unlock(&JFS_IP(ip)->commit_mutex);
6815 @@ -261,6 +271,13 @@ int extRealloc(struct inode *ip, s64 nxl
6816 mutex_unlock(&JFS_IP(ip)->commit_mutex);
6819 + /* Allocate blocks to dlimit. */
6820 + if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
6821 + DQUOT_FREE_BLOCK(ip, nxlen);
6822 + dbFree(ip, nxaddr, (s64) nxlen);
6823 + up(&JFS_IP(ip)->commit_sem);
6827 delta = nxlen - xlen;
6829 @@ -297,6 +314,7 @@ int extRealloc(struct inode *ip, s64 nxl
6830 /* extend the extent */
6831 if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
6832 dbFree(ip, xaddr + xlen, delta);
6833 + DLIMIT_FREE_BLOCK(ip, nxlen);
6834 DQUOT_FREE_BLOCK(ip, nxlen);
6837 @@ -308,6 +326,7 @@ int extRealloc(struct inode *ip, s64 nxl
6839 if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
6840 dbFree(ip, nxaddr, nxlen);
6841 + DLIMIT_FREE_BLOCK(ip, nxlen);
6842 DQUOT_FREE_BLOCK(ip, nxlen);
6845 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_filsys.h linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_filsys.h
6846 --- linux-2.6.19.1/fs/jfs/jfs_filsys.h 2006-11-30 21:19:25 +0100
6847 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_filsys.h 2006-11-08 04:57:46 +0100
6849 #define JFS_DIR_INDEX 0x00200000 /* Persistant index for */
6850 /* directory entries */
6852 +#define JFS_TAGGED 0x00800000 /* Context Tagging */
6855 * buffer cache configuration
6856 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_imap.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_imap.c
6857 --- linux-2.6.19.1/fs/jfs/jfs_imap.c 2006-11-30 21:19:25 +0100
6858 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_imap.c 2006-11-30 18:53:18 +0100
6860 #include <linux/buffer_head.h>
6861 #include <linux/pagemap.h>
6862 #include <linux/quotaops.h>
6863 +#include <linux/vs_tag.h>
6865 #include "jfs_incore.h"
6866 #include "jfs_inode.h"
6867 @@ -3075,6 +3076,8 @@ static int copy_from_dinode(struct dinod
6869 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
6870 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
6874 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
6875 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
6876 @@ -3094,14 +3097,18 @@ static int copy_from_dinode(struct dinod
6878 ip->i_nlink = le32_to_cpu(dip->di_nlink);
6880 - jfs_ip->saved_uid = le32_to_cpu(dip->di_uid);
6881 + uid = le32_to_cpu(dip->di_uid);
6882 + gid = le32_to_cpu(dip->di_gid);
6883 + ip->i_tag = INOTAG_TAG(DX_TAG(ip), uid, gid, 0);
6885 + jfs_ip->saved_uid = INOTAG_UID(DX_TAG(ip), uid, gid);
6887 ip->i_uid = jfs_ip->saved_uid;
6889 ip->i_uid = sbi->uid;
6892 - jfs_ip->saved_gid = le32_to_cpu(dip->di_gid);
6893 + jfs_ip->saved_gid = INOTAG_GID(DX_TAG(ip), uid, gid);
6895 ip->i_gid = jfs_ip->saved_gid;
6897 @@ -3166,14 +3173,12 @@ static void copy_to_dinode(struct dinode
6898 dip->di_size = cpu_to_le64(ip->i_size);
6899 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
6900 dip->di_nlink = cpu_to_le32(ip->i_nlink);
6901 - if (sbi->uid == -1)
6902 - dip->di_uid = cpu_to_le32(ip->i_uid);
6904 - dip->di_uid = cpu_to_le32(jfs_ip->saved_uid);
6905 - if (sbi->gid == -1)
6906 - dip->di_gid = cpu_to_le32(ip->i_gid);
6908 - dip->di_gid = cpu_to_le32(jfs_ip->saved_gid);
6910 + dip->di_uid = cpu_to_le32(TAGINO_UID(DX_TAG(ip),
6911 + (sbi->uid == -1) ? ip->i_uid : jfs_ip->saved_uid, ip->i_tag));
6912 + dip->di_gid = cpu_to_le32(TAGINO_GID(DX_TAG(ip),
6913 + (sbi->gid == -1) ? ip->i_gid : jfs_ip->saved_gid, ip->i_tag));
6916 * mode2 is only needed for storing the higher order bits.
6917 * Trust i_mode for the lower order ones
6918 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_inode.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_inode.c
6919 --- linux-2.6.19.1/fs/jfs/jfs_inode.c 2006-11-30 21:19:25 +0100
6920 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_inode.c 2006-11-08 04:57:51 +0100
6923 #include <linux/fs.h>
6924 #include <linux/quotaops.h>
6925 +#include <linux/vs_dlimit.h>
6926 +#include <linux/vs_tag.h>
6927 #include "jfs_incore.h"
6928 #include "jfs_inode.h"
6929 #include "jfs_filsys.h"
6930 @@ -30,19 +32,59 @@ void jfs_set_inode_flags(struct inode *i
6932 unsigned int flags = JFS_IP(inode)->mode2;
6934 - inode->i_flags &= ~(S_IMMUTABLE | S_APPEND |
6935 - S_NOATIME | S_DIRSYNC | S_SYNC);
6936 + inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
6937 + S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
6939 if (flags & JFS_IMMUTABLE_FL)
6940 inode->i_flags |= S_IMMUTABLE;
6941 + if (flags & JFS_IUNLINK_FL)
6942 + inode->i_flags |= S_IUNLINK;
6943 + if (flags & JFS_BARRIER_FL)
6944 + inode->i_flags |= S_BARRIER;
6946 + if (flags & JFS_SYNC_FL)
6947 + inode->i_flags |= S_SYNC;
6948 if (flags & JFS_APPEND_FL)
6949 inode->i_flags |= S_APPEND;
6950 if (flags & JFS_NOATIME_FL)
6951 inode->i_flags |= S_NOATIME;
6952 if (flags & JFS_DIRSYNC_FL)
6953 inode->i_flags |= S_DIRSYNC;
6954 - if (flags & JFS_SYNC_FL)
6955 - inode->i_flags |= S_SYNC;
6958 +int jfs_sync_flags(struct inode *inode)
6960 + unsigned int oldflags, newflags;
6962 + oldflags = JFS_IP(inode)->mode2;
6963 + newflags = oldflags & ~(JFS_APPEND_FL |
6964 + JFS_IMMUTABLE_FL | JFS_IUNLINK_FL |
6965 + JFS_BARRIER_FL | JFS_NOATIME_FL |
6966 + JFS_SYNC_FL | JFS_DIRSYNC_FL);
6968 + if (IS_APPEND(inode))
6969 + newflags |= JFS_APPEND_FL;
6970 + if (IS_IMMUTABLE(inode))
6971 + newflags |= JFS_IMMUTABLE_FL;
6972 + if (IS_IUNLINK(inode))
6973 + newflags |= JFS_IUNLINK_FL;
6974 + if (IS_BARRIER(inode))
6975 + newflags |= JFS_BARRIER_FL;
6977 + /* we do not want to copy superblock flags */
6978 + if (inode->i_flags & S_NOATIME)
6979 + newflags |= JFS_NOATIME_FL;
6980 + if (inode->i_flags & S_SYNC)
6981 + newflags |= JFS_SYNC_FL;
6982 + if (inode->i_flags & S_DIRSYNC)
6983 + newflags |= JFS_DIRSYNC_FL;
6985 + if (oldflags ^ newflags) {
6986 + JFS_IP(inode)->mode2 = newflags;
6987 + inode->i_ctime = CURRENT_TIME;
6988 + mark_inode_dirty(inode);
6994 @@ -90,10 +132,17 @@ struct inode *ialloc(struct inode *paren
6995 jfs_inode->saved_uid = inode->i_uid;
6996 jfs_inode->saved_gid = inode->i_gid;
6998 + inode->i_tag = dx_current_fstag(sb);
6999 + if (DLIMIT_ALLOC_INODE(inode)) {
7005 * Allocate inode to quota.
7007 if (DQUOT_ALLOC_INODE(inode)) {
7008 + DLIMIT_FREE_INODE(inode);
7010 inode->i_flags |= S_NOQUOTA;
7012 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_inode.h linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_inode.h
7013 --- linux-2.6.19.1/fs/jfs/jfs_inode.h 2006-11-30 21:19:25 +0100
7014 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_inode.h 2006-11-08 04:57:51 +0100
7015 @@ -31,6 +31,7 @@ extern void jfs_truncate(struct inode *)
7016 extern void jfs_truncate_nolock(struct inode *, loff_t);
7017 extern void jfs_free_zero_link(struct inode *);
7018 extern struct dentry *jfs_get_parent(struct dentry *dentry);
7019 +extern int jfs_sync_flags(struct inode *);
7020 extern void jfs_set_inode_flags(struct inode *);
7021 extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
7023 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_xtree.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_xtree.c
7024 --- linux-2.6.19.1/fs/jfs/jfs_xtree.c 2006-11-30 21:19:26 +0100
7025 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_xtree.c 2006-11-08 04:57:50 +0100
7028 #include <linux/fs.h>
7029 #include <linux/quotaops.h>
7030 +#include <linux/vs_dlimit.h>
7031 #include "jfs_incore.h"
7032 #include "jfs_filsys.h"
7033 #include "jfs_metapage.h"
7034 @@ -841,7 +842,12 @@ int xtInsert(tid_t tid, /* transaction
7036 if ((rc = DQUOT_ALLOC_BLOCK(ip, xlen)))
7038 + if ((rc = DLIMIT_ALLOC_BLOCK(ip, xlen))) {
7039 + DQUOT_FREE_BLOCK(ip, xlen);
7042 if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) {
7043 + DLIMIT_FREE_BLOCK(ip, xlen);
7044 DQUOT_FREE_BLOCK(ip, xlen);
7047 @@ -871,6 +877,7 @@ int xtInsert(tid_t tid, /* transaction
7048 /* undo data extent allocation */
7050 dbFree(ip, xaddr, (s64) xlen);
7051 + DLIMIT_FREE_BLOCK(ip, xlen);
7052 DQUOT_FREE_BLOCK(ip, xlen);
7055 @@ -1231,6 +1238,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
7057 struct xtlock *sxtlck = NULL, *rxtlck = NULL;
7058 int quota_allocation = 0;
7059 + int dlimit_allocation = 0;
7062 sp = XT_PAGE(ip, smp);
7063 @@ -1250,6 +1258,13 @@ xtSplitPage(tid_t tid, struct inode *ip,
7065 quota_allocation += lengthPXD(pxd);
7067 + /* Allocate blocks to dlimit. */
7068 + if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
7072 + dlimit_allocation += lengthPXD(pxd);
7075 * allocate the new right page for the split
7077 @@ -1451,6 +1466,9 @@ xtSplitPage(tid_t tid, struct inode *ip,
7081 + /* Rollback dlimit allocation. */
7082 + if (dlimit_allocation)
7083 + DLIMIT_FREE_BLOCK(ip, dlimit_allocation);
7084 /* Rollback quota allocation. */
7085 if (quota_allocation)
7086 DQUOT_FREE_BLOCK(ip, quota_allocation);
7087 @@ -1515,6 +1533,12 @@ xtSplitRoot(tid_t tid,
7088 release_metapage(rmp);
7091 + /* Allocate blocks to dlimit. */
7092 + if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
7093 + DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
7094 + release_metapage(rmp);
7098 jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp);
7100 @@ -3941,6 +3965,8 @@ s64 xtTruncate(tid_t tid, struct inode *
7102 ip->i_size = newsize;
7104 + /* update dlimit allocation to reflect freed blocks */
7105 + DLIMIT_FREE_BLOCK(ip, nfreed);
7106 /* update quota allocation to reflect freed blocks */
7107 DQUOT_FREE_BLOCK(ip, nfreed);
7109 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/namei.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/namei.c
7110 --- linux-2.6.19.1/fs/jfs/namei.c 2006-11-30 21:19:26 +0100
7111 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/namei.c 2006-11-30 18:53:18 +0100
7113 #include <linux/fs.h>
7114 #include <linux/ctype.h>
7115 #include <linux/quotaops.h>
7116 +#include <linux/vs_tag.h>
7117 #include "jfs_incore.h"
7118 #include "jfs_superblock.h"
7119 #include "jfs_inode.h"
7120 @@ -1461,6 +1462,7 @@ static struct dentry *jfs_lookup(struct
7121 return ERR_PTR(-EACCES);
7124 + dx_propagate_tag(nd, ip);
7125 dentry = d_splice_alias(ip, dentry);
7127 if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2))
7128 @@ -1513,6 +1515,7 @@ struct inode_operations jfs_dir_inode_op
7129 .setattr = jfs_setattr,
7130 .permission = jfs_permission,
7132 + .sync_flags = jfs_sync_flags,
7135 const struct file_operations jfs_dir_operations = {
7136 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/super.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/super.c
7137 --- linux-2.6.19.1/fs/jfs/super.c 2006-11-30 21:19:26 +0100
7138 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/super.c 2006-11-08 04:57:51 +0100
7139 @@ -194,7 +194,8 @@ static void jfs_put_super(struct super_b
7141 Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
7142 Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
7143 - Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask
7144 + Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
7145 + Opt_tag, Opt_notag, Opt_tagid
7148 static match_table_t tokens = {
7149 @@ -204,6 +205,10 @@ static match_table_t tokens = {
7150 {Opt_resize, "resize=%u"},
7151 {Opt_resize_nosize, "resize"},
7152 {Opt_errors, "errors=%s"},
7154 + {Opt_notag, "notag"},
7155 + {Opt_tagid, "tagid=%u"},
7156 + {Opt_tag, "tagxid"},
7157 {Opt_ignore, "noquota"},
7158 {Opt_ignore, "quota"},
7159 {Opt_usrquota, "usrquota"},
7160 @@ -338,6 +343,20 @@ static int parse_options(char *options,
7164 +#ifndef CONFIG_TAGGING_NONE
7166 + *flag |= JFS_TAGGED;
7169 + *flag &= JFS_TAGGED;
7172 +#ifdef CONFIG_PROPAGATE
7175 + *flag |= JFS_TAGGED;
7179 printk("jfs: Unrecognized mount option \"%s\" "
7180 " or missing value\n", p);
7181 @@ -368,6 +387,13 @@ static int jfs_remount(struct super_bloc
7182 if (!parse_options(data, sb, &newLVSize, &flag)) {
7186 + if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) {
7187 + printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n",
7193 if (sb->s_flags & MS_RDONLY) {
7195 @@ -439,6 +465,9 @@ static int jfs_fill_super(struct super_b
7196 #ifdef CONFIG_JFS_POSIX_ACL
7197 sb->s_flags |= MS_POSIXACL;
7199 + /* map mount option tagxid */
7200 + if (sbi->flag & JFS_TAGGED)
7201 + sb->s_flags |= MS_TAGGED;
7204 printk(KERN_ERR "resize option for remount only\n");
7205 @@ -615,10 +644,11 @@ static int jfs_show_options(struct seq_f
7206 * acquiring the locks... As quota files are never truncated and quota code
7207 * itself serializes the operations (and noone else should touch the files)
7208 * we don't have to be afraid of races */
7209 -static ssize_t jfs_quota_read(struct super_block *sb, int type, char *data,
7210 +static ssize_t jfs_quota_read(struct dqhash *hash, int type, char *data,
7211 size_t len, loff_t off)
7213 - struct inode *inode = sb_dqopt(sb)->files[type];
7214 + struct inode *inode = dqh_dqopt(hash)->files[type];
7215 + struct super_block *sb = hash->dqh_sb;
7216 sector_t blk = off >> sb->s_blocksize_bits;
7218 int offset = off & (sb->s_blocksize - 1);
7219 @@ -660,10 +690,11 @@ static ssize_t jfs_quota_read(struct sup
7222 /* Write to quotafile */
7223 -static ssize_t jfs_quota_write(struct super_block *sb, int type,
7224 +static ssize_t jfs_quota_write(struct dqhash *hash, int type,
7225 const char *data, size_t len, loff_t off)
7227 - struct inode *inode = sb_dqopt(sb)->files[type];
7228 + struct inode *inode = dqh_dqopt(hash)->files[type];
7229 + struct super_block *sb = hash->dqh_sb;
7230 sector_t blk = off >> sb->s_blocksize_bits;
7232 int offset = off & (sb->s_blocksize - 1);
7233 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/xattr.c
7234 --- linux-2.6.19.1/fs/jfs/xattr.c 2006-11-30 21:19:26 +0100
7235 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/xattr.c 2006-11-08 21:52:09 +0100
7237 #include <linux/posix_acl_xattr.h>
7238 #include <linux/quotaops.h>
7239 #include <linux/security.h>
7240 +#include <linux/vs_dlimit.h>
7241 #include "jfs_incore.h"
7242 #include "jfs_superblock.h"
7243 #include "jfs_dmap.h"
7244 @@ -263,9 +264,16 @@ static int ea_write(struct inode *ip, st
7245 if (DQUOT_ALLOC_BLOCK(ip, nblocks)) {
7248 + /* Allocate new blocks to dlimit. */
7249 + if (DLIMIT_ALLOC_BLOCK(ip, nblocks)) {
7250 + DQUOT_FREE_BLOCK(ip, nblocks);
7254 rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno);
7256 + /*Rollback dlimit allocation. */
7257 + DLIMIT_FREE_BLOCK(ip, nblocks);
7258 /*Rollback quota allocation. */
7259 DQUOT_FREE_BLOCK(ip, nblocks);
7261 @@ -332,6 +340,8 @@ static int ea_write(struct inode *ip, st
7264 /* Rollback quota allocation. */
7265 + DLIMIT_FREE_BLOCK(ip, nblocks);
7266 + /* Rollback quota allocation. */
7267 DQUOT_FREE_BLOCK(ip, nblocks);
7269 dbFree(ip, blkno, nblocks);
7270 @@ -468,6 +478,7 @@ static int ea_get(struct inode *inode, s
7273 int quota_allocation = 0;
7274 + int dlimit_allocation = 0;
7276 /* When fsck.jfs clears a bad ea, it doesn't clear the size */
7277 if (ji->ea.flag == 0)
7278 @@ -543,6 +554,12 @@ static int ea_get(struct inode *inode, s
7280 quota_allocation = blocks_needed;
7282 + /* Allocate new blocks to dlimit. */
7284 + if (DLIMIT_ALLOC_BLOCK(inode, blocks_needed))
7286 + dlimit_allocation = blocks_needed;
7288 rc = dbAlloc(inode, INOHINT(inode), (s64) blocks_needed,
7291 @@ -599,6 +616,9 @@ static int ea_get(struct inode *inode, s
7295 + /* Rollback dlimit allocation */
7296 + if (dlimit_allocation)
7297 + DLIMIT_FREE_BLOCK(inode, dlimit_allocation);
7298 /* Rollback quota allocation */
7299 if (quota_allocation)
7300 DQUOT_FREE_BLOCK(inode, quota_allocation);
7301 @@ -675,8 +695,10 @@ static int ea_put(tid_t tid, struct inod
7304 /* If old blocks exist, they must be removed from quota allocation. */
7307 + DLIMIT_FREE_BLOCK(inode, old_blocks);
7308 DQUOT_FREE_BLOCK(inode, old_blocks);
7311 inode->i_ctime = CURRENT_TIME;
7313 diff -NurpP --minimal linux-2.6.19.1/fs/libfs.c linux-2.6.19.1-vs2.3.0.6/fs/libfs.c
7314 --- linux-2.6.19.1/fs/libfs.c 2006-11-30 21:19:26 +0100
7315 +++ linux-2.6.19.1-vs2.3.0.6/fs/libfs.c 2006-11-08 04:57:43 +0100
7316 @@ -124,7 +124,8 @@ static inline unsigned char dt_type(stru
7317 * both impossible due to the lock on directory.
7320 -int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
7321 +static inline int do_dcache_readdir_filter(struct file * filp,
7322 + void * dirent, filldir_t filldir, int (*filter)(struct dentry *dentry))
7324 struct dentry *dentry = filp->f_dentry;
7325 struct dentry *cursor = filp->private_data;
7326 @@ -157,6 +158,8 @@ int dcache_readdir(struct file * filp, v
7327 next = list_entry(p, struct dentry, d_u.d_child);
7328 if (d_unhashed(next) || !next->d_inode)
7330 + if (filter && !filter(next))
7333 spin_unlock(&dcache_lock);
7334 if (filldir(dirent, next->d_name.name, next->d_name.len, filp->f_pos, next->d_inode->i_ino, dt_type(next->d_inode)) < 0)
7335 @@ -172,6 +175,18 @@ int dcache_readdir(struct file * filp, v
7339 +int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
7341 + return do_dcache_readdir_filter(filp, dirent, filldir, NULL);
7344 +int dcache_readdir_filter(struct file * filp, void * dirent, filldir_t filldir,
7345 + int (*filter)(struct dentry *))
7347 + return do_dcache_readdir_filter(filp, dirent, filldir, filter);
7351 ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
7354 @@ -611,6 +626,7 @@ EXPORT_SYMBOL(dcache_dir_close);
7355 EXPORT_SYMBOL(dcache_dir_lseek);
7356 EXPORT_SYMBOL(dcache_dir_open);
7357 EXPORT_SYMBOL(dcache_readdir);
7358 +EXPORT_SYMBOL(dcache_readdir_filter);
7359 EXPORT_SYMBOL(generic_read_dir);
7360 EXPORT_SYMBOL(get_sb_pseudo);
7361 EXPORT_SYMBOL(simple_commit_write);
7362 diff -NurpP --minimal linux-2.6.19.1/fs/locks.c linux-2.6.19.1-vs2.3.0.6/fs/locks.c
7363 --- linux-2.6.19.1/fs/locks.c 2006-11-30 21:19:26 +0100
7364 +++ linux-2.6.19.1-vs2.3.0.6/fs/locks.c 2006-11-30 18:53:18 +0100
7366 #include <linux/syscalls.h>
7367 #include <linux/time.h>
7368 #include <linux/rcupdate.h>
7369 +#include <linux/vs_base.h>
7370 +#include <linux/vs_limit.h>
7372 #include <asm/semaphore.h>
7373 #include <asm/uaccess.h>
7374 @@ -147,6 +149,8 @@ static kmem_cache_t *filelock_cache __re
7375 /* Allocate an empty lock structure. */
7376 static struct file_lock *locks_alloc_lock(void)
7378 + if (!vx_locks_avail(1))
7380 return kmem_cache_alloc(filelock_cache, SLAB_KERNEL);
7383 @@ -172,6 +176,7 @@ static void locks_free_lock(struct file_
7384 BUG_ON(!list_empty(&fl->fl_block));
7385 BUG_ON(!list_empty(&fl->fl_link));
7388 locks_release_private(fl);
7389 kmem_cache_free(filelock_cache, fl);
7391 @@ -191,6 +196,7 @@ void locks_init_lock(struct file_lock *f
7392 fl->fl_start = fl->fl_end = 0;
7394 fl->fl_lmops = NULL;
7398 EXPORT_SYMBOL(locks_init_lock);
7399 @@ -248,6 +254,7 @@ void locks_copy_lock(struct file_lock *n
7400 new->fl_file = fl->fl_file;
7401 new->fl_ops = fl->fl_ops;
7402 new->fl_lmops = fl->fl_lmops;
7403 + new->fl_xid = fl->fl_xid;
7405 locks_copy_private(new, fl);
7407 @@ -286,6 +293,11 @@ static int flock_make_lock(struct file *
7408 fl->fl_flags = FL_FLOCK;
7410 fl->fl_end = OFFSET_MAX;
7412 + vxd_assert(filp->f_xid == vx_current_xid(),
7413 + "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
7414 + fl->fl_xid = filp->f_xid;
7419 @@ -451,6 +463,7 @@ static int lease_init(struct file *filp,
7421 fl->fl_owner = current->files;
7422 fl->fl_pid = current->tgid;
7423 + fl->fl_xid = vx_current_xid();
7426 fl->fl_flags = FL_LEASE;
7427 @@ -470,6 +483,11 @@ static int lease_alloc(struct file *filp
7431 + fl->fl_xid = vx_current_xid();
7433 + vxd_assert(filp->f_xid == fl->fl_xid,
7434 + "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid);
7436 error = lease_init(filp, type, fl);
7438 locks_free_lock(fl);
7439 @@ -790,6 +808,7 @@ find_conflict:
7440 if (request->fl_flags & FL_ACCESS)
7442 locks_copy_lock(new_fl, request);
7443 + vx_locks_inc(new_fl);
7444 locks_insert_lock(&inode->i_flock, new_fl);
7447 @@ -801,7 +820,8 @@ out:
7451 -static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
7452 +static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request,
7453 + struct file_lock *conflock, xid_t xid)
7455 struct file_lock *fl;
7456 struct file_lock *new_fl = NULL;
7457 @@ -811,6 +831,8 @@ static int __posix_lock_file_conf(struct
7458 struct file_lock **before;
7459 int error, added = 0;
7461 + vxd_assert(xid == vx_current_xid(),
7462 + "xid(%d) == current(%d)", xid, vx_current_xid());
7464 * We may need two file_lock structures for this operation,
7465 * so we get them in advance to avoid races.
7466 @@ -821,7 +843,11 @@ static int __posix_lock_file_conf(struct
7467 (request->fl_type != F_UNLCK ||
7468 request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
7469 new_fl = locks_alloc_lock();
7470 + new_fl->fl_xid = xid;
7471 + vx_locks_inc(new_fl);
7472 new_fl2 = locks_alloc_lock();
7473 + new_fl2->fl_xid = xid;
7474 + vx_locks_inc(new_fl2);
7478 @@ -1018,7 +1044,8 @@ static int __posix_lock_file_conf(struct
7480 int posix_lock_file(struct file *filp, struct file_lock *fl)
7482 - return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, NULL);
7483 + return __posix_lock_file_conf(filp->f_dentry->d_inode,
7484 + fl, NULL, filp->f_xid);
7486 EXPORT_SYMBOL(posix_lock_file);
7488 @@ -1033,7 +1060,8 @@ EXPORT_SYMBOL(posix_lock_file);
7489 int posix_lock_file_conf(struct file *filp, struct file_lock *fl,
7490 struct file_lock *conflock)
7492 - return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, conflock);
7493 + return __posix_lock_file_conf(filp->f_dentry->d_inode,
7494 + fl, conflock, filp->f_xid);
7496 EXPORT_SYMBOL(posix_lock_file_conf);
7498 @@ -1123,7 +1151,7 @@ int locks_mandatory_area(int read_write,
7499 fl.fl_end = offset + count - 1;
7502 - error = __posix_lock_file_conf(inode, &fl, NULL);
7503 + error = __posix_lock_file_conf(inode, &fl, NULL, filp->f_xid);
7504 if (error != -EAGAIN)
7506 if (!(fl.fl_flags & FL_SLEEP))
7507 @@ -1685,6 +1713,11 @@ int fcntl_setlk(unsigned int fd, struct
7508 if (file_lock == NULL)
7511 + vxd_assert(filp->f_xid == vx_current_xid(),
7512 + "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
7513 + file_lock->fl_xid = filp->f_xid;
7514 + vx_locks_inc(file_lock);
7517 * This might block, so we do it before checking the inode.
7519 @@ -1828,6 +1861,11 @@ int fcntl_setlk64(unsigned int fd, struc
7520 if (file_lock == NULL)
7523 + vxd_assert(filp->f_xid == vx_current_xid(),
7524 + "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
7525 + file_lock->fl_xid = filp->f_xid;
7526 + vx_locks_inc(file_lock);
7529 * This might block, so we do it before checking the inode.
7531 @@ -2123,6 +2161,10 @@ int get_locks_status(char *buffer, char
7532 list_for_each(tmp, &file_lock_list) {
7533 struct list_head *btmp;
7534 struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
7536 + if (!vx_check(fl->fl_xid, VS_WATCH_P|VS_IDENT))
7539 lock_get_status(q, fl, ++i, "");
7540 move_lock_status(&q, &pos, offset);
7542 diff -NurpP --minimal linux-2.6.19.1/fs/namei.c linux-2.6.19.1-vs2.3.0.6/fs/namei.c
7543 --- linux-2.6.19.1/fs/namei.c 2006-11-30 21:19:26 +0100
7544 +++ linux-2.6.19.1-vs2.3.0.6/fs/namei.c 2006-11-30 19:41:35 +0100
7546 #include <linux/file.h>
7547 #include <linux/fcntl.h>
7548 #include <linux/namei.h>
7549 +#include <linux/proc_fs.h>
7550 +#include <linux/vserver/inode.h>
7551 +#include <linux/vs_base.h>
7552 +#include <linux/vs_tag.h>
7553 +#include <linux/vs_cowbl.h>
7554 #include <asm/namei.h>
7555 #include <asm/uaccess.h>
7557 @@ -225,6 +230,31 @@ int generic_permission(struct inode *ino
7561 +static inline int dx_barrier(struct inode *inode)
7563 + if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN)) {
7564 + vxwprintk(1, "xid=%d did hit the barrier.",
7565 + vx_current_xid());
7571 +static inline int dx_permission(struct inode *inode, int mask, struct nameidata *nd)
7573 + if (dx_barrier(inode))
7575 + if (inode->i_tag == 0)
7577 + if (dx_check(inode->i_tag, DX_ADMIN|DX_WATCH|DX_IDENT))
7580 + vxwprintk(1, "xid=%d denied access to %p[#%d,%lu] »%s«.",
7581 + vx_current_xid(), inode, inode->i_tag, inode->i_ino,
7582 + vxd_cond_path(nd));
7586 int permission(struct inode *inode, int mask, struct nameidata *nd)
7588 umode_t mode = inode->i_mode;
7589 @@ -235,14 +265,14 @@ int permission(struct inode *inode, int
7591 * Nobody gets write access to a read-only fs.
7593 - if (IS_RDONLY(inode) &&
7594 + if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
7595 (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
7599 * Nobody gets write access to an immutable file.
7601 - if (IS_IMMUTABLE(inode))
7602 + if (IS_IMMUTABLE(inode) && !IS_COW(inode))
7606 @@ -256,6 +286,8 @@ int permission(struct inode *inode, int
7608 /* Ordinary permission routines do not understand MAY_APPEND. */
7609 submask = mask & ~MAY_APPEND;
7610 + if ((retval = dx_permission(inode, mask, nd)))
7612 if (inode->i_op && inode->i_op->permission)
7613 retval = inode->i_op->permission(inode, submask, nd);
7615 @@ -431,6 +463,8 @@ static int exec_permission_lite(struct i
7617 umode_t mode = inode->i_mode;
7619 + if (dx_barrier(inode))
7621 if (inode->i_op && inode->i_op->permission)
7624 @@ -736,7 +770,8 @@ static __always_inline void follow_dotdo
7625 if (nd->dentry == fs->root &&
7626 nd->mnt == fs->rootmnt) {
7627 read_unlock(&fs->lock);
7629 + /* FIXME: for sane '/' avoid follow_mount() */
7632 read_unlock(&fs->lock);
7633 spin_lock(&dcache_lock);
7634 @@ -773,16 +808,34 @@ static int do_lookup(struct nameidata *n
7636 struct vfsmount *mnt = nd->mnt;
7637 struct dentry *dentry = __d_lookup(nd->dentry, name);
7638 + struct inode *inode;
7642 if (dentry->d_op && dentry->d_op->d_revalidate)
7643 goto need_revalidate;
7644 + inode = dentry->d_inode;
7647 + if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
7648 + struct proc_dir_entry *de = PDE(inode);
7650 + if (de && !vx_hide_check(0, de->vx_flags))
7653 + if (!dx_check(inode->i_tag, DX_WATCH|DX_ADMIN|DX_HOSTID|DX_IDENT))
7657 path->dentry = dentry;
7658 __follow_mount(path);
7661 + vxwprintk(1, "xid=%d did lookup hidden %p[#%d,%lu] »%s«.",
7662 + vx_current_xid(), inode, inode->i_tag, inode->i_ino,
7663 + vxd_path(dentry, mnt));
7668 dentry = real_lookup(nd->dentry, name, nd);
7669 @@ -1384,7 +1437,8 @@ static inline int check_sticky(struct in
7670 * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
7671 * nfs_async_unlink().
7673 -static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
7674 +static int may_delete(struct inode *dir, struct dentry *victim,
7675 + int isdir, struct nameidata *nd)
7679 @@ -1394,13 +1448,13 @@ static int may_delete(struct inode *dir,
7680 BUG_ON(victim->d_parent->d_inode != dir);
7681 audit_inode_child(victim->d_name.name, victim->d_inode, dir);
7683 - error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
7684 + error = permission(dir,MAY_WRITE | MAY_EXEC, nd);
7689 if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
7690 - IS_IMMUTABLE(victim->d_inode))
7691 + IS_IXORUNLINK(victim->d_inode))
7694 if (!S_ISDIR(victim->d_inode->i_mode))
7695 @@ -1531,6 +1585,14 @@ int may_open(struct nameidata *nd, int a
7696 if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
7699 +#ifdef CONFIG_VSERVER_COWBL
7700 + if (IS_COW(inode) && (flag & FMODE_WRITE)) {
7701 + if (IS_COW_LINK(inode))
7703 + inode->i_flags &= ~(S_IUNLINK|S_IMMUTABLE);
7704 + mark_inode_dirty(inode);
7707 error = vfs_permission(nd, acc_mode);
7710 @@ -1547,7 +1609,8 @@ int may_open(struct nameidata *nd, int a
7714 - } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
7715 + } else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
7716 + && (flag & FMODE_WRITE))
7719 * An append-only file must be opened in append mode for writing.
7720 @@ -1635,6 +1698,11 @@ int open_namei(int dfd, const char *path
7724 +#ifdef CONFIG_VSERVER_COWBL
7729 acc_mode = ACC_MODE(flag);
7731 /* O_TRUNC implies we need access checks for write permissions */
7732 @@ -1728,6 +1796,22 @@ do_last:
7735 error = may_open(nd, acc_mode, flag);
7736 +#ifdef CONFIG_VSERVER_COWBL
7737 + if (error == -EMLINK) {
7738 + struct dentry *dentry;
7739 + dentry = cow_break_link(pathname);
7740 + if (IS_ERR(dentry)) {
7741 + error = PTR_ERR(dentry);
7745 + release_open_intent(nd);
7755 @@ -1839,9 +1923,10 @@ fail:
7757 EXPORT_SYMBOL_GPL(lookup_create);
7759 -int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
7760 +int vfs_mknod(struct inode *dir, struct dentry *dentry,
7761 + int mode, dev_t dev, struct nameidata *nd)
7763 - int error = may_create(dir, dentry, NULL);
7764 + int error = may_create(dir, dentry, nd);
7768 @@ -1891,11 +1976,12 @@ asmlinkage long sys_mknodat(int dfd, con
7769 error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
7771 case S_IFCHR: case S_IFBLK:
7772 - error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
7773 - new_decode_dev(dev));
7774 + error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
7775 + new_decode_dev(dev), &nd);
7777 case S_IFIFO: case S_IFSOCK:
7778 - error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
7779 + error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
7784 @@ -1918,9 +2004,10 @@ asmlinkage long sys_mknod(const char __u
7785 return sys_mknodat(AT_FDCWD, filename, mode, dev);
7788 -int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
7789 +int vfs_mkdir(struct inode *dir, struct dentry *dentry,
7790 + int mode, struct nameidata *nd)
7792 - int error = may_create(dir, dentry, NULL);
7793 + int error = may_create(dir, dentry, nd);
7797 @@ -1962,7 +2049,7 @@ asmlinkage long sys_mkdirat(int dfd, con
7799 if (!IS_POSIXACL(nd.dentry->d_inode))
7800 mode &= ~current->fs->umask;
7801 - error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
7802 + error = vfs_mkdir(nd.dentry->d_inode, dentry, mode, &nd);
7805 mutex_unlock(&nd.dentry->d_inode->i_mutex);
7806 @@ -2006,9 +2093,10 @@ void dentry_unhash(struct dentry *dentry
7807 spin_unlock(&dcache_lock);
7810 -int vfs_rmdir(struct inode *dir, struct dentry *dentry)
7811 +int vfs_rmdir(struct inode *dir, struct dentry *dentry,
7812 + struct nameidata *nd)
7814 - int error = may_delete(dir, dentry, 1);
7815 + int error = may_delete(dir, dentry, 1, nd);
7819 @@ -2070,7 +2158,7 @@ static long do_rmdir(int dfd, const char
7820 error = PTR_ERR(dentry);
7823 - error = vfs_rmdir(nd.dentry->d_inode, dentry);
7824 + error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
7827 mutex_unlock(&nd.dentry->d_inode->i_mutex);
7828 @@ -2086,9 +2174,10 @@ asmlinkage long sys_rmdir(const char __u
7829 return do_rmdir(AT_FDCWD, pathname);
7832 -int vfs_unlink(struct inode *dir, struct dentry *dentry)
7833 +int vfs_unlink(struct inode *dir, struct dentry *dentry,
7834 + struct nameidata *nd)
7836 - int error = may_delete(dir, dentry, 0);
7837 + int error = may_delete(dir, dentry, 0, nd);
7841 @@ -2150,7 +2239,7 @@ static long do_unlinkat(int dfd, const c
7842 inode = dentry->d_inode;
7844 atomic_inc(&inode->i_count);
7845 - error = vfs_unlink(nd.dentry->d_inode, dentry);
7846 + error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
7850 @@ -2185,9 +2274,10 @@ asmlinkage long sys_unlink(const char __
7851 return do_unlinkat(AT_FDCWD, pathname);
7854 -int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
7855 +int vfs_symlink(struct inode *dir, struct dentry *dentry,
7856 + const char *oldname, int mode, struct nameidata *nd)
7858 - int error = may_create(dir, dentry, NULL);
7859 + int error = may_create(dir, dentry, nd);
7863 @@ -2231,7 +2321,7 @@ asmlinkage long sys_symlinkat(const char
7867 - error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
7868 + error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO, &nd);
7871 mutex_unlock(&nd.dentry->d_inode->i_mutex);
7872 @@ -2248,7 +2338,8 @@ asmlinkage long sys_symlink(const char _
7873 return sys_symlinkat(oldname, AT_FDCWD, newname);
7876 -int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
7877 +int vfs_link(struct dentry *old_dentry, struct inode *dir,
7878 + struct dentry *new_dentry, struct nameidata *nd)
7880 struct inode *inode = old_dentry->d_inode;
7882 @@ -2256,7 +2347,7 @@ int vfs_link(struct dentry *old_dentry,
7886 - error = may_create(dir, new_dentry, NULL);
7887 + error = may_create(dir, new_dentry, nd);
7891 @@ -2266,7 +2357,7 @@ int vfs_link(struct dentry *old_dentry,
7893 * A link to an append-only or immutable file cannot be created.
7895 - if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
7896 + if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
7898 if (!dir->i_op || !dir->i_op->link)
7900 @@ -2326,7 +2417,7 @@ asmlinkage long sys_linkat(int olddfd, c
7901 error = PTR_ERR(new_dentry);
7902 if (IS_ERR(new_dentry))
7904 - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
7905 + error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry, &nd);
7908 mutex_unlock(&nd.dentry->d_inode->i_mutex);
7909 @@ -2458,14 +2549,14 @@ int vfs_rename(struct inode *old_dir, st
7910 if (old_dentry->d_inode == new_dentry->d_inode)
7913 - error = may_delete(old_dir, old_dentry, is_dir);
7914 + error = may_delete(old_dir, old_dentry, is_dir, NULL);
7918 if (!new_dentry->d_inode)
7919 error = may_create(new_dir, new_dentry, NULL);
7921 - error = may_delete(new_dir, new_dentry, is_dir);
7922 + error = may_delete(new_dir, new_dentry, is_dir, NULL);
7926 @@ -2543,6 +2634,9 @@ static int do_rename(int olddfd, const c
7928 if (old_dentry == trap)
7931 + if (MNT_IS_RDONLY(newnd.mnt))
7933 new_dentry = lookup_hash(&newnd);
7934 error = PTR_ERR(new_dentry);
7935 if (IS_ERR(new_dentry))
7936 @@ -2636,6 +2730,126 @@ int vfs_follow_link(struct nameidata *nd
7937 return __vfs_follow_link(nd, link);
7941 +#ifdef CONFIG_VSERVER_COWBL
7943 +#include <linux/file.h>
7945 +struct dentry *cow_break_link(const char *pathname)
7947 + int ret, mode, pathlen;
7948 + struct nameidata old_nd, dir_nd;
7949 + struct dentry *old_dentry, *new_dentry;
7950 + struct dentry *res = ERR_PTR(-EMLINK);
7951 + struct vfsmount *old_mnt, *new_mnt;
7952 + struct file *old_file;
7953 + struct file *new_file;
7954 + char *to, *path, pad='\251';
7957 + vxdprintk(VXD_CBIT(misc, 1), "cow_break_link(»%s«)", pathname);
7958 + path = kmalloc(PATH_MAX, GFP_KERNEL);
7960 + ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd);
7961 + vxdprintk(VXD_CBIT(misc, 2), "path_lookup(old): %d", ret);
7962 + old_dentry = old_nd.dentry;
7963 + old_mnt = old_nd.mnt;
7964 + mode = old_dentry->d_inode->i_mode;
7966 + to = d_path(old_dentry, old_mnt, path, PATH_MAX-2);
7967 + pathlen = strlen(to);
7968 + vxdprintk(VXD_CBIT(misc, 2), "old path »%s«", to);
7970 + to[pathlen+1] = 0;
7972 + to[pathlen] = pad--;
7973 + if (pad <= '\240')
7976 + vxdprintk(VXD_CBIT(misc, 1), "temp copy »%s«", to);
7977 + ret = path_lookup(to,
7978 + LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, &dir_nd);
7980 + /* this puppy downs the inode sem */
7981 + new_dentry = lookup_create(&dir_nd, 0);
7982 + vxdprintk(VXD_CBIT(misc, 2),
7983 + "lookup_create(new): %p", new_dentry);
7984 + if (!new_dentry) {
7985 + path_release(&dir_nd);
7989 + ret = vfs_create(dir_nd.dentry->d_inode, new_dentry, mode, &dir_nd);
7990 + vxdprintk(VXD_CBIT(misc, 2),
7991 + "vfs_create(new): %d", ret);
7992 + if (ret == -EEXIST) {
7994 + mutex_unlock(&dir_nd.dentry->d_inode->i_mutex);
7996 + path_release(&dir_nd);
8000 + new_mnt = dir_nd.mnt;
8004 + /* this one cleans up the dentry in case of failure */
8005 + old_file = dentry_open(old_dentry, old_mnt, O_RDONLY);
8006 + vxdprintk(VXD_CBIT(misc, 2),
8007 + "dentry_open(old): %p", old_file);
8009 + goto out_rel_both;
8013 + /* this one cleans up the dentry in case of failure */
8014 + new_file = dentry_open(new_dentry, new_mnt, O_WRONLY);
8015 + vxdprintk(VXD_CBIT(misc, 2),
8016 + "dentry_open(new): %p", new_file);
8018 + goto out_fput_old;
8020 + size = i_size_read(old_file->f_dentry->d_inode);
8021 + ret = vfs_sendfile(new_file, old_file, NULL, size, 0);
8022 + vxdprintk(VXD_CBIT(misc, 2), "vfs_sendfile: %d", ret);
8025 + goto out_fput_both;
8027 + ret = vfs_rename(dir_nd.dentry->d_inode, new_dentry,
8028 + old_nd.dentry->d_parent->d_inode, old_dentry);
8029 + vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
8036 + vxdprintk(VXD_CBIT(misc, 3),
8037 + "fput(new_file=%p[#%d])", new_file,
8038 + atomic_read(&new_file->f_count));
8042 + vxdprintk(VXD_CBIT(misc, 3),
8043 + "fput(old_file=%p[#%d])", old_file,
8044 + atomic_read(&old_file->f_count));
8048 + mutex_unlock(&dir_nd.dentry->d_inode->i_mutex);
8051 + path_release(&dir_nd);
8053 + path_release(&old_nd);
8060 /* get the link contents into pagecache */
8061 static char *page_getlink(struct dentry * dentry, struct page **ppage)
8063 diff -NurpP --minimal linux-2.6.19.1/fs/namespace.c linux-2.6.19.1-vs2.3.0.6/fs/namespace.c
8064 --- linux-2.6.19.1/fs/namespace.c 2006-11-30 21:19:26 +0100
8065 +++ linux-2.6.19.1-vs2.3.0.6/fs/namespace.c 2006-12-05 18:17:10 +0100
8067 #include <linux/security.h>
8068 #include <linux/mount.h>
8069 #include <linux/ramfs.h>
8070 +#include <linux/vs_base.h>
8071 +#include <linux/vserver/space.h>
8072 +#include <linux/vs_context.h>
8073 +#include <linux/vs_tag.h>
8074 #include <asm/uaccess.h>
8075 #include <asm/unistd.h>
8077 @@ -241,6 +245,7 @@ static struct vfsmount *clone_mnt(struct
8078 mnt->mnt_root = dget(root);
8079 mnt->mnt_mountpoint = mnt->mnt_root;
8080 mnt->mnt_parent = mnt;
8081 + mnt->mnt_tag = old->mnt_tag;
8083 if (flag & CL_SLAVE) {
8084 list_add(&mnt->mnt_slave, &old->mnt_slave_list);
8085 @@ -349,43 +354,85 @@ static inline void mangle(struct seq_fil
8086 seq_escape(m, s, " \t\n\\");
8089 +static int mnt_is_reachable(struct vfsmount *mnt)
8091 + struct vfsmount *root_mnt;
8092 + struct dentry *root, *point;
8095 + if (mnt == mnt->mnt_namespace->root)
8098 + spin_lock(&dcache_lock);
8099 + root_mnt = current->fs->rootmnt;
8100 + root = current->fs->root;
8103 + while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) {
8104 + point = mnt->mnt_mountpoint;
8105 + mnt = mnt->mnt_parent;
8108 + ret = (mnt == root_mnt) && is_subdir(point, root);
8110 + spin_unlock(&dcache_lock);
8115 static int show_vfsmnt(struct seq_file *m, void *v)
8117 struct vfsmount *mnt = v;
8119 static struct proc_fs_info {
8127 - { MS_SYNCHRONOUS, ",sync" },
8128 - { MS_DIRSYNC, ",dirsync" },
8129 - { MS_MANDLOCK, ",mand" },
8132 - static struct proc_fs_info mnt_info[] = {
8133 - { MNT_NOSUID, ",nosuid" },
8134 - { MNT_NODEV, ",nodev" },
8135 - { MNT_NOEXEC, ",noexec" },
8136 - { MNT_NOATIME, ",noatime" },
8137 - { MNT_NODIRATIME, ",nodiratime" },
8139 + { MS_RDONLY, MNT_RDONLY, "ro", "rw" },
8140 + { MS_SYNCHRONOUS, 0, ",sync", NULL },
8141 + { MS_DIRSYNC, 0, ",dirsync", NULL },
8142 + { MS_MANDLOCK, 0, ",mand", NULL },
8143 + { MS_TAGGED, 0, ",tag", NULL },
8144 + { MS_NOATIME, MNT_NOATIME, ",noatime", NULL },
8145 + { MS_NODIRATIME, MNT_NODIRATIME, ",nodiratime", NULL },
8146 + { 0, MNT_NOSUID, ",nosuid", NULL },
8147 + { 0, MNT_NODEV, ",nodev", NULL },
8148 + { 0, MNT_NOEXEC, ",noexec", NULL },
8149 + { 0, 0, NULL, NULL }
8151 - struct proc_fs_info *fs_infop;
8152 + struct proc_fs_info *p;
8153 + unsigned long s_flags = mnt->mnt_sb->s_flags;
8154 + int mnt_flags = mnt->mnt_flags;
8156 - mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
8158 - seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
8160 - mangle(m, mnt->mnt_sb->s_type->name);
8161 - seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
8162 - for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
8163 - if (mnt->mnt_sb->s_flags & fs_infop->flag)
8164 - seq_puts(m, fs_infop->str);
8165 + if (vx_flags(VXF_HIDE_MOUNT, 0))
8167 + if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
8170 + if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
8171 + mnt == current->fs->rootmnt) {
8172 + seq_puts(m, "/dev/root / ");
8174 + mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
8176 + seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
8179 - for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
8180 - if (mnt->mnt_flags & fs_infop->flag)
8181 - seq_puts(m, fs_infop->str);
8182 + mangle(m, mnt->mnt_sb->s_type->name);
8184 + for (p = fs_info; (p->s_flag | p->mnt_flag) ; p++) {
8185 + if ((s_flags & p->s_flag) || (mnt_flags & p->mnt_flag)) {
8187 + seq_puts(m, p->set_str);
8190 + seq_puts(m, p->unset_str);
8193 + if (mnt->mnt_flags & MNT_TAGID)
8194 + seq_printf(m, ",tag=%d", mnt->mnt_tag);
8195 if (mnt->mnt_sb->s_op->show_options)
8196 err = mnt->mnt_sb->s_op->show_options(m, mnt);
8197 seq_puts(m, " 0 0\n");
8198 @@ -404,17 +451,27 @@ static int show_vfsstat(struct seq_file
8199 struct vfsmount *mnt = v;
8203 - if (mnt->mnt_devname) {
8204 - seq_puts(m, "device ");
8205 - mangle(m, mnt->mnt_devname);
8207 - seq_puts(m, "no device");
8208 + if (vx_flags(VXF_HIDE_MOUNT, 0))
8210 + if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
8214 - seq_puts(m, " mounted on ");
8215 - seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
8217 + if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
8218 + mnt == current->fs->rootmnt) {
8219 + seq_puts(m, "device /dev/root mounted on / ");
8222 + if (mnt->mnt_devname) {
8223 + seq_puts(m, "device ");
8224 + mangle(m, mnt->mnt_devname);
8226 + seq_puts(m, "no device");
8229 + seq_puts(m, " mounted on ");
8230 + seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
8234 /* file system type */
8235 seq_puts(m, "with fstype ");
8236 @@ -595,7 +652,7 @@ static int do_umount(struct vfsmount *mn
8237 down_write(&sb->s_umount);
8238 if (!(sb->s_flags & MS_RDONLY)) {
8241 + DQUOT_OFF(sb->s_dqh);
8242 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
8245 @@ -644,7 +701,7 @@ asmlinkage long sys_umount(char __user *
8249 - if (!capable(CAP_SYS_ADMIN))
8250 + if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
8253 retval = do_umount(nd.mnt, flags);
8254 @@ -668,7 +725,7 @@ asmlinkage long sys_oldumount(char __use
8256 static int mount_is_safe(struct nameidata *nd)
8258 - if (capable(CAP_SYS_ADMIN))
8259 + if (vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
8263 @@ -897,11 +954,13 @@ static int do_change_type(struct nameida
8265 * do loopback mount.
8267 -static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
8268 +static int do_loopback(struct nameidata *nd, char *old_name, tag_t tag,
8269 + unsigned long flags, int mnt_flags)
8271 struct nameidata old_nd;
8272 struct vfsmount *mnt = NULL;
8273 int err = mount_is_safe(nd);
8274 + int recurse = flags & MS_REC;
8277 if (!old_name || !*old_name)
8278 @@ -927,6 +986,12 @@ static int do_loopback(struct nameidata
8282 + mnt->mnt_flags = mnt_flags;
8283 + if (flags & MS_TAGID) {
8284 + mnt->mnt_tag = tag;
8285 + mnt->mnt_flags |= MNT_TAGID;
8288 err = graft_tree(mnt, nd);
8290 LIST_HEAD(umount_list);
8291 @@ -935,6 +1000,7 @@ static int do_loopback(struct nameidata
8292 spin_unlock(&vfsmount_lock);
8293 release_mounts(&umount_list);
8295 + mnt->mnt_flags = mnt_flags;
8298 up_write(&namespace_sem);
8299 @@ -948,12 +1014,12 @@ out:
8300 * on it - tough luck.
8302 static int do_remount(struct nameidata *nd, int flags, int mnt_flags,
8304 + void *data, xid_t xid)
8307 struct super_block *sb = nd->mnt->mnt_sb;
8309 - if (!capable(CAP_SYS_ADMIN))
8310 + if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_REMOUNT))
8313 if (!check_mnt(nd->mnt))
8314 @@ -987,7 +1053,7 @@ static int do_move_mount(struct nameidat
8315 struct nameidata old_nd, parent_nd;
8318 - if (!capable(CAP_SYS_ADMIN))
8319 + if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
8321 if (!old_name || !*old_name)
8323 @@ -1067,7 +1133,7 @@ static int do_new_mount(struct nameidata
8326 /* we need capabilities... */
8327 - if (!capable(CAP_SYS_ADMIN))
8328 + if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
8331 mnt = do_kern_mount(type, flags, name, data);
8332 @@ -1379,6 +1445,7 @@ long do_mount(char *dev_name, char *dir_
8333 struct nameidata nd;
8339 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
8340 @@ -1394,7 +1461,19 @@ long do_mount(char *dev_name, char *dir_
8342 ((char *)data_page)[PAGE_SIZE - 1] = 0;
8344 +#ifdef CONFIG_PROPAGATE
8345 + retval = dx_parse_tag(data_page, &tag, 1);
8347 + mnt_flags |= MNT_TAGID;
8348 + /* bind and re-mounts get the tag flag */
8349 + if (flags & (MS_BIND|MS_REMOUNT))
8350 + flags |= MS_TAGID;
8354 /* Separate the per-mountpoint flags */
8355 + if (flags & MS_RDONLY)
8356 + mnt_flags |= MNT_RDONLY;
8357 if (flags & MS_NOSUID)
8358 mnt_flags |= MNT_NOSUID;
8359 if (flags & MS_NODEV)
8360 @@ -1406,6 +1485,8 @@ long do_mount(char *dev_name, char *dir_
8361 if (flags & MS_NODIRATIME)
8362 mnt_flags |= MNT_NODIRATIME;
8364 + if (!capable(CAP_SYS_ADMIN))
8365 + mnt_flags |= MNT_NODEV;
8366 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
8367 MS_NOATIME | MS_NODIRATIME);
8369 @@ -1420,9 +1501,9 @@ long do_mount(char *dev_name, char *dir_
8371 if (flags & MS_REMOUNT)
8372 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
8375 else if (flags & MS_BIND)
8376 - retval = do_loopback(&nd, dev_name, flags & MS_REC);
8377 + retval = do_loopback(&nd, dev_name, tag, flags, mnt_flags);
8378 else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
8379 retval = do_change_type(&nd, flags);
8380 else if (flags & MS_MOVE)
8381 @@ -1520,7 +1601,7 @@ int copy_namespace(int flags, struct tas
8382 if (!(flags & CLONE_NEWNS))
8385 - if (!capable(CAP_SYS_ADMIN)) {
8386 + if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) {
8390 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/client.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/client.c
8391 --- linux-2.6.19.1/fs/nfs/client.c 2006-11-30 21:19:26 +0100
8392 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/client.c 2006-11-08 04:57:47 +0100
8393 @@ -520,6 +520,9 @@ static int nfs_init_server_rpcclient(str
8394 if (server->flags & NFS4_MOUNT_INTR)
8395 server->client->cl_intr = 1;
8397 + server->client->cl_tag = 0;
8398 + if (server->flags & NFS_MOUNT_TAGGED)
8399 + server->client->cl_tag = 1;
8403 @@ -676,6 +679,10 @@ static void nfs_server_set_fsinfo(struct
8404 server->acdirmin = server->acdirmax = 0;
8407 + /* FIXME: needs fsinfo
8408 + if (server->flags & NFS_MOUNT_TAGGED)
8409 + sb->s_flags |= MS_TAGGED; */
8411 server->maxfilesize = fsinfo->maxfilesize;
8413 /* We're airborne Set socket buffersize */
8414 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/dir.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/dir.c
8415 --- linux-2.6.19.1/fs/nfs/dir.c 2006-11-30 21:19:26 +0100
8416 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/dir.c 2006-11-30 19:09:28 +0100
8418 #include <linux/pagevec.h>
8419 #include <linux/namei.h>
8420 #include <linux/mount.h>
8421 +#include <linux/vs_tag.h>
8423 #include "nfs4_fs.h"
8424 #include "delegation.h"
8425 @@ -933,6 +934,7 @@ static struct dentry *nfs_lookup(struct
8429 + dx_propagate_tag(nd, inode);
8431 res = d_materialise_unique(dentry, inode);
8433 @@ -975,7 +977,8 @@ static int is_atomic_open(struct inode *
8434 if (nd->flags & LOOKUP_DIRECTORY)
8436 /* Are we trying to write to a read only partition? */
8437 - if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
8438 + if ((IS_RDONLY(dir) || MNT_IS_RDONLY(nd->mnt)) &&
8439 + (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
8443 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/inode.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/inode.c
8444 --- linux-2.6.19.1/fs/nfs/inode.c 2006-11-30 21:19:26 +0100
8445 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/inode.c 2006-11-30 18:53:18 +0100
8447 #include <linux/vfs.h>
8448 #include <linux/inet.h>
8449 #include <linux/nfs_xdr.h>
8450 +#include <linux/vs_tag.h>
8452 #include <asm/system.h>
8453 #include <asm/uaccess.h>
8454 @@ -279,8 +280,10 @@ nfs_fhget(struct super_block *sb, struct
8455 nfsi->change_attr = fattr->change_attr;
8456 inode->i_size = nfs_size_to_loff_t(fattr->size);
8457 inode->i_nlink = fattr->nlink;
8458 - inode->i_uid = fattr->uid;
8459 - inode->i_gid = fattr->gid;
8460 + inode->i_uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
8461 + inode->i_gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
8462 + inode->i_tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
8463 + /* maybe fattr->xid someday */
8464 if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
8466 * report the blocks in 512byte units
8467 @@ -369,6 +372,8 @@ void nfs_setattr_update_inode(struct ino
8468 inode->i_uid = attr->ia_uid;
8469 if ((attr->ia_valid & ATTR_GID) != 0)
8470 inode->i_gid = attr->ia_gid;
8471 + if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
8472 + inode->i_tag = attr->ia_tag;
8473 spin_lock(&inode->i_lock);
8474 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
8475 spin_unlock(&inode->i_lock);
8476 @@ -778,6 +783,9 @@ static int nfs_check_inode_attributes(st
8477 struct nfs_inode *nfsi = NFS_I(inode);
8478 loff_t cur_size, new_isize;
8485 /* Has the inode gone and changed behind our back? */
8486 @@ -805,10 +813,15 @@ static int nfs_check_inode_attributes(st
8487 if (cur_size != new_isize && nfsi->npages == 0)
8488 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
8490 + uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
8491 + gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
8492 + tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
8494 /* Have any file permissions changed? */
8495 if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
8496 - || inode->i_uid != fattr->uid
8497 - || inode->i_gid != fattr->gid)
8498 + || inode->i_uid != uid
8499 + || inode->i_gid != gid
8500 + || inode->i_tag != tag)
8501 nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
8503 /* Has the link count changed? */
8504 @@ -898,6 +911,9 @@ static int nfs_update_inode(struct inode
8505 loff_t cur_isize, new_isize;
8506 unsigned int invalid = 0;
8512 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
8513 __FUNCTION__, inode->i_sb->s_id, inode->i_ino,
8514 @@ -970,15 +986,21 @@ static int nfs_update_inode(struct inode
8516 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
8518 + uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
8519 + gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
8520 + tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
8522 if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
8523 - inode->i_uid != fattr->uid ||
8524 - inode->i_gid != fattr->gid)
8525 + inode->i_uid != uid ||
8526 + inode->i_gid != gid ||
8527 + inode->i_tag != tag)
8528 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
8530 inode->i_mode = fattr->mode;
8531 inode->i_nlink = fattr->nlink;
8532 - inode->i_uid = fattr->uid;
8533 - inode->i_gid = fattr->gid;
8534 + inode->i_uid = uid;
8535 + inode->i_gid = gid;
8536 + inode->i_tag = tag;
8538 if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
8540 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/nfs3xdr.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/nfs3xdr.c
8541 --- linux-2.6.19.1/fs/nfs/nfs3xdr.c 2006-11-30 21:19:26 +0100
8542 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/nfs3xdr.c 2006-11-30 18:53:18 +0100
8544 #include <linux/nfs3.h>
8545 #include <linux/nfs_fs.h>
8546 #include <linux/nfsacl.h>
8547 +#include <linux/vs_tag.h>
8548 #include "internal.h"
8550 #define NFSDBG_FACILITY NFSDBG_XDR
8551 @@ -178,7 +179,7 @@ xdr_decode_fattr(__be32 *p, struct nfs_f
8554 static inline __be32 *
8555 -xdr_encode_sattr(__be32 *p, struct iattr *attr)
8556 +xdr_encode_sattr(__be32 *p, struct iattr *attr, int tag)
8558 if (attr->ia_valid & ATTR_MODE) {
8560 @@ -186,15 +187,17 @@ xdr_encode_sattr(__be32 *p, struct iattr
8564 - if (attr->ia_valid & ATTR_UID) {
8565 + if (attr->ia_valid & ATTR_UID ||
8566 + (tag && (attr->ia_valid & ATTR_TAG))) {
8568 - *p++ = htonl(attr->ia_uid);
8569 + *p++ = htonl(TAGINO_UID(tag, attr->ia_uid, attr->ia_tag));
8573 - if (attr->ia_valid & ATTR_GID) {
8574 + if (attr->ia_valid & ATTR_GID ||
8575 + (tag && (attr->ia_valid & ATTR_TAG))) {
8577 - *p++ = htonl(attr->ia_gid);
8578 + *p++ = htonl(TAGINO_GID(tag, attr->ia_gid, attr->ia_tag));
8582 @@ -279,7 +282,8 @@ static int
8583 nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
8585 p = xdr_encode_fhandle(p, args->fh);
8586 - p = xdr_encode_sattr(p, args->sattr);
8587 + p = xdr_encode_sattr(p, args->sattr,
8588 + req->rq_task->tk_client->cl_tag);
8589 *p++ = htonl(args->guard);
8591 p = xdr_encode_time3(p, &args->guardtime);
8592 @@ -370,7 +374,8 @@ nfs3_xdr_createargs(struct rpc_rqst *req
8593 *p++ = args->verifier[0];
8594 *p++ = args->verifier[1];
8596 - p = xdr_encode_sattr(p, args->sattr);
8597 + p = xdr_encode_sattr(p, args->sattr,
8598 + req->rq_task->tk_client->cl_tag);
8600 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
8602 @@ -384,7 +389,8 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req,
8604 p = xdr_encode_fhandle(p, args->fh);
8605 p = xdr_encode_array(p, args->name, args->len);
8606 - p = xdr_encode_sattr(p, args->sattr);
8607 + p = xdr_encode_sattr(p, args->sattr,
8608 + req->rq_task->tk_client->cl_tag);
8609 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
8612 @@ -397,7 +403,8 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *re
8614 p = xdr_encode_fhandle(p, args->fromfh);
8615 p = xdr_encode_array(p, args->fromname, args->fromlen);
8616 - p = xdr_encode_sattr(p, args->sattr);
8617 + p = xdr_encode_sattr(p, args->sattr,
8618 + req->rq_task->tk_client->cl_tag);
8619 *p++ = htonl(args->pathlen);
8620 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
8622 @@ -415,7 +422,8 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req,
8623 p = xdr_encode_fhandle(p, args->fh);
8624 p = xdr_encode_array(p, args->name, args->len);
8625 *p++ = htonl(args->type);
8626 - p = xdr_encode_sattr(p, args->sattr);
8627 + p = xdr_encode_sattr(p, args->sattr,
8628 + req->rq_task->tk_client->cl_tag);
8629 if (args->type == NF3CHR || args->type == NF3BLK) {
8630 *p++ = htonl(MAJOR(args->rdev));
8631 *p++ = htonl(MINOR(args->rdev));
8632 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/nfsroot.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/nfsroot.c
8633 --- linux-2.6.19.1/fs/nfs/nfsroot.c 2006-11-30 21:19:26 +0100
8634 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/nfsroot.c 2006-12-02 01:37:05 +0100
8635 @@ -118,12 +118,12 @@ static int mount_port __initdata = 0; /
8637 /* Options that take integer arguments */
8638 Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin,
8639 - Opt_acregmax, Opt_acdirmin, Opt_acdirmax,
8640 + Opt_acregmax, Opt_acdirmin, Opt_acdirmax, Opt_tagid,
8641 /* Options that take no arguments */
8642 Opt_soft, Opt_hard, Opt_intr,
8643 Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac,
8644 Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
8645 - Opt_acl, Opt_noacl,
8646 + Opt_acl, Opt_noacl, Opt_tag, Opt_notag,
8650 @@ -160,6 +160,10 @@ static match_table_t __initdata tokens =
8653 {Opt_noacl, "noacl"},
8655 + {Opt_notag, "notag"},
8656 + {Opt_tagid, "tagid=%u"},
8657 + {Opt_tag, "tagxid"},
8661 @@ -274,6 +278,20 @@ static int __init root_nfs_parse(char *n
8663 nfs_data.flags |= NFS_MOUNT_NOACL;
8665 +#ifndef CONFIG_TAGGING_NONE
8667 + nfs_data.flags |= NFS_MOUNT_TAGGED;
8670 + nfs_data.flags &= ~NFS_MOUNT_TAGGED;
8673 +#ifdef CONFIG_PROPAGATE
8676 + nfs_data.flags |= NFS_MOUNT_TAGGED;
8680 printk(KERN_WARNING "Root-NFS: unknown "
8682 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/super.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/super.c
8683 --- linux-2.6.19.1/fs/nfs/super.c 2006-11-30 21:19:26 +0100
8684 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/super.c 2006-11-30 18:53:18 +0100
8686 #include <linux/vfs.h>
8687 #include <linux/inet.h>
8688 #include <linux/nfs_xdr.h>
8689 +#include <linux/vs_tag.h>
8691 #include <asm/system.h>
8692 #include <asm/uaccess.h>
8693 @@ -290,6 +291,7 @@ static void nfs_show_mount_options(struc
8694 { NFS_MOUNT_NOAC, ",noac", "" },
8695 { NFS_MOUNT_NONLM, ",nolock", "" },
8696 { NFS_MOUNT_NOACL, ",noacl", "" },
8697 + { NFS_MOUNT_TAGGED, ",tag", "" },
8700 const struct proc_nfs_info *nfs_infop;
8701 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/auth.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/auth.c
8702 --- linux-2.6.19.1/fs/nfsd/auth.c 2006-06-18 04:54:42 +0200
8703 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/auth.c 2006-11-30 18:53:18 +0100
8705 #include <linux/sunrpc/svc.h>
8706 #include <linux/sunrpc/svcauth.h>
8707 #include <linux/nfsd/nfsd.h>
8708 +#include <linux/vs_tag.h>
8710 #define CAP_NFSD_MASK (CAP_FS_MASK|CAP_TO_MASK(CAP_SYS_RESOURCE))
8712 @@ -41,19 +42,22 @@ int nfsd_setuser(struct svc_rqst *rqstp,
8713 get_group_info(cred.cr_group_info);
8715 if (cred.cr_uid != (uid_t) -1)
8716 - current->fsuid = cred.cr_uid;
8717 + current->fsuid = INOTAG_UID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid);
8719 current->fsuid = exp->ex_anon_uid;
8720 if (cred.cr_gid != (gid_t) -1)
8721 - current->fsgid = cred.cr_gid;
8722 + current->fsgid = INOTAG_GID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid);
8724 current->fsgid = exp->ex_anon_gid;
8726 + /* this desperately needs a tag :) */
8727 + current->xid = (xid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
8729 if (!cred.cr_group_info)
8731 ret = set_current_groups(cred.cr_group_info);
8732 put_group_info(cred.cr_group_info);
8733 - if ((cred.cr_uid)) {
8734 + if (INOTAG_UID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid)) {
8735 cap_t(current->cap_effective) &= ~CAP_NFSD_MASK;
8737 cap_t(current->cap_effective) |= (CAP_NFSD_MASK &
8738 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/nfs3xdr.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs3xdr.c
8739 --- linux-2.6.19.1/fs/nfsd/nfs3xdr.c 2006-11-30 21:19:26 +0100
8740 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs3xdr.c 2006-11-30 18:53:18 +0100
8742 #include <linux/sunrpc/svc.h>
8743 #include <linux/nfsd/nfsd.h>
8744 #include <linux/nfsd/xdr3.h>
8745 +#include <linux/vs_tag.h>
8747 #define NFSDDBG_FACILITY NFSDDBG_XDR
8749 @@ -111,6 +112,8 @@ static inline __be32 *
8750 decode_sattr3(__be32 *p, struct iattr *iap)
8758 @@ -120,12 +123,15 @@ decode_sattr3(__be32 *p, struct iattr *i
8761 iap->ia_valid |= ATTR_UID;
8762 - iap->ia_uid = ntohl(*p++);
8763 + uid = ntohl(*p++);
8766 iap->ia_valid |= ATTR_GID;
8767 - iap->ia_gid = ntohl(*p++);
8768 + gid = ntohl(*p++);
8770 + iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid);
8771 + iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid);
8772 + iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0);
8776 @@ -163,8 +169,10 @@ encode_fattr3(struct svc_rqst *rqstp, __
8777 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
8778 *p++ = htonl((u32) stat->mode);
8779 *p++ = htonl((u32) stat->nlink);
8780 - *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
8781 - *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
8782 + *p++ = htonl((u32) nfsd_ruid(rqstp,
8783 + TAGINO_UID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
8784 + *p++ = htonl((u32) nfsd_rgid(rqstp,
8785 + TAGINO_GID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
8786 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
8787 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
8789 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/nfs4recover.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs4recover.c
8790 --- linux-2.6.19.1/fs/nfsd/nfs4recover.c 2006-11-30 21:19:26 +0100
8791 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs4recover.c 2006-11-08 21:53:01 +0100
8792 @@ -156,7 +156,7 @@ nfsd4_create_clid_dir(struct nfs4_client
8793 dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
8796 - status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
8797 + status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU, NULL);
8801 @@ -260,7 +260,7 @@ nfsd4_remove_clid_file(struct dentry *di
8804 mutex_lock(&dir->d_inode->i_mutex);
8805 - status = vfs_unlink(dir->d_inode, dentry);
8806 + status = vfs_unlink(dir->d_inode, dentry, NULL);
8807 mutex_unlock(&dir->d_inode->i_mutex);
8810 @@ -275,7 +275,7 @@ nfsd4_clear_clid_dir(struct dentry *dir,
8811 * a kernel from the future.... */
8812 nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
8813 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
8814 - status = vfs_rmdir(dir->d_inode, dentry);
8815 + status = vfs_rmdir(dir->d_inode, dentry, NULL);
8816 mutex_unlock(&dir->d_inode->i_mutex);
8819 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/nfs4xdr.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs4xdr.c
8820 --- linux-2.6.19.1/fs/nfsd/nfs4xdr.c 2006-11-30 21:19:26 +0100
8821 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs4xdr.c 2006-11-30 18:53:18 +0100
8823 #include <linux/nfsd_idmap.h>
8824 #include <linux/nfs4.h>
8825 #include <linux/nfs4_acl.h>
8826 +#include <linux/vs_tag.h>
8828 #define NFSDDBG_FACILITY NFSDDBG_XDR
8830 @@ -1727,14 +1728,18 @@ out_acl:
8831 WRITE32(stat.nlink);
8833 if (bmval1 & FATTR4_WORD1_OWNER) {
8834 - status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
8835 + status = nfsd4_encode_user(rqstp,
8836 + TAGINO_UID(DX_TAG(dentry->d_inode),
8837 + stat.uid, stat.tag), &p, &buflen);
8838 if (status == nfserr_resource)
8843 if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
8844 - status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
8845 + status = nfsd4_encode_group(rqstp,
8846 + TAGINO_GID(DX_TAG(dentry->d_inode),
8847 + stat.gid, stat.tag), &p, &buflen);
8848 if (status == nfserr_resource)
8851 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/nfsxdr.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfsxdr.c
8852 --- linux-2.6.19.1/fs/nfsd/nfsxdr.c 2006-11-30 21:19:26 +0100
8853 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfsxdr.c 2006-11-30 18:53:18 +0100
8855 #include <linux/nfsd/nfsd.h>
8856 #include <linux/nfsd/xdr.h>
8857 #include <linux/mm.h>
8858 +#include <linux/vs_tag.h>
8860 #define NFSDDBG_FACILITY NFSDDBG_XDR
8862 @@ -102,6 +103,8 @@ static inline __be32 *
8863 decode_sattr(__be32 *p, struct iattr *iap)
8871 @@ -115,12 +118,15 @@ decode_sattr(__be32 *p, struct iattr *ia
8873 if ((tmp = ntohl(*p++)) != (u32)-1) {
8874 iap->ia_valid |= ATTR_UID;
8875 - iap->ia_uid = tmp;
8878 if ((tmp = ntohl(*p++)) != (u32)-1) {
8879 iap->ia_valid |= ATTR_GID;
8880 - iap->ia_gid = tmp;
8883 + iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid);
8884 + iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid);
8885 + iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0);
8886 if ((tmp = ntohl(*p++)) != (u32)-1) {
8887 iap->ia_valid |= ATTR_SIZE;
8889 @@ -164,8 +170,10 @@ encode_fattr(struct svc_rqst *rqstp, __b
8890 *p++ = htonl(nfs_ftypes[type >> 12]);
8891 *p++ = htonl((u32) stat->mode);
8892 *p++ = htonl((u32) stat->nlink);
8893 - *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
8894 - *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
8895 + *p++ = htonl((u32) nfsd_ruid(rqstp,
8896 + TAGINO_UID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
8897 + *p++ = htonl((u32) nfsd_rgid(rqstp,
8898 + TAGINO_GID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
8900 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
8901 *p++ = htonl(NFS_MAXPATHLEN);
8902 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/vfs.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/vfs.c
8903 --- linux-2.6.19.1/fs/nfsd/vfs.c 2006-11-30 21:19:26 +0100
8904 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/vfs.c 2006-11-20 21:12:32 +0100
8905 @@ -1183,13 +1183,13 @@ nfsd_create(struct svc_rqst *rqstp, stru
8906 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
8909 - host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
8910 + host_err = vfs_mkdir(dirp, dchild, iap->ia_mode, NULL);
8916 - host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
8917 + host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev, NULL);
8920 printk("nfsd: bad file type %o in nfsd_create\n", type);
8921 @@ -1474,11 +1474,13 @@ nfsd_symlink(struct svc_rqst *rqstp, str
8923 strncpy(path_alloced, path, plen);
8924 path_alloced[plen] = 0;
8925 - host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
8926 + host_err = vfs_symlink(dentry->d_inode, dnew,
8927 + path_alloced, mode, NULL);
8928 kfree(path_alloced);
8931 - host_err = vfs_symlink(dentry->d_inode, dnew, path, mode);
8932 + host_err = vfs_symlink(dentry->d_inode, dnew,
8933 + path, mode, NULL);
8936 if (EX_ISSYNC(fhp->fh_export))
8937 @@ -1537,7 +1539,7 @@ nfsd_link(struct svc_rqst *rqstp, struct
8938 dold = tfhp->fh_dentry;
8939 dest = dold->d_inode;
8941 - host_err = vfs_link(dold, dirp, dnew);
8942 + host_err = vfs_link(dold, dirp, dnew, NULL);
8944 if (EX_ISSYNC(ffhp->fh_export)) {
8945 err = nfserrno(nfsd_sync_dir(ddir));
8946 @@ -1702,9 +1704,9 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
8950 - host_err = vfs_unlink(dirp, rdentry);
8951 + host_err = vfs_unlink(dirp, rdentry, NULL);
8952 } else { /* It's RMDIR */
8953 - host_err = vfs_rmdir(dirp, rdentry);
8954 + host_err = vfs_rmdir(dirp, rdentry, NULL);
8958 @@ -1815,7 +1817,8 @@ nfsd_permission(struct svc_export *exp,
8960 if (!(acc & MAY_LOCAL_ACCESS))
8961 if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
8962 - if (EX_RDONLY(exp) || IS_RDONLY(inode))
8963 + if (EX_RDONLY(exp) || IS_RDONLY(inode)
8964 + || MNT_IS_RDONLY(exp->ex_mnt))
8966 if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
8968 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/dlm/dlmfs.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlm/dlmfs.c
8969 --- linux-2.6.19.1/fs/ocfs2/dlm/dlmfs.c 2006-11-30 21:19:27 +0100
8970 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlm/dlmfs.c 2006-12-02 01:14:52 +0100
8972 #include <linux/string.h>
8973 #include <linux/smp_lock.h>
8974 #include <linux/backing-dev.h>
8975 +#include <linux/vs_tag.h>
8977 #include <asm/uaccess.h>
8979 @@ -335,6 +336,7 @@ static struct inode *dlmfs_get_root_inod
8980 inode->i_mode = mode;
8981 inode->i_uid = current->fsuid;
8982 inode->i_gid = current->fsgid;
8983 + inode->i_tag = dx_current_fstag(sb);
8984 inode->i_blocks = 0;
8985 inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
8986 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
8987 @@ -361,6 +363,7 @@ static struct inode *dlmfs_get_inode(str
8988 inode->i_mode = mode;
8989 inode->i_uid = current->fsuid;
8990 inode->i_gid = current->fsgid;
8991 + inode->i_tag = dx_current_fstag(sb);
8992 inode->i_blocks = 0;
8993 inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
8994 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
8995 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/dlmglue.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlmglue.c
8996 --- linux-2.6.19.1/fs/ocfs2/dlmglue.c 2006-11-30 21:19:28 +0100
8997 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlmglue.c 2006-12-02 01:19:57 +0100
8998 @@ -1326,6 +1326,7 @@ static void __ocfs2_stuff_meta_lvb(struc
8999 lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
9000 lvb->lvb_iuid = cpu_to_be32(inode->i_uid);
9001 lvb->lvb_igid = cpu_to_be32(inode->i_gid);
9002 + lvb->lvb_itag = cpu_to_be16(inode->i_tag);
9003 lvb->lvb_imode = cpu_to_be16(inode->i_mode);
9004 lvb->lvb_inlink = cpu_to_be16(inode->i_nlink);
9005 lvb->lvb_iatime_packed =
9006 @@ -1379,6 +1380,7 @@ static void ocfs2_refresh_inode_from_lvb
9008 inode->i_uid = be32_to_cpu(lvb->lvb_iuid);
9009 inode->i_gid = be32_to_cpu(lvb->lvb_igid);
9010 + inode->i_tag = be16_to_cpu(lvb->lvb_itag);
9011 inode->i_mode = be16_to_cpu(lvb->lvb_imode);
9012 inode->i_nlink = be16_to_cpu(lvb->lvb_inlink);
9013 ocfs2_unpack_timespec(&inode->i_atime,
9014 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/dlmglue.h linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlmglue.h
9015 --- linux-2.6.19.1/fs/ocfs2/dlmglue.h 2006-11-30 21:19:28 +0100
9016 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlmglue.h 2006-12-02 01:14:52 +0100
9018 struct ocfs2_meta_lvb {
9021 - __be16 lvb_reserved1;
9023 __be32 lvb_iclusters;
9026 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/file.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/file.c
9027 --- linux-2.6.19.1/fs/ocfs2/file.c 2006-11-30 21:19:28 +0100
9028 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/file.c 2006-11-08 04:57:52 +0100
9029 @@ -800,13 +800,15 @@ int ocfs2_setattr(struct dentry *dentry,
9030 mlog(0, "uid change: %d\n", attr->ia_uid);
9031 if (attr->ia_valid & ATTR_GID)
9032 mlog(0, "gid change: %d\n", attr->ia_gid);
9033 + if (attr->ia_valid & ATTR_TAG)
9034 + mlog(0, "tag change: %d\n", attr->ia_tag);
9035 if (attr->ia_valid & ATTR_SIZE)
9036 mlog(0, "size change...\n");
9037 if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME))
9038 mlog(0, "time change...\n");
9040 #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
9041 - | ATTR_GID | ATTR_UID | ATTR_MODE)
9042 + | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE)
9043 if (!(attr->ia_valid & OCFS2_VALID_ATTRS)) {
9044 mlog(0, "can't handle attrs: 0x%x\n", attr->ia_valid);
9046 @@ -1220,6 +1222,7 @@ bail:
9047 struct inode_operations ocfs2_file_iops = {
9048 .setattr = ocfs2_setattr,
9049 .getattr = ocfs2_getattr,
9050 + .sync_flags = ocfs2_sync_flags,
9053 struct inode_operations ocfs2_special_file_iops = {
9054 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/inode.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/inode.c
9055 --- linux-2.6.19.1/fs/ocfs2/inode.c 2006-11-30 21:19:28 +0100
9056 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/inode.c 2006-12-02 01:35:31 +0100
9058 #include <linux/highmem.h>
9059 #include <linux/pagemap.h>
9060 #include <linux/smp_lock.h>
9061 +#include <linux/vs_tag.h>
9063 #include <asm/byteorder.h>
9067 #include "heartbeat.h"
9070 #include "journal.h"
9072 #include "suballoc.h"
9073 @@ -78,6 +80,10 @@ void ocfs2_set_inode_flags(struct inode
9075 if (flags & OCFS2_IMMUTABLE_FL)
9076 inode->i_flags |= S_IMMUTABLE;
9077 + if (flags & OCFS2_IUNLINK_FL)
9078 + inode->i_flags |= S_IUNLINK;
9079 + if (flags & OCFS2_BARRIER_FL)
9080 + inode->i_flags |= S_BARRIER;
9082 if (flags & OCFS2_SYNC_FL)
9083 inode->i_flags |= S_SYNC;
9084 @@ -89,6 +95,39 @@ void ocfs2_set_inode_flags(struct inode
9085 inode->i_flags |= S_DIRSYNC;
9088 +int ocfs2_sync_flags(struct inode *inode)
9090 + unsigned int oldflags, newflags;
9092 + oldflags = OCFS2_I(inode)->ip_flags;
9093 + newflags = oldflags & ~(OCFS2_APPEND_FL |
9094 + OCFS2_IMMUTABLE_FL | OCFS2_IUNLINK_FL |
9095 + OCFS2_BARRIER_FL | OCFS2_NOATIME_FL |
9096 + OCFS2_SYNC_FL | OCFS2_DIRSYNC_FL);
9098 + if (IS_APPEND(inode))
9099 + newflags |= OCFS2_APPEND_FL;
9100 + if (IS_IMMUTABLE(inode))
9101 + newflags |= OCFS2_IMMUTABLE_FL;
9102 + if (IS_IUNLINK(inode))
9103 + newflags |= OCFS2_IUNLINK_FL;
9104 + if (IS_BARRIER(inode))
9105 + newflags |= OCFS2_BARRIER_FL;
9107 + /* we do not want to copy superblock flags */
9108 + if (inode->i_flags & S_NOATIME)
9109 + newflags |= OCFS2_NOATIME_FL;
9110 + if (inode->i_flags & S_SYNC)
9111 + newflags |= OCFS2_SYNC_FL;
9112 + if (inode->i_flags & S_DIRSYNC)
9113 + newflags |= OCFS2_DIRSYNC_FL;
9115 + if (oldflags ^ newflags)
9116 + return ocfs2_set_inode_attr(inode,
9117 + newflags, OCFS2_FL_MASK);
9121 struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb,
9124 @@ -236,6 +275,8 @@ int ocfs2_populate_inode(struct inode *i
9125 struct super_block *sb;
9126 struct ocfs2_super *osb;
9127 int status = -EINVAL;
9131 mlog_entry("(0x%p, size:%llu)\n", inode,
9132 (unsigned long long)fe->i_size);
9133 @@ -267,8 +308,12 @@ int ocfs2_populate_inode(struct inode *i
9134 inode->i_generation = le32_to_cpu(fe->i_generation);
9135 inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
9136 inode->i_mode = le16_to_cpu(fe->i_mode);
9137 - inode->i_uid = le32_to_cpu(fe->i_uid);
9138 - inode->i_gid = le32_to_cpu(fe->i_gid);
9139 + uid = le32_to_cpu(fe->i_uid);
9140 + gid = le32_to_cpu(fe->i_gid);
9141 + inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
9142 + inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
9143 + inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
9144 + /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0);
9146 /* Fast symlinks will have i_size but no allocated clusters. */
9147 if (S_ISLNK(inode->i_mode) && !fe->i_clusters)
9148 @@ -1228,8 +1273,11 @@ int ocfs2_mark_inode_dirty(struct ocfs2_
9150 fe->i_size = cpu_to_le64(i_size_read(inode));
9151 fe->i_links_count = cpu_to_le16(inode->i_nlink);
9152 - fe->i_uid = cpu_to_le32(inode->i_uid);
9153 - fe->i_gid = cpu_to_le32(inode->i_gid);
9154 + fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode),
9155 + inode->i_uid, inode->i_tag));
9156 + fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode),
9157 + inode->i_gid, inode->i_tag));
9158 + /* i_tag = = cpu_to_le16(inode->i_tag); */
9159 fe->i_mode = cpu_to_le16(inode->i_mode);
9160 fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
9161 fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
9162 @@ -1257,15 +1305,24 @@ leave:
9163 void ocfs2_refresh_inode(struct inode *inode,
9164 struct ocfs2_dinode *fe)
9169 spin_lock(&OCFS2_I(inode)->ip_lock);
9171 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
9172 OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
9173 + /* OCFS2_I(inode)->ip_flags &= ~OCFS2_FL_MASK;
9174 + OCFS2_I(inode)->ip_flags |= le32_to_cpu(fe->i_flags) & OCFS2_FL_MASK; */
9175 ocfs2_set_inode_flags(inode);
9176 i_size_write(inode, le64_to_cpu(fe->i_size));
9177 inode->i_nlink = le16_to_cpu(fe->i_links_count);
9178 - inode->i_uid = le32_to_cpu(fe->i_uid);
9179 - inode->i_gid = le32_to_cpu(fe->i_gid);
9180 + uid = le32_to_cpu(fe->i_uid);
9181 + gid = le32_to_cpu(fe->i_gid);
9182 + inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
9183 + inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
9184 + inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
9185 + /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0);
9186 inode->i_mode = le16_to_cpu(fe->i_mode);
9187 if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)
9188 inode->i_blocks = 0;
9189 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/inode.h linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/inode.h
9190 --- linux-2.6.19.1/fs/ocfs2/inode.h 2006-11-30 21:19:28 +0100
9191 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/inode.h 2006-11-08 04:57:46 +0100
9192 @@ -150,5 +150,6 @@ int ocfs2_aio_read(struct file *file, st
9193 int ocfs2_aio_write(struct file *file, struct kiocb *req, struct iocb *iocb);
9195 void ocfs2_set_inode_flags(struct inode *inode);
9196 +int ocfs2_sync_flags(struct inode *inode);
9198 #endif /* OCFS2_INODE_H */
9199 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ioctl.c
9200 --- linux-2.6.19.1/fs/ocfs2/ioctl.c 2006-11-30 21:19:28 +0100
9201 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ioctl.c 2006-12-02 01:28:36 +0100
9202 @@ -38,7 +38,7 @@ static int ocfs2_get_inode_attr(struct i
9206 -static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
9207 +int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
9210 struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
9211 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/ioctl.h linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ioctl.h
9212 --- linux-2.6.19.1/fs/ocfs2/ioctl.h 2006-11-30 21:19:28 +0100
9213 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ioctl.h 2006-12-02 01:29:36 +0100
9215 #ifndef OCFS2_IOCTL_H
9216 #define OCFS2_IOCTL_H
9218 +int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
9221 int ocfs2_ioctl(struct inode * inode, struct file * filp,
9222 unsigned int cmd, unsigned long arg);
9224 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/namei.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/namei.c
9225 --- linux-2.6.19.1/fs/ocfs2/namei.c 2006-11-30 21:19:28 +0100
9226 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/namei.c 2006-11-08 04:57:52 +0100
9228 #include <linux/types.h>
9229 #include <linux/slab.h>
9230 #include <linux/highmem.h>
9231 +#include <linux/vs_tag.h>
9233 #define MLOG_MASK_PREFIX ML_NAMEI
9234 #include <cluster/masklog.h>
9235 @@ -497,6 +498,9 @@ static int ocfs2_mknod_locked(struct ocf
9238 struct inode *inode = NULL;
9243 mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
9244 (unsigned long)dev, dentry->d_name.len,
9245 @@ -556,13 +560,19 @@ static int ocfs2_mknod_locked(struct ocf
9246 fe->i_blkno = cpu_to_le64(fe_blkno);
9247 fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
9248 fe->i_suballoc_slot = cpu_to_le16(osb->slot_num);
9249 - fe->i_uid = cpu_to_le32(current->fsuid);
9251 + tag = dx_current_fstag(osb->sb);
9252 + uid = current->fsuid;
9253 if (dir->i_mode & S_ISGID) {
9254 - fe->i_gid = cpu_to_le32(dir->i_gid);
9259 - fe->i_gid = cpu_to_le32(current->fsgid);
9260 + gid = current->fsgid;
9262 + fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode), uid, tag));
9263 + fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode), gid, tag));
9264 + inode->i_tag = tag;
9265 fe->i_mode = cpu_to_le16(mode);
9266 if (S_ISCHR(mode) || S_ISBLK(mode))
9267 fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
9268 @@ -2300,4 +2310,5 @@ struct inode_operations ocfs2_dir_iops =
9269 .rename = ocfs2_rename,
9270 .setattr = ocfs2_setattr,
9271 .getattr = ocfs2_getattr,
9272 + .sync_flags = ocfs2_sync_flags,
9274 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/ocfs2.h linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ocfs2.h
9275 --- linux-2.6.19.1/fs/ocfs2/ocfs2.h 2006-09-20 16:58:35 +0200
9276 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ocfs2.h 2006-11-08 04:57:52 +0100
9277 @@ -174,6 +174,7 @@ enum ocfs2_mount_options
9278 OCFS2_MOUNT_NOINTR = 1 << 2, /* Don't catch signals */
9279 OCFS2_MOUNT_ERRORS_PANIC = 1 << 3, /* Panic on errors */
9280 OCFS2_MOUNT_DATA_WRITEBACK = 1 << 4, /* No data ordering */
9281 + OCFS2_MOUNT_TAGGED = 1 << 8, /* use tagging */
9284 #define OCFS2_OSB_SOFT_RO 0x0001
9285 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/ocfs2_fs.h linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ocfs2_fs.h
9286 --- linux-2.6.19.1/fs/ocfs2/ocfs2_fs.h 2006-11-30 21:19:28 +0100
9287 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ocfs2_fs.h 2006-12-02 01:33:58 +0100
9288 @@ -125,8 +125,12 @@
9289 #define OCFS2_NOATIME_FL (0x00000080) /* do not update atime */
9290 #define OCFS2_DIRSYNC_FL (0x00010000) /* dirsync behaviour (directories only) */
9292 +#define OCFS2_BARRIER_FL (0x04000000) /* Barrier for chroot() */
9293 +#define OCFS2_IUNLINK_FL (0x08000000) /* Immutable unlink */
9295 #define OCFS2_FL_VISIBLE (0x000100FF) /* User visible flags */
9296 #define OCFS2_FL_MODIFIABLE (0x000100FF) /* User modifiable flags */
9297 +#define OCFS2_FL_MASK (0x0F0100FF)
9301 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/super.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/super.c
9302 --- linux-2.6.19.1/fs/ocfs2/super.c 2006-11-30 21:19:28 +0100
9303 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/super.c 2006-11-08 04:57:52 +0100
9304 @@ -141,6 +141,7 @@ enum {
9308 + Opt_tag, Opt_notag, Opt_tagid,
9312 @@ -154,6 +155,10 @@ static match_table_t tokens = {
9313 {Opt_hb_local, OCFS2_HB_LOCAL},
9314 {Opt_data_ordered, "data=ordered"},
9315 {Opt_data_writeback, "data=writeback"},
9317 + {Opt_tag, "tagxid"},
9318 + {Opt_notag, "notag"},
9319 + {Opt_tagid, "tagid=%u"},
9323 @@ -362,6 +367,14 @@ static int ocfs2_remount(struct super_bl
9327 + printk("ocfs2_remount: %lx,%lx\n", osb->s_mount_opt, sb->s_flags);
9328 + if ((parsed_options & OCFS2_MOUNT_TAGGED) &&
9329 + !(sb->s_flags & MS_TAGGED)) {
9331 + mlog(ML_ERROR, "Cannot change tagging on remount\n");
9335 if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) !=
9336 (parsed_options & OCFS2_MOUNT_HB_LOCAL)) {
9338 @@ -635,6 +648,9 @@ static int ocfs2_fill_super(struct super
9340 ocfs2_complete_mount_recovery(osb);
9342 + if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
9343 + sb->s_flags |= MS_TAGGED;
9345 printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %d, slot %d) "
9346 "with %s data mode.\n",
9347 osb->dev_str, osb->node_num, osb->slot_num,
9348 @@ -747,6 +763,20 @@ static int ocfs2_parse_options(struct su
9349 case Opt_data_writeback:
9350 *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK;
9352 +#ifndef CONFIG_TAGGING_NONE
9354 + *mount_opt |= OCFS2_MOUNT_TAGGED;
9357 + *mount_opt &= ~OCFS2_MOUNT_TAGGED;
9360 +#ifdef CONFIG_PROPAGATE
9363 + *mount_opt |= OCFS2_MOUNT_TAGGED;
9368 "Unrecognized mount option \"%s\" "
9369 diff -NurpP --minimal linux-2.6.19.1/fs/open.c linux-2.6.19.1-vs2.3.0.6/fs/open.c
9370 --- linux-2.6.19.1/fs/open.c 2006-11-30 21:19:28 +0100
9371 +++ linux-2.6.19.1-vs2.3.0.6/fs/open.c 2006-11-30 18:53:18 +0100
9373 #include <linux/syscalls.h>
9374 #include <linux/rcupdate.h>
9375 #include <linux/audit.h>
9376 +#include <linux/vs_base.h>
9377 +#include <linux/vs_limit.h>
9378 +#include <linux/vs_dlimit.h>
9379 +#include <linux/vs_tag.h>
9380 +#include <linux/vs_cowbl.h>
9382 int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
9384 int retval = -ENODEV;
9387 + struct super_block *sb = dentry->d_sb;
9390 - if (dentry->d_sb->s_op->statfs) {
9391 + if (sb->s_op->statfs) {
9392 memset(buf, 0, sizeof(*buf));
9393 retval = security_sb_statfs(dentry);
9396 - retval = dentry->d_sb->s_op->statfs(dentry, buf);
9397 + retval = sb->s_op->statfs(dentry, buf);
9398 if (retval == 0 && buf->f_frsize == 0)
9399 buf->f_frsize = buf->f_bsize;
9401 + if (!vx_check(0, VS_ADMIN|VS_WATCH))
9402 + vx_vsi_statfs(sb, buf);
9406 @@ -246,7 +255,7 @@ static long do_sys_truncate(const char _
9410 - if (IS_RDONLY(inode))
9411 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
9415 @@ -395,7 +404,7 @@ asmlinkage long sys_faccessat(int dfd, c
9416 special_file(nd.dentry->d_inode->i_mode))
9417 goto out_path_release;
9419 - if(IS_RDONLY(nd.dentry->d_inode))
9420 + if(IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
9424 @@ -509,7 +518,7 @@ asmlinkage long sys_fchmod(unsigned int
9425 audit_inode(NULL, inode);
9428 - if (IS_RDONLY(inode))
9429 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt))
9432 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9433 @@ -539,11 +548,11 @@ asmlinkage long sys_fchmodat(int dfd, co
9434 error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
9437 - inode = nd.dentry->d_inode;
9440 - if (IS_RDONLY(inode))
9441 + error = cow_check_and_break(&nd);
9444 + inode = nd.dentry->d_inode;
9447 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9448 @@ -568,7 +577,8 @@ asmlinkage long sys_chmod(const char __u
9449 return sys_fchmodat(AT_FDCWD, filename, mode);
9452 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
9453 +static int chown_common(struct dentry *dentry, struct vfsmount *mnt,
9454 + uid_t user, gid_t group)
9456 struct inode * inode;
9458 @@ -580,7 +590,7 @@ static int chown_common(struct dentry *
9462 - if (IS_RDONLY(inode))
9463 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
9466 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9467 @@ -588,11 +598,11 @@ static int chown_common(struct dentry *
9468 newattrs.ia_valid = ATTR_CTIME;
9469 if (user != (uid_t) -1) {
9470 newattrs.ia_valid |= ATTR_UID;
9471 - newattrs.ia_uid = user;
9472 + newattrs.ia_uid = dx_map_uid(user);
9474 if (group != (gid_t) -1) {
9475 newattrs.ia_valid |= ATTR_GID;
9476 - newattrs.ia_gid = group;
9477 + newattrs.ia_gid = dx_map_gid(group);
9479 if (!S_ISDIR(inode->i_mode))
9480 newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
9481 @@ -611,7 +621,11 @@ asmlinkage long sys_chown(const char __u
9482 error = user_path_walk(filename, &nd);
9485 - error = chown_common(nd.dentry, user, group);
9486 +#ifdef CONFIG_VSERVER_COWBL
9487 + error = cow_check_and_break(&nd);
9490 + error = chown_common(nd.dentry, nd.mnt, user, group);
9494 @@ -631,7 +645,11 @@ asmlinkage long sys_fchownat(int dfd, co
9495 error = __user_walk_fd(dfd, filename, follow, &nd);
9498 - error = chown_common(nd.dentry, user, group);
9499 +#ifdef CONFIG_VSERVER_COWBL
9500 + error = cow_check_and_break(&nd);
9503 + error = chown_common(nd.dentry, nd.mnt, user, group);
9507 @@ -645,7 +663,11 @@ asmlinkage long sys_lchown(const char __
9508 error = user_path_walk_link(filename, &nd);
9511 - error = chown_common(nd.dentry, user, group);
9512 +#ifdef CONFIG_VSERVER_COWBL
9513 + error = cow_check_and_break(&nd);
9516 + error = chown_common(nd.dentry, nd.mnt, user, group);
9520 @@ -664,7 +686,7 @@ asmlinkage long sys_fchown(unsigned int
9522 dentry = file->f_dentry;
9523 audit_inode(NULL, dentry->d_inode);
9524 - error = chown_common(dentry, user, group);
9525 + error = chown_common(dentry, file->f_vfsmnt, user, group);
9529 @@ -892,6 +914,7 @@ repeat:
9530 FD_SET(fd, fdt->open_fds);
9531 FD_CLR(fd, fdt->close_on_exec);
9532 files->next_fd = fd + 1;
9533 + vx_openfd_inc(fd);
9536 if (fdt->fd[fd] != NULL) {
9537 @@ -914,6 +937,7 @@ static void __put_unused_fd(struct files
9538 __FD_CLR(fd, fdt->open_fds);
9539 if (fd < files->next_fd)
9540 files->next_fd = fd;
9541 + vx_openfd_dec(fd);
9544 void fastcall put_unused_fd(unsigned int fd)
9545 diff -NurpP --minimal linux-2.6.19.1/fs/proc/array.c linux-2.6.19.1-vs2.3.0.6/fs/proc/array.c
9546 --- linux-2.6.19.1/fs/proc/array.c 2006-11-30 21:19:28 +0100
9547 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/array.c 2006-12-17 04:32:56 +0100
9549 #include <linux/cpuset.h>
9550 #include <linux/rcupdate.h>
9551 #include <linux/delayacct.h>
9552 +#include <linux/vs_context.h>
9553 +#include <linux/vs_network.h>
9555 #include <asm/uaccess.h>
9556 #include <asm/pgtable.h>
9557 @@ -134,8 +136,9 @@ static const char *task_state_array[] =
9558 "D (disk sleep)", /* 2 */
9559 "T (stopped)", /* 4 */
9560 "T (tracing stop)", /* 8 */
9561 - "Z (zombie)", /* 16 */
9562 - "X (dead)" /* 32 */
9563 + "H (on hold)" /* 16 */
9564 + "Z (zombie)", /* 32 */
9565 + "X (dead)", /* 64 */
9568 static inline const char * get_task_state(struct task_struct *tsk)
9569 @@ -144,7 +147,8 @@ static inline const char * get_task_stat
9570 TASK_INTERRUPTIBLE |
9571 TASK_UNINTERRUPTIBLE |
9576 (tsk->exit_state & (EXIT_ZOMBIE |
9578 const char **p = &task_state_array[0];
9579 @@ -161,8 +165,16 @@ static inline char * task_state(struct t
9580 struct group_info *group_info;
9582 struct fdtable *fdt = NULL;
9583 + pid_t pid, ptgid, tppid, tgid;
9586 + tgid = vx_map_tgid(p->tgid);
9587 + pid = vx_map_pid(p->pid);
9588 + ptgid = vx_map_pid(pid_alive(p) ?
9589 + rcu_dereference(p->real_parent)->tgid : 0);
9590 + tppid = vx_map_pid(pid_alive(p) && p->ptrace ?
9591 + rcu_dereference(p->parent)->pid : 0);
9593 buffer += sprintf(buffer,
9595 "SleepAVG:\t%lu%%\n"
9596 @@ -174,9 +186,7 @@ static inline char * task_state(struct t
9597 "Gid:\t%d\t%d\t%d\t%d\n",
9599 (p->sleep_avg/1024)*100/(1020000000/1024),
9601 - pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
9602 - pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
9603 + tgid, pid, (pid > 1) ? ptgid : 0, tppid,
9604 p->uid, p->euid, p->suid, p->fsuid,
9605 p->gid, p->egid, p->sgid, p->fsgid);
9607 @@ -283,12 +293,15 @@ static inline char * task_sig(struct tas
9609 static inline char *task_cap(struct task_struct *p, char *buffer)
9611 - return buffer + sprintf(buffer, "CapInh:\t%016x\n"
9612 - "CapPrm:\t%016x\n"
9613 - "CapEff:\t%016x\n",
9614 - cap_t(p->cap_inheritable),
9615 - cap_t(p->cap_permitted),
9616 - cap_t(p->cap_effective));
9617 + struct vx_info *vxi = p->vx_info;
9619 + return buffer + sprintf(buffer,
9620 + "CapInh:\t%016x\n"
9621 + "CapPrm:\t%016x\n"
9622 + "CapEff:\t%016x\n",
9623 + (unsigned)vx_info_mbcap(vxi, p->cap_inheritable),
9624 + (unsigned)vx_info_mbcap(vxi, p->cap_permitted),
9625 + (unsigned)vx_info_mbcap(vxi, p->cap_effective));
9628 int proc_pid_status(struct task_struct *task, char * buffer)
9629 @@ -306,6 +319,12 @@ int proc_pid_status(struct task_struct *
9630 buffer = task_sig(task, buffer);
9631 buffer = task_cap(task, buffer);
9632 buffer = cpuset_task_status_allowed(task, buffer);
9634 + if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
9636 + buffer += sprintf (buffer,"VxID: %d\n", vx_task_xid(task));
9637 + buffer += sprintf (buffer,"NxID: %d\n", nx_task_nid(task));
9639 #if defined(CONFIG_S390)
9640 buffer = task_show_regs(task, buffer);
9642 @@ -320,7 +339,7 @@ static int do_task_stat(struct task_stru
9643 sigset_t sigign, sigcatch;
9646 - pid_t ppid = 0, pgid = -1, sid = -1;
9647 + pid_t pid = 0, ppid = 0, pgid = -1, sid = -1;
9648 int num_threads = 0;
9649 struct mm_struct *mm;
9650 unsigned long long start_time;
9651 @@ -389,8 +408,10 @@ static int do_task_stat(struct task_stru
9655 - pgid = process_group(task);
9656 - ppid = rcu_dereference(task->real_parent)->tgid;
9657 + pid = vx_info_map_pid(task->vx_info, task->pid);
9658 + pgid = vx_info_map_pid(task->vx_info, process_group(task));
9659 + ppid = (pid > 1) ? vx_info_map_tgid(task->vx_info,
9660 + rcu_dereference(task->real_parent)->tgid) : 0;
9662 unlock_task_sighand(task, &flags);
9664 @@ -418,10 +439,21 @@ static int do_task_stat(struct task_stru
9665 /* convert nsec -> ticks */
9666 start_time = nsec_to_clock_t(start_time);
9668 + /* fixup start time for virt uptime */
9669 + if (vx_flags(VXF_VIRT_UPTIME, 0)) {
9670 + unsigned long long bias =
9671 + current->vx_info->cvirt.bias_clock;
9673 + if (start_time > bias)
9674 + start_time -= bias;
9679 res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
9680 %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
9681 %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu\n",
9687 diff -NurpP --minimal linux-2.6.19.1/fs/proc/base.c linux-2.6.19.1-vs2.3.0.6/fs/proc/base.c
9688 --- linux-2.6.19.1/fs/proc/base.c 2006-11-30 21:19:28 +0100
9689 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/base.c 2006-12-04 06:53:21 +0100
9691 #include <linux/poll.h>
9692 #include <linux/nsproxy.h>
9693 #include <linux/oom.h>
9694 +#include <linux/vs_context.h>
9695 +#include <linux/vs_network.h>
9697 #include "internal.h"
9700 @@ -971,6 +974,8 @@ static struct inode *proc_pid_make_inode
9701 inode->i_uid = task->euid;
9702 inode->i_gid = task->egid;
9704 + /* procfs is xid tagged */
9705 + inode->i_tag = (tag_t)vx_task_xid(task);
9706 security_task_to_inode(task, inode);
9709 @@ -1023,7 +1028,13 @@ static int pid_revalidate(struct dentry
9711 struct inode *inode = dentry->d_inode;
9712 struct task_struct *task = get_proc_task(inode);
9716 + if (!vx_proc_task_visible(task))
9720 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
9721 task_dumpable(task)) {
9722 inode->i_uid = task->euid;
9723 @@ -1034,11 +1045,11 @@ static int pid_revalidate(struct dentry
9725 inode->i_mode &= ~(S_ISUID | S_ISGID);
9726 security_task_to_inode(task, inode);
9728 put_task_struct(task);
9736 static int pid_delete_dentry(struct dentry * dentry)
9737 @@ -1404,6 +1415,13 @@ static struct dentry *proc_pident_lookup
9741 + /* FIXME: maybe we can come up with a generic approach? */
9742 + if (task_vx_flags(task, VXF_HIDE_VINFO, 0) &&
9743 + (dentry->d_name.len == 5) &&
9744 + (!memcmp(dentry->d_name.name, "vinfo", 5) ||
9745 + !memcmp(dentry->d_name.name, "ninfo", 5)))
9749 * Yes, it does not scale. And it should not. Don't add
9750 * new entries into /proc/<tgid>/ without very good reasons.
9751 @@ -1608,14 +1626,14 @@ static int proc_self_readlink(struct den
9754 char tmp[PROC_NUMBUF];
9755 - sprintf(tmp, "%d", current->tgid);
9756 + sprintf(tmp, "%d", vx_map_tgid(current->tgid));
9757 return vfs_readlink(dentry,buffer,buflen,tmp);
9760 static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
9762 char tmp[PROC_NUMBUF];
9763 - sprintf(tmp, "%d", current->tgid);
9764 + sprintf(tmp, "%d", vx_map_tgid(current->tgid));
9765 return ERR_PTR(vfs_follow_link(nd,tmp));
9768 @@ -1709,7 +1727,7 @@ out_iput:
9769 static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
9771 struct dentry *error;
9772 - struct task_struct *task = get_proc_task(dir);
9773 + struct task_struct *task = get_proc_task_real(dir);
9774 struct pid_entry *p, *last;
9776 error = ERR_PTR(-ENOENT);
9777 @@ -1749,6 +1767,9 @@ static int proc_base_fill_cache(struct f
9778 static struct file_operations proc_task_operations;
9779 static struct inode_operations proc_task_inode_operations;
9781 +extern int proc_pid_vx_info(struct task_struct *, char *);
9782 +extern int proc_pid_nx_info(struct task_struct *, char *);
9784 static struct pid_entry tgid_base_stuff[] = {
9785 DIR("task", S_IRUGO|S_IXUGO, task),
9786 DIR("fd", S_IRUSR|S_IXUSR, fd),
9787 @@ -1786,6 +1807,8 @@ static struct pid_entry tgid_base_stuff[
9788 #ifdef CONFIG_CPUSETS
9789 REG("cpuset", S_IRUGO, cpuset),
9791 + INF("vinfo", S_IRUGO, pid_vx_info),
9792 + INF("ninfo", S_IRUGO, pid_nx_info),
9793 INF("oom_score", S_IRUGO, oom_score),
9794 REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust),
9795 #ifdef CONFIG_AUDITSYSCALL
9796 @@ -1927,7 +1950,7 @@ struct dentry *proc_pid_lookup(struct in
9800 - task = find_task_by_pid(tgid);
9801 + task = vx_find_proc_task_by_pid(tgid);
9803 get_task_struct(task);
9805 @@ -1991,7 +2014,7 @@ static int proc_pid_fill_cache(struct fi
9806 int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
9808 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
9809 - struct task_struct *reaper = get_proc_task(filp->f_dentry->d_inode);
9810 + struct task_struct *reaper = get_proc_task_real(filp->f_dentry->d_inode);
9811 struct task_struct *task;
9814 @@ -2010,7 +2033,10 @@ int proc_pid_readdir(struct file * filp,
9815 put_task_struct(task), task = next_tgid(tgid + 1)) {
9817 filp->f_pos = tgid + TGID_OFFSET;
9818 - if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
9819 + if (!vx_proc_task_visible(task))
9821 + if (proc_pid_fill_cache(filp, dirent, filldir, task,
9822 + vx_map_tgid(tgid)) < 0) {
9823 put_task_struct(task);
9826 @@ -2131,9 +2157,11 @@ static struct dentry *proc_task_lookup(s
9827 tid = name_to_int(dentry);
9830 + if (vx_current_initpid(tid))
9834 - task = find_task_by_pid(tid);
9835 + task = vx_find_proc_task_by_pid(tid);
9837 get_task_struct(task);
9839 @@ -2268,7 +2296,10 @@ static int proc_task_readdir(struct file
9840 for (task = first_tid(leader, tid, pos - 2);
9842 task = next_tid(task), pos++) {
9844 + tid = vx_map_pid(task->pid);
9845 + /* FIXME: could go away now! */
9846 + if (!vx_proc_task_visible(task))
9848 if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
9849 /* returning this tgid failed, save it as the first
9850 * pid for the next readir call */
9851 diff -NurpP --minimal linux-2.6.19.1/fs/proc/generic.c linux-2.6.19.1-vs2.3.0.6/fs/proc/generic.c
9852 --- linux-2.6.19.1/fs/proc/generic.c 2006-06-18 04:54:45 +0200
9853 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/generic.c 2006-11-08 04:57:41 +0100
9855 #include <linux/namei.h>
9856 #include <linux/bitops.h>
9857 #include <linux/spinlock.h>
9858 +#include <linux/vserver/inode.h>
9859 #include <asm/uaccess.h>
9861 #include "internal.h"
9862 @@ -395,12 +396,16 @@ struct dentry *proc_lookup(struct inode
9863 for (de = de->subdir; de ; de = de->next) {
9864 if (de->namelen != dentry->d_name.len)
9866 + if (!vx_hide_check(0, de->vx_flags))
9868 if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
9869 unsigned int ino = de->low_ino;
9871 spin_unlock(&proc_subdir_lock);
9873 inode = proc_get_inode(dir->i_sb, ino, de);
9874 + /* generic proc entries belong to the host */
9876 spin_lock(&proc_subdir_lock);
9879 @@ -476,12 +481,15 @@ int proc_readdir(struct file * filp,
9883 + if (!vx_hide_check(0, de->vx_flags))
9885 /* filldir passes info to user space */
9886 spin_unlock(&proc_subdir_lock);
9887 if (filldir(dirent, de->name, de->namelen, filp->f_pos,
9888 de->low_ino, de->mode >> 12) < 0)
9890 spin_lock(&proc_subdir_lock);
9895 @@ -604,6 +612,7 @@ static struct proc_dir_entry *proc_creat
9899 + ent->vx_flags = IATTR_PROC_DEFAULT;
9903 @@ -624,7 +633,8 @@ struct proc_dir_entry *proc_symlink(cons
9909 + ent->vx_flags = IATTR_PROC_SYMLINK;
9913 diff -NurpP --minimal linux-2.6.19.1/fs/proc/inode.c linux-2.6.19.1-vs2.3.0.6/fs/proc/inode.c
9914 --- linux-2.6.19.1/fs/proc/inode.c 2006-09-20 16:58:35 +0200
9915 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/inode.c 2006-11-08 04:57:41 +0100
9916 @@ -168,6 +168,8 @@ struct inode *proc_get_inode(struct supe
9917 inode->i_uid = de->uid;
9918 inode->i_gid = de->gid;
9921 + PROC_I(inode)->vx_flags = de->vx_flags;
9923 inode->i_size = de->size;
9925 diff -NurpP --minimal linux-2.6.19.1/fs/proc/internal.h linux-2.6.19.1-vs2.3.0.6/fs/proc/internal.h
9926 --- linux-2.6.19.1/fs/proc/internal.h 2006-11-30 21:19:28 +0100
9927 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/internal.h 2006-12-04 02:53:55 +0100
9931 #include <linux/proc_fs.h>
9932 +#include <linux/vs_pid.h>
9934 struct vmalloc_info {
9936 @@ -56,11 +57,16 @@ static inline struct pid *proc_pid(struc
9937 return PROC_I(inode)->pid;
9940 -static inline struct task_struct *get_proc_task(struct inode *inode)
9941 +static inline struct task_struct *get_proc_task_real(struct inode *inode)
9943 return get_pid_task(proc_pid(inode), PIDTYPE_PID);
9946 +static inline struct task_struct *get_proc_task(struct inode *inode)
9948 + return vx_get_proc_task(inode, proc_pid(inode));
9951 static inline int proc_fd(struct inode *inode)
9953 return PROC_I(inode)->fd;
9954 diff -NurpP --minimal linux-2.6.19.1/fs/proc/proc_misc.c linux-2.6.19.1-vs2.3.0.6/fs/proc/proc_misc.c
9955 --- linux-2.6.19.1/fs/proc/proc_misc.c 2006-11-30 21:19:28 +0100
9956 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/proc_misc.c 2006-12-06 08:48:35 +0100
9958 #include <asm/div64.h>
9959 #include "internal.h"
9961 +#include <linux/vs_cvirt.h>
9963 #define LOAD_INT(x) ((x) >> FSHIFT)
9964 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
9966 @@ -82,17 +84,32 @@ static int proc_calc_metrics(char *page,
9967 static int loadavg_read_proc(char *page, char **start, off_t off,
9968 int count, int *eof, void *data)
9970 + unsigned int running, threads;
9974 - a = avenrun[0] + (FIXED_1/200);
9975 - b = avenrun[1] + (FIXED_1/200);
9976 - c = avenrun[2] + (FIXED_1/200);
9977 - len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
9978 + if (vx_flags(VXF_VIRT_LOAD, 0)) {
9979 + struct vx_info *vxi = current->vx_info;
9981 + a = vxi->cvirt.load[0] + (FIXED_1/200);
9982 + b = vxi->cvirt.load[1] + (FIXED_1/200);
9983 + c = vxi->cvirt.load[2] + (FIXED_1/200);
9985 + running = atomic_read(&vxi->cvirt.nr_running);
9986 + threads = atomic_read(&vxi->cvirt.nr_threads);
9988 + a = avenrun[0] + (FIXED_1/200);
9989 + b = avenrun[1] + (FIXED_1/200);
9990 + c = avenrun[2] + (FIXED_1/200);
9992 + running = nr_running();
9993 + threads = nr_threads;
9995 + len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
9996 LOAD_INT(a), LOAD_FRAC(a),
9997 LOAD_INT(b), LOAD_FRAC(b),
9998 LOAD_INT(c), LOAD_FRAC(c),
9999 - nr_running(), nr_threads, init_pspace.last_pid);
10000 + running, threads, init_pspace.last_pid);
10001 return proc_calc_metrics(page, start, off, count, eof, len);
10004 @@ -106,6 +123,9 @@ static int uptime_read_proc(char *page,
10006 do_posix_clock_monotonic_gettime(&uptime);
10007 cputime_to_timespec(idletime, &idle);
10008 + if (vx_flags(VXF_VIRT_UPTIME, 0))
10009 + vx_vsi_uptime(&uptime, &idle);
10011 len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
10012 (unsigned long) uptime.tv_sec,
10013 (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
10014 @@ -142,7 +162,7 @@ static int meminfo_read_proc(char *page,
10016 cached = global_page_state(NR_FILE_PAGES) -
10017 total_swapcache_pages - i.bufferram;
10019 + if (cached < 0 || vx_flags(VXF_VIRT_MEM, 0))
10022 get_vmalloc_info(&vmi);
10023 @@ -252,8 +272,8 @@ static int version_read_proc(char *page,
10027 - strcpy(page, linux_banner);
10028 - len = strlen(page);
10029 + len = sprintf(page, linux_banner,
10030 + utsname()->release, utsname()->version);
10031 return proc_calc_metrics(page, start, off, count, eof, len);
10034 diff -NurpP --minimal linux-2.6.19.1/fs/proc/root.c linux-2.6.19.1-vs2.3.0.6/fs/proc/root.c
10035 --- linux-2.6.19.1/fs/proc/root.c 2006-11-30 21:19:28 +0100
10036 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/root.c 2006-11-08 04:57:41 +0100
10037 @@ -25,6 +25,9 @@ struct proc_dir_entry *proc_net, *proc_n
10038 #ifdef CONFIG_SYSCTL
10039 struct proc_dir_entry *proc_sys_root;
10041 +struct proc_dir_entry *proc_virtual;
10043 +extern void proc_vx_init(void);
10045 static int proc_get_sb(struct file_system_type *fs_type,
10046 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
10047 @@ -89,6 +92,7 @@ void __init proc_root_init(void)
10048 proc_device_tree_init();
10050 proc_bus = proc_mkdir("bus", NULL);
10054 static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
10055 diff -NurpP --minimal linux-2.6.19.1/fs/quota.c linux-2.6.19.1-vs2.3.0.6/fs/quota.c
10056 --- linux-2.6.19.1/fs/quota.c 2006-11-30 21:19:28 +0100
10057 +++ linux-2.6.19.1-vs2.3.0.6/fs/quota.c 2006-12-01 22:46:55 +0100
10058 @@ -17,47 +17,122 @@
10059 #include <linux/buffer_head.h>
10060 #include <linux/capability.h>
10061 #include <linux/quotaops.h>
10062 +#include <linux/major.h>
10063 +#include <linux/blkdev.h>
10064 +#include <linux/vs_context.h>
10067 +/* Dquota Hash Management Functions */
10069 +static LIST_HEAD(dqhash_list);
10071 +struct dqhash *new_dqhash(struct super_block *sb, unsigned int id)
10073 + struct dqhash *hash;
10077 + hash = kmalloc(sizeof(struct dqhash), GFP_USER);
10081 + memset(hash, 0, sizeof(struct dqhash));
10082 + hash->dqh_id = id;
10083 + atomic_set(&hash->dqh_count, 1);
10085 + INIT_LIST_HEAD(&hash->dqh_list);
10087 + mutex_init(&hash->dqh_dqopt.dqio_mutex);
10088 + mutex_init(&hash->dqh_dqopt.dqonoff_mutex);
10089 + init_rwsem(&hash->dqh_dqopt.dqptr_sem);
10090 + hash->dqh_qop = sb->s_qop;
10091 + hash->dqh_qcop = sb->s_qcop;
10092 + hash->dqh_sb = sb;
10095 + list_add(&hash->dqh_list, &dqhash_list);
10097 + vxdprintk(VXD_CBIT(misc, 0),
10098 + "new_dqhash: %p [#0x%08x]", hash, hash->dqh_id);
10103 + return ERR_PTR(err);
10106 +void destroy_dqhash(struct dqhash *hash)
10108 + vxdprintk(VXD_CBIT(misc, 0),
10109 + "destroy_dqhash: %p [#0x%08x] c=%d",
10110 + hash, hash->dqh_id, atomic_read(&hash->dqh_count));
10112 + list_del_init(&hash->dqh_list);
10118 +struct dqhash *find_dqhash(unsigned int id)
10120 + struct list_head *head;
10121 + struct dqhash *hash;
10124 + list_for_each(head, &dqhash_list) {
10125 + hash = list_entry(head, struct dqhash, dqh_list);
10126 + if (hash->dqh_id == id)
10134 + return dqhget(hash);
10138 /* Check validity of generic quotactl commands */
10139 -static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
10140 +static int generic_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id)
10142 if (type >= MAXQUOTAS)
10144 - if (!sb && cmd != Q_SYNC)
10145 + if (!hash && cmd != Q_SYNC)
10147 /* Is operation supported? */
10148 - if (sb && !sb->s_qcop)
10149 + if (hash && !hash->dqh_qcop)
10156 - if (!sb->s_qcop->quota_on)
10157 + if (!hash->dqh_qcop->quota_on)
10161 - if (!sb->s_qcop->quota_off)
10162 + if (!hash->dqh_qcop->quota_off)
10166 - if (!sb->s_qcop->set_info)
10167 + if (!hash->dqh_qcop->set_info)
10171 - if (!sb->s_qcop->get_info)
10172 + if (!hash->dqh_qcop->get_info)
10176 - if (!sb->s_qcop->set_dqblk)
10177 + if (!hash->dqh_qcop->set_dqblk)
10181 - if (!sb->s_qcop->get_dqblk)
10182 + if (!hash->dqh_qcop->get_dqblk)
10186 - if (sb && !sb->s_qcop->quota_sync)
10187 + if (hash && !hash->dqh_qcop->quota_sync)
10191 @@ -73,7 +148,7 @@ static int generic_quotactl_valid(struct
10194 /* This is just informative test so we are satisfied without a lock */
10195 - if (!sb_has_quota_enabled(sb, type))
10196 + if (!dqh_has_quota_enabled(hash, type))
10200 @@ -81,47 +156,47 @@ static int generic_quotactl_valid(struct
10201 if (cmd == Q_GETQUOTA) {
10202 if (((type == USRQUOTA && current->euid != id) ||
10203 (type == GRPQUOTA && !in_egroup_p(id))) &&
10204 - !capable(CAP_SYS_ADMIN))
10205 + !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10208 else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO)
10209 - if (!capable(CAP_SYS_ADMIN))
10210 + if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10216 /* Check validity of XFS Quota Manager commands */
10217 -static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
10218 +static int xqm_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id)
10220 if (type >= XQM_MAXQUOTAS)
10226 + if (!hash->dqh_qcop)
10233 - if (!sb->s_qcop->set_xstate)
10234 + if (!hash->dqh_qcop->set_xstate)
10238 - if (!sb->s_qcop->get_xstate)
10239 + if (!hash->dqh_qcop->get_xstate)
10243 - if (!sb->s_qcop->set_xquota)
10244 + if (!hash->dqh_qcop->set_xquota)
10248 - if (!sb->s_qcop->get_xquota)
10249 + if (!hash->dqh_qcop->get_xquota)
10253 - if (!sb->s_qcop->quota_sync)
10254 + if (!hash->dqh_qcop->quota_sync)
10258 @@ -132,57 +207,68 @@ static int xqm_quotactl_valid(struct sup
10259 if (cmd == Q_XGETQUOTA) {
10260 if (((type == XQM_USRQUOTA && current->euid != id) ||
10261 (type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
10262 - !capable(CAP_SYS_ADMIN))
10263 + !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10265 } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) {
10266 - if (!capable(CAP_SYS_ADMIN))
10267 + if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10274 -static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
10275 +static int check_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id)
10279 if (XQM_COMMAND(cmd))
10280 - error = xqm_quotactl_valid(sb, type, cmd, id);
10281 + error = xqm_quotactl_valid(hash, type, cmd, id);
10283 - error = generic_quotactl_valid(sb, type, cmd, id);
10284 + error = generic_quotactl_valid(hash, type, cmd, id);
10286 - error = security_quotactl(cmd, type, id, sb);
10287 + error = security_quotactl(cmd, type, id, hash);
10291 -static void quota_sync_sb(struct super_block *sb, int type)
10292 +static void quota_sync_sb(struct super_block *sb)
10295 - struct inode *discard[MAXQUOTAS];
10297 - sb->s_qcop->quota_sync(sb, type);
10298 /* This is not very clever (and fast) but currently I don't know about
10299 * any other simple way of getting quota data to disk and we must get
10300 * them there for userspace to be visible... */
10301 if (sb->s_op->sync_fs)
10302 sb->s_op->sync_fs(sb, 1);
10303 sync_blockdev(sb->s_bdev);
10306 +static void quota_sync_dqh(struct dqhash *hash, int type)
10309 + struct inode *discard[MAXQUOTAS];
10311 + vxdprintk(VXD_CBIT(quota, 1),
10312 + "quota_sync_dqh(%p,%d)", hash, type);
10313 + hash->dqh_qcop->quota_sync(hash, type);
10315 + quota_sync_sb(hash->dqh_sb);
10317 /* Now when everything is written we can discard the pagecache so
10318 * that userspace sees the changes. We need i_mutex and so we could
10319 * not do it inside dqonoff_mutex. Moreover we need to be carefull
10320 * about races with quotaoff() (that is the reason why we have own
10321 * reference to inode). */
10322 - mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
10323 + mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
10324 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
10325 discard[cnt] = NULL;
10326 if (type != -1 && cnt != type)
10328 - if (!sb_has_quota_enabled(sb, cnt))
10329 + if (!dqh_has_quota_enabled(hash, cnt))
10331 - discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]);
10332 + vxdprintk(VXD_CBIT(quota, 0),
10333 + "quota_sync_dqh(%p,%d) discard inode %p",
10334 + hash, type, dqh_dqopt(hash)->files[cnt]);
10335 + discard[cnt] = igrab(dqh_dqopt(hash)->files[cnt]);
10337 - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
10338 + mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
10339 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
10340 if (discard[cnt]) {
10341 mutex_lock(&discard[cnt]->i_mutex);
10342 @@ -193,67 +279,59 @@ static void quota_sync_sb(struct super_b
10346 -void sync_dquots(struct super_block *sb, int type)
10347 +void sync_dquots_dqh(struct dqhash *hash, int type)
10350 + vxdprintk(VXD_CBIT(quota, 1),
10351 + "sync_dquots_dqh(%p,%d)", hash, type);
10354 - if (sb->s_qcop->quota_sync)
10355 - quota_sync_sb(sb, type);
10358 + if (hash->dqh_qcop->quota_sync)
10359 + quota_sync_dqh(hash, type);
10362 - spin_lock(&sb_lock);
10364 - list_for_each_entry(sb, &super_blocks, s_list) {
10365 - /* This test just improves performance so it needn't be reliable... */
10366 - for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
10367 - if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
10368 - && info_any_dirty(&sb_dqopt(sb)->info[cnt]))
10373 - spin_unlock(&sb_lock);
10374 - down_read(&sb->s_umount);
10375 - if (sb->s_root && sb->s_qcop->quota_sync)
10376 - quota_sync_sb(sb, type);
10377 - up_read(&sb->s_umount);
10378 - spin_lock(&sb_lock);
10379 - if (__put_super_and_need_restart(sb))
10381 +void sync_dquots(struct dqhash *hash, int type)
10384 + vxdprintk(VXD_CBIT(quota, 1),
10385 + "sync_dquots(%p,%d)", hash, type);
10388 + if (hash->dqh_qcop->quota_sync)
10389 + quota_sync_dqh(hash, type);
10392 - spin_unlock(&sb_lock);
10395 /* Copy parameters and call proper function */
10396 -static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void __user *addr)
10397 +static int do_quotactl(struct dqhash *hash, int type, int cmd, qid_t id, void __user *addr)
10401 + vxdprintk(VXD_CBIT(quota, 3),
10402 + "do_quotactl(%p,%d,cmd=%d,id=%d,%p)", hash, type, cmd, id, addr);
10408 if (IS_ERR(pathname = getname(addr)))
10409 return PTR_ERR(pathname);
10410 - ret = sb->s_qcop->quota_on(sb, type, id, pathname);
10411 + ret = hash->dqh_qcop->quota_on(hash, type, id, pathname);
10416 - return sb->s_qcop->quota_off(sb, type);
10417 + return hash->dqh_qcop->quota_off(hash, type);
10422 - down_read(&sb_dqopt(sb)->dqptr_sem);
10423 - if (!sb_has_quota_enabled(sb, type)) {
10424 - up_read(&sb_dqopt(sb)->dqptr_sem);
10425 + down_read(&dqh_dqopt(hash)->dqptr_sem);
10426 + if (!dqh_has_quota_enabled(hash, type)) {
10427 + up_read(&dqh_dqopt(hash)->dqptr_sem);
10430 - fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
10431 - up_read(&sb_dqopt(sb)->dqptr_sem);
10432 + fmt = dqh_dqopt(hash)->info[type].dqi_format->qf_fmt_id;
10433 + up_read(&dqh_dqopt(hash)->dqptr_sem);
10434 if (copy_to_user(addr, &fmt, sizeof(fmt)))
10437 @@ -261,7 +339,7 @@ static int do_quotactl(struct super_bloc
10439 struct if_dqinfo info;
10441 - if ((ret = sb->s_qcop->get_info(sb, type, &info)))
10442 + if ((ret = hash->dqh_qcop->get_info(hash, type, &info)))
10444 if (copy_to_user(addr, &info, sizeof(info)))
10446 @@ -272,12 +350,12 @@ static int do_quotactl(struct super_bloc
10448 if (copy_from_user(&info, addr, sizeof(info)))
10450 - return sb->s_qcop->set_info(sb, type, &info);
10451 + return hash->dqh_qcop->set_info(hash, type, &info);
10454 struct if_dqblk idq;
10456 - if ((ret = sb->s_qcop->get_dqblk(sb, type, id, &idq)))
10457 + if ((ret = hash->dqh_qcop->get_dqblk(hash, type, id, &idq)))
10459 if (copy_to_user(addr, &idq, sizeof(idq)))
10461 @@ -288,10 +366,10 @@ static int do_quotactl(struct super_bloc
10463 if (copy_from_user(&idq, addr, sizeof(idq)))
10465 - return sb->s_qcop->set_dqblk(sb, type, id, &idq);
10466 + return hash->dqh_qcop->set_dqblk(hash, type, id, &idq);
10469 - sync_dquots(sb, type);
10470 + sync_dquots_dqh(hash, type);
10474 @@ -301,12 +379,12 @@ static int do_quotactl(struct super_bloc
10476 if (copy_from_user(&flags, addr, sizeof(flags)))
10478 - return sb->s_qcop->set_xstate(sb, flags, cmd);
10479 + return hash->dqh_qcop->set_xstate(hash, flags, cmd);
10481 case Q_XGETQSTAT: {
10482 struct fs_quota_stat fqs;
10484 - if ((ret = sb->s_qcop->get_xstate(sb, &fqs)))
10485 + if ((ret = hash->dqh_qcop->get_xstate(hash, &fqs)))
10487 if (copy_to_user(addr, &fqs, sizeof(fqs)))
10489 @@ -317,19 +395,19 @@ static int do_quotactl(struct super_bloc
10491 if (copy_from_user(&fdq, addr, sizeof(fdq)))
10493 - return sb->s_qcop->set_xquota(sb, type, id, &fdq);
10494 + return hash->dqh_qcop->set_xquota(hash, type, id, &fdq);
10496 case Q_XGETQUOTA: {
10497 struct fs_disk_quota fdq;
10499 - if ((ret = sb->s_qcop->get_xquota(sb, type, id, &fdq)))
10500 + if ((ret = hash->dqh_qcop->get_xquota(hash, type, id, &fdq)))
10502 if (copy_to_user(addr, &fdq, sizeof(fdq)))
10507 - return sb->s_qcop->quota_sync(sb, type);
10508 + return hash->dqh_qcop->quota_sync(hash, type);
10509 /* We never reach here unless validity check is broken */
10512 @@ -365,6 +443,43 @@ static inline struct super_block *quotac
10516 +#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
10518 +#include <linux/vroot.h>
10519 +#include <linux/kallsyms.h>
10521 +static vroot_grb_func *vroot_get_real_bdev = NULL;
10523 +static spinlock_t vroot_grb_lock = SPIN_LOCK_UNLOCKED;
10525 +int register_vroot_grb(vroot_grb_func *func) {
10526 + int ret = -EBUSY;
10528 + spin_lock(&vroot_grb_lock);
10529 + if (!vroot_get_real_bdev) {
10530 + vroot_get_real_bdev = func;
10533 + spin_unlock(&vroot_grb_lock);
10536 +EXPORT_SYMBOL(register_vroot_grb);
10538 +int unregister_vroot_grb(vroot_grb_func *func) {
10539 + int ret = -EINVAL;
10541 + spin_lock(&vroot_grb_lock);
10542 + if (vroot_get_real_bdev) {
10543 + vroot_get_real_bdev = NULL;
10546 + spin_unlock(&vroot_grb_lock);
10549 +EXPORT_SYMBOL(unregister_vroot_grb);
10554 * This is the system call interface. This communicates with
10555 * the user-level programs. Currently this only supports diskquota
10556 @@ -375,6 +490,7 @@ asmlinkage long sys_quotactl(unsigned in
10559 struct super_block *sb = NULL;
10560 + struct dqhash *dqh = NULL;
10563 cmds = cmd >> SUBCMDSHIFT;
10564 @@ -386,9 +502,11 @@ asmlinkage long sys_quotactl(unsigned in
10565 return PTR_ERR(sb);
10568 - ret = check_quotactl_valid(sb, type, cmds, id);
10571 + ret = check_quotactl_valid(dqh, type, cmds, id);
10573 - ret = do_quotactl(sb, type, cmds, id, addr);
10574 + ret = do_quotactl(dqh, type, cmds, id, addr);
10578 diff -NurpP --minimal linux-2.6.19.1/fs/quota_v1.c linux-2.6.19.1-vs2.3.0.6/fs/quota_v1.c
10579 --- linux-2.6.19.1/fs/quota_v1.c 2005-03-02 12:38:45 +0100
10580 +++ linux-2.6.19.1-vs2.3.0.6/fs/quota_v1.c 2006-11-08 04:57:51 +0100
10581 @@ -42,12 +42,13 @@ static int v1_read_dqblk(struct dquot *d
10582 int type = dquot->dq_type;
10583 struct v1_disk_dqblk dqblk;
10585 - if (!sb_dqopt(dquot->dq_sb)->files[type])
10586 + if (!dqh_dqopt(dquot->dq_dqh)->files[type])
10589 /* Set structure to 0s in case read fails/is after end of file */
10590 memset(&dqblk, 0, sizeof(struct v1_disk_dqblk));
10591 - dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10592 + dquot->dq_dqh->dqh_sb->s_op->quota_read(dquot->dq_dqh, type,
10593 + (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10595 v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk);
10596 if (dquot->dq_dqb.dqb_bhardlimit == 0 && dquot->dq_dqb.dqb_bsoftlimit == 0 &&
10597 @@ -66,16 +67,16 @@ static int v1_commit_dqblk(struct dquot
10599 v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb);
10600 if (dquot->dq_id == 0) {
10601 - dqblk.dqb_btime = sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace;
10602 - dqblk.dqb_itime = sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace;
10603 + dqblk.dqb_btime = dqh_dqopt(dquot->dq_dqh)->info[type].dqi_bgrace;
10604 + dqblk.dqb_itime = dqh_dqopt(dquot->dq_dqh)->info[type].dqi_igrace;
10607 - if (sb_dqopt(dquot->dq_sb)->files[type])
10608 - ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, (char *)&dqblk,
10609 - sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10610 + if (dqh_dqopt(dquot->dq_dqh)->files[type])
10611 + ret = dquot->dq_dqh->dqh_sb->s_op->quota_write(dquot->dq_dqh, type,
10612 + (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10613 if (ret != sizeof(struct v1_disk_dqblk)) {
10614 printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
10615 - dquot->dq_sb->s_id);
10616 + dquot->dq_dqh->dqh_sb->s_id);
10620 @@ -100,9 +101,9 @@ struct v2_disk_dqheader {
10621 __le32 dqh_version; /* File version */
10624 -static int v1_check_quota_file(struct super_block *sb, int type)
10625 +static int v1_check_quota_file(struct dqhash *hash, int type)
10627 - struct inode *inode = sb_dqopt(sb)->files[type];
10628 + struct inode *inode = dqh_dqopt(hash)->files[type];
10631 struct v2_disk_dqheader dqhead;
10632 @@ -118,22 +119,26 @@ static int v1_check_quota_file(struct su
10633 if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % sizeof(struct v1_disk_dqblk))
10635 /* Doublecheck whether we didn't get file with new format - with old quotactl() this could happen */
10636 - size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10637 + size = hash->dqh_sb->s_op->quota_read(hash, type,
10638 + (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10639 if (size != sizeof(struct v2_disk_dqheader))
10640 return 1; /* Probably not new format */
10641 if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type])
10642 return 1; /* Definitely not new format */
10643 - printk(KERN_INFO "VFS: %s: Refusing to turn on old quota format on given file. It probably contains newer quota format.\n", sb->s_id);
10644 + printk(KERN_INFO "VFS: %s: Refusing to turn on old quota format on given file."
10645 + " It probably contains newer quota format.\n", hash->dqh_sb->s_id);
10646 return 0; /* Seems like a new format file -> refuse it */
10649 -static int v1_read_file_info(struct super_block *sb, int type)
10650 +static int v1_read_file_info(struct dqhash *hash, int type)
10652 - struct quota_info *dqopt = sb_dqopt(sb);
10653 + struct quota_info *dqopt = dqh_dqopt(hash);
10654 struct v1_disk_dqblk dqblk;
10657 - if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
10658 + if ((ret = hash->dqh_sb->s_op->quota_read(hash, type,
10659 + (char *)&dqblk, sizeof(struct v1_disk_dqblk),
10660 + v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
10664 @@ -145,14 +150,14 @@ out:
10668 -static int v1_write_file_info(struct super_block *sb, int type)
10669 +static int v1_write_file_info(struct dqhash *hash, int type)
10671 - struct quota_info *dqopt = sb_dqopt(sb);
10672 + struct quota_info *dqopt = dqh_dqopt(hash);
10673 struct v1_disk_dqblk dqblk;
10676 dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY;
10677 - if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk,
10678 + if ((ret = hash->dqh_sb->s_op->quota_read(hash, type, (char *)&dqblk,
10679 sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
10682 @@ -160,7 +165,7 @@ static int v1_write_file_info(struct sup
10684 dqblk.dqb_itime = dqopt->info[type].dqi_igrace;
10685 dqblk.dqb_btime = dqopt->info[type].dqi_bgrace;
10686 - ret = sb->s_op->quota_write(sb, type, (char *)&dqblk,
10687 + ret = hash->dqh_sb->s_op->quota_write(hash, type, (char *)&dqblk,
10688 sizeof(struct v1_disk_dqblk), v1_dqoff(0));
10689 if (ret == sizeof(struct v1_disk_dqblk))
10691 diff -NurpP --minimal linux-2.6.19.1/fs/quota_v2.c linux-2.6.19.1-vs2.3.0.6/fs/quota_v2.c
10692 --- linux-2.6.19.1/fs/quota_v2.c 2006-06-18 04:54:47 +0200
10693 +++ linux-2.6.19.1-vs2.3.0.6/fs/quota_v2.c 2006-11-08 04:57:51 +0100
10694 @@ -26,14 +26,15 @@ typedef char *dqbuf_t;
10695 #define GETENTRIES(buf) ((struct v2_disk_dqblk *)(((char *)buf)+sizeof(struct v2_disk_dqdbheader)))
10697 /* Check whether given file is really vfsv0 quotafile */
10698 -static int v2_check_quota_file(struct super_block *sb, int type)
10699 +static int v2_check_quota_file(struct dqhash *hash, int type)
10701 struct v2_disk_dqheader dqhead;
10703 static const uint quota_magics[] = V2_INITQMAGICS;
10704 static const uint quota_versions[] = V2_INITQVERSIONS;
10706 - size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10707 + size = hash->dqh_sb->s_op->quota_read(hash, type,
10708 + (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10709 if (size != sizeof(struct v2_disk_dqheader)) {
10710 printk("quota_v2: failed read expected=%zd got=%zd\n",
10711 sizeof(struct v2_disk_dqheader), size);
10712 @@ -46,17 +47,17 @@ static int v2_check_quota_file(struct su
10715 /* Read information header from quota file */
10716 -static int v2_read_file_info(struct super_block *sb, int type)
10717 +static int v2_read_file_info(struct dqhash *hash, int type)
10719 struct v2_disk_dqinfo dinfo;
10720 - struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
10721 + struct mem_dqinfo *info = dqh_dqopt(hash)->info+type;
10724 - size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
10725 - sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
10726 + size = hash->dqh_sb->s_op->quota_read(hash, type,
10727 + (char *)&dinfo, sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
10728 if (size != sizeof(struct v2_disk_dqinfo)) {
10729 printk(KERN_WARNING "Can't read info structure on device %s.\n",
10731 + hash->dqh_sb->s_id);
10734 info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
10735 @@ -69,10 +70,10 @@ static int v2_read_file_info(struct supe
10738 /* Write information header to quota file */
10739 -static int v2_write_file_info(struct super_block *sb, int type)
10740 +static int v2_write_file_info(struct dqhash *hash, int type)
10742 struct v2_disk_dqinfo dinfo;
10743 - struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
10744 + struct mem_dqinfo *info = dqh_dqopt(hash)->info+type;
10747 spin_lock(&dq_data_lock);
10748 @@ -84,11 +85,11 @@ static int v2_write_file_info(struct sup
10749 dinfo.dqi_blocks = cpu_to_le32(info->u.v2_i.dqi_blocks);
10750 dinfo.dqi_free_blk = cpu_to_le32(info->u.v2_i.dqi_free_blk);
10751 dinfo.dqi_free_entry = cpu_to_le32(info->u.v2_i.dqi_free_entry);
10752 - size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
10753 + size = hash->dqh_sb->s_op->quota_write(hash, type, (char *)&dinfo,
10754 sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
10755 if (size != sizeof(struct v2_disk_dqinfo)) {
10756 printk(KERN_WARNING "Can't write info structure on device %s.\n",
10758 + hash->dqh_sb->s_id);
10762 @@ -132,24 +133,24 @@ static inline void freedqbuf(dqbuf_t buf
10766 -static inline ssize_t read_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
10767 +static inline ssize_t read_blk(struct dqhash *hash, int type, uint blk, dqbuf_t buf)
10769 memset(buf, 0, V2_DQBLKSIZE);
10770 - return sb->s_op->quota_read(sb, type, (char *)buf,
10771 - V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10772 + return hash->dqh_sb->s_op->quota_read(hash, type,
10773 + (char *)buf, V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10776 -static inline ssize_t write_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
10777 +static inline ssize_t write_blk(struct dqhash *hash, int type, uint blk, dqbuf_t buf)
10779 - return sb->s_op->quota_write(sb, type, (char *)buf,
10780 - V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10781 + return hash->dqh_sb->s_op->quota_write(hash, type,
10782 + (char *)buf, V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10785 /* Remove empty block from list and return it */
10786 -static int get_free_dqblk(struct super_block *sb, int type)
10787 +static int get_free_dqblk(struct dqhash *hash, int type)
10789 dqbuf_t buf = getdqbuf();
10790 - struct mem_dqinfo *info = sb_dqinfo(sb, type);
10791 + struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10792 struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10795 @@ -157,18 +158,18 @@ static int get_free_dqblk(struct super_b
10797 if (info->u.v2_i.dqi_free_blk) {
10798 blk = info->u.v2_i.dqi_free_blk;
10799 - if ((ret = read_blk(sb, type, blk, buf)) < 0)
10800 + if ((ret = read_blk(hash, type, blk, buf)) < 0)
10802 info->u.v2_i.dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
10805 memset(buf, 0, V2_DQBLKSIZE);
10806 /* Assure block allocation... */
10807 - if ((ret = write_blk(sb, type, info->u.v2_i.dqi_blocks, buf)) < 0)
10808 + if ((ret = write_blk(hash, type, info->u.v2_i.dqi_blocks, buf)) < 0)
10810 blk = info->u.v2_i.dqi_blocks++;
10812 - mark_info_dirty(sb, type);
10813 + mark_info_dirty(hash, type);
10817 @@ -176,9 +177,9 @@ out_buf:
10820 /* Insert empty block to the list */
10821 -static int put_free_dqblk(struct super_block *sb, int type, dqbuf_t buf, uint blk)
10822 +static int put_free_dqblk(struct dqhash *hash, int type, dqbuf_t buf, uint blk)
10824 - struct mem_dqinfo *info = sb_dqinfo(sb, type);
10825 + struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10826 struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10829 @@ -186,18 +187,18 @@ static int put_free_dqblk(struct super_b
10830 dh->dqdh_prev_free = cpu_to_le32(0);
10831 dh->dqdh_entries = cpu_to_le16(0);
10832 info->u.v2_i.dqi_free_blk = blk;
10833 - mark_info_dirty(sb, type);
10834 + mark_info_dirty(hash, type);
10835 /* Some strange block. We had better leave it... */
10836 - if ((err = write_blk(sb, type, blk, buf)) < 0)
10837 + if ((err = write_blk(hash, type, blk, buf)) < 0)
10842 /* Remove given block from the list of blocks with free entries */
10843 -static int remove_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
10844 +static int remove_free_dqentry(struct dqhash *hash, int type, dqbuf_t buf, uint blk)
10846 dqbuf_t tmpbuf = getdqbuf();
10847 - struct mem_dqinfo *info = sb_dqinfo(sb, type);
10848 + struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10849 struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10850 uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = le32_to_cpu(dh->dqdh_prev_free);
10852 @@ -205,27 +206,27 @@ static int remove_free_dqentry(struct su
10856 - if ((err = read_blk(sb, type, nextblk, tmpbuf)) < 0)
10857 + if ((err = read_blk(hash, type, nextblk, tmpbuf)) < 0)
10859 ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = dh->dqdh_prev_free;
10860 - if ((err = write_blk(sb, type, nextblk, tmpbuf)) < 0)
10861 + if ((err = write_blk(hash, type, nextblk, tmpbuf)) < 0)
10865 - if ((err = read_blk(sb, type, prevblk, tmpbuf)) < 0)
10866 + if ((err = read_blk(hash, type, prevblk, tmpbuf)) < 0)
10868 ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_next_free = dh->dqdh_next_free;
10869 - if ((err = write_blk(sb, type, prevblk, tmpbuf)) < 0)
10870 + if ((err = write_blk(hash, type, prevblk, tmpbuf)) < 0)
10874 info->u.v2_i.dqi_free_entry = nextblk;
10875 - mark_info_dirty(sb, type);
10876 + mark_info_dirty(hash, type);
10879 dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
10880 /* No matter whether write succeeds block is out of list */
10881 - if (write_blk(sb, type, blk, buf) < 0)
10882 + if (write_blk(hash, type, blk, buf) < 0)
10883 printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk);
10886 @@ -234,10 +235,10 @@ out_buf:
10889 /* Insert given block to the beginning of list with free entries */
10890 -static int insert_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
10891 +static int insert_free_dqentry(struct dqhash *hash, int type, dqbuf_t buf, uint blk)
10893 dqbuf_t tmpbuf = getdqbuf();
10894 - struct mem_dqinfo *info = sb_dqinfo(sb, type);
10895 + struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10896 struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10899 @@ -245,18 +246,18 @@ static int insert_free_dqentry(struct su
10901 dh->dqdh_next_free = cpu_to_le32(info->u.v2_i.dqi_free_entry);
10902 dh->dqdh_prev_free = cpu_to_le32(0);
10903 - if ((err = write_blk(sb, type, blk, buf)) < 0)
10904 + if ((err = write_blk(hash, type, blk, buf)) < 0)
10906 if (info->u.v2_i.dqi_free_entry) {
10907 - if ((err = read_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10908 + if ((err = read_blk(hash, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10910 ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = cpu_to_le32(blk);
10911 - if ((err = write_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10912 + if ((err = write_blk(hash, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10916 info->u.v2_i.dqi_free_entry = blk;
10917 - mark_info_dirty(sb, type);
10918 + mark_info_dirty(hash, type);
10922 @@ -266,8 +267,9 @@ out_buf:
10923 /* Find space for dquot */
10924 static uint find_free_dqentry(struct dquot *dquot, int *err)
10926 - struct super_block *sb = dquot->dq_sb;
10927 - struct mem_dqinfo *info = sb_dqopt(sb)->info+dquot->dq_type;
10928 + // struct super_block *sb = dquot->dq_sb;
10929 + struct dqhash *dqh = dquot->dq_dqh;
10930 + struct mem_dqinfo *info = dqh_dqopt(dqh)->info+dquot->dq_type;
10932 struct v2_disk_dqdbheader *dh;
10933 struct v2_disk_dqblk *ddquot;
10934 @@ -283,11 +285,11 @@ static uint find_free_dqentry(struct dqu
10935 ddquot = GETENTRIES(buf);
10936 if (info->u.v2_i.dqi_free_entry) {
10937 blk = info->u.v2_i.dqi_free_entry;
10938 - if ((*err = read_blk(sb, dquot->dq_type, blk, buf)) < 0)
10939 + if ((*err = read_blk(dqh, dquot->dq_type, blk, buf)) < 0)
10943 - blk = get_free_dqblk(sb, dquot->dq_type);
10944 + blk = get_free_dqblk(dqh, dquot->dq_type);
10945 if ((int)blk < 0) {
10948 @@ -296,10 +298,10 @@ static uint find_free_dqentry(struct dqu
10949 memset(buf, 0, V2_DQBLKSIZE);
10950 /* This is enough as block is already zeroed and entry list is empty... */
10951 info->u.v2_i.dqi_free_entry = blk;
10952 - mark_info_dirty(sb, dquot->dq_type);
10953 + mark_info_dirty(dqh, dquot->dq_type);
10955 if (le16_to_cpu(dh->dqdh_entries)+1 >= V2_DQSTRINBLK) /* Block will be full? */
10956 - if ((*err = remove_free_dqentry(sb, dquot->dq_type, buf, blk)) < 0) {
10957 + if ((*err = remove_free_dqentry(dqh, dquot->dq_type, buf, blk)) < 0) {
10958 printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk);
10961 @@ -314,7 +316,7 @@ static uint find_free_dqentry(struct dqu
10965 - if ((*err = write_blk(sb, dquot->dq_type, blk, buf)) < 0) {
10966 + if ((*err = write_blk(dqh, dquot->dq_type, blk, buf)) < 0) {
10967 printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota data block %u.\n", blk);
10970 @@ -329,7 +331,7 @@ out_buf:
10971 /* Insert reference to structure into the trie */
10972 static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth)
10974 - struct super_block *sb = dquot->dq_sb;
10975 + struct dqhash *dqh = dquot->dq_dqh;
10977 int ret = 0, newson = 0, newact = 0;
10979 @@ -338,7 +340,7 @@ static int do_insert_tree(struct dquot *
10980 if (!(buf = getdqbuf()))
10983 - ret = get_free_dqblk(sb, dquot->dq_type);
10984 + ret = get_free_dqblk(dqh, dquot->dq_type);
10988 @@ -346,7 +348,7 @@ static int do_insert_tree(struct dquot *
10992 - if ((ret = read_blk(sb, dquot->dq_type, *treeblk, buf)) < 0) {
10993 + if ((ret = read_blk(dqh, dquot->dq_type, *treeblk, buf)) < 0) {
10994 printk(KERN_ERR "VFS: Can't read tree quota block %u.\n", *treeblk);
10997 @@ -369,10 +371,10 @@ static int do_insert_tree(struct dquot *
10998 ret = do_insert_tree(dquot, &newblk, depth+1);
10999 if (newson && ret >= 0) {
11000 ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk);
11001 - ret = write_blk(sb, dquot->dq_type, *treeblk, buf);
11002 + ret = write_blk(dqh, dquot->dq_type, *treeblk, buf);
11004 else if (newact && ret < 0)
11005 - put_free_dqblk(sb, dquot->dq_type, buf, *treeblk);
11006 + put_free_dqblk(dqh, dquot->dq_type, buf, *treeblk);
11010 @@ -409,10 +411,11 @@ static int v2_write_dquot(struct dquot *
11011 if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
11012 ddquot.dqb_itime = cpu_to_le64(1);
11013 spin_unlock(&dq_data_lock);
11014 - ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,
11015 + ret = dquot->dq_dqh->dqh_sb->s_op->quota_write(dquot->dq_dqh, type,
11016 (char *)&ddquot, sizeof(struct v2_disk_dqblk), dquot->dq_off);
11017 if (ret != sizeof(struct v2_disk_dqblk)) {
11018 - printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", dquot->dq_sb->s_id);
11019 + printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
11020 + dquot->dq_dqh->dqh_sb->s_id);
11024 @@ -426,7 +429,8 @@ static int v2_write_dquot(struct dquot *
11025 /* Free dquot entry in data block */
11026 static int free_dqentry(struct dquot *dquot, uint blk)
11028 - struct super_block *sb = dquot->dq_sb;
11029 + // struct super_block *sb = dquot->dq_sb;
11030 + struct dqhash *dqh = dquot->dq_dqh;
11031 int type = dquot->dq_type;
11032 struct v2_disk_dqdbheader *dh;
11033 dqbuf_t buf = getdqbuf();
11034 @@ -440,15 +444,15 @@ static int free_dqentry(struct dquot *dq
11035 (uint)(dquot->dq_off >> V2_DQBLKSIZE_BITS));
11038 - if ((ret = read_blk(sb, type, blk, buf)) < 0) {
11039 + if ((ret = read_blk(dqh, type, blk, buf)) < 0) {
11040 printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk);
11043 dh = (struct v2_disk_dqdbheader *)buf;
11044 dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)-1);
11045 if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */
11046 - if ((ret = remove_free_dqentry(sb, type, buf, blk)) < 0 ||
11047 - (ret = put_free_dqblk(sb, type, buf, blk)) < 0) {
11048 + if ((ret = remove_free_dqentry(dqh, type, buf, blk)) < 0 ||
11049 + (ret = put_free_dqblk(dqh, type, buf, blk)) < 0) {
11050 printk(KERN_ERR "VFS: Can't move quota data block (%u) "
11051 "to free list.\n", blk);
11053 @@ -459,13 +463,13 @@ static int free_dqentry(struct dquot *dq
11054 sizeof(struct v2_disk_dqblk));
11055 if (le16_to_cpu(dh->dqdh_entries) == V2_DQSTRINBLK-1) {
11056 /* Insert will write block itself */
11057 - if ((ret = insert_free_dqentry(sb, type, buf, blk)) < 0) {
11058 + if ((ret = insert_free_dqentry(dqh, type, buf, blk)) < 0) {
11059 printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk);
11064 - if ((ret = write_blk(sb, type, blk, buf)) < 0) {
11065 + if ((ret = write_blk(dqh, type, blk, buf)) < 0) {
11066 printk(KERN_ERR "VFS: Can't write quota data "
11067 "block %u\n", blk);
11069 @@ -480,7 +484,7 @@ out_buf:
11070 /* Remove reference to dquot from tree */
11071 static int remove_tree(struct dquot *dquot, uint *blk, int depth)
11073 - struct super_block *sb = dquot->dq_sb;
11074 + struct dqhash *dqh = dquot->dq_dqh;
11075 int type = dquot->dq_type;
11076 dqbuf_t buf = getdqbuf();
11078 @@ -489,7 +493,7 @@ static int remove_tree(struct dquot *dqu
11082 - if ((ret = read_blk(sb, type, *blk, buf)) < 0) {
11083 + if ((ret = read_blk(dqh, type, *blk, buf)) < 0) {
11084 printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk);
11087 @@ -506,11 +510,11 @@ static int remove_tree(struct dquot *dqu
11088 for (i = 0; i < V2_DQBLKSIZE && !buf[i]; i++); /* Block got empty? */
11089 /* Don't put the root block into the free block list */
11090 if (i == V2_DQBLKSIZE && *blk != V2_DQTREEOFF) {
11091 - put_free_dqblk(sb, type, buf, *blk);
11092 + put_free_dqblk(dqh, type, buf, *blk);
11096 - if ((ret = write_blk(sb, type, *blk, buf)) < 0)
11097 + if ((ret = write_blk(dqh, type, *blk, buf)) < 0)
11098 printk(KERN_ERR "VFS: Can't write quota tree "
11099 "block %u.\n", *blk);
11101 @@ -539,7 +543,7 @@ static loff_t find_block_dqentry(struct
11105 - if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
11106 + if ((ret = read_blk(dquot->dq_dqh, dquot->dq_type, blk, buf)) < 0) {
11107 printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
11110 @@ -578,7 +582,7 @@ static loff_t find_tree_dqentry(struct d
11114 - if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
11115 + if ((ret = read_blk(dquot->dq_dqh, dquot->dq_type, blk, buf)) < 0) {
11116 printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
11119 @@ -610,7 +614,7 @@ static int v2_read_dquot(struct dquot *d
11121 #ifdef __QUOTA_V2_PARANOIA
11122 /* Invalidated quota? */
11123 - if (!dquot->dq_sb || !sb_dqopt(dquot->dq_sb)->files[type]) {
11124 + if (!dquot->dq_dqh || !dqh_dqopt(dquot->dq_dqh)->files[type]) {
11125 printk(KERN_ERR "VFS: Quota invalidated while reading!\n");
11128 @@ -627,7 +631,7 @@ static int v2_read_dquot(struct dquot *d
11131 dquot->dq_off = offset;
11132 - if ((ret = dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type,
11133 + if ((ret = dquot->dq_dqh->dqh_sb->s_op->quota_read(dquot->dq_dqh, type,
11134 (char *)&ddquot, sizeof(struct v2_disk_dqblk), offset))
11135 != sizeof(struct v2_disk_dqblk)) {
11137 diff -NurpP --minimal linux-2.6.19.1/fs/read_write.c linux-2.6.19.1-vs2.3.0.6/fs/read_write.c
11138 --- linux-2.6.19.1/fs/read_write.c 2006-11-30 21:19:28 +0100
11139 +++ linux-2.6.19.1-vs2.3.0.6/fs/read_write.c 2006-11-08 04:57:51 +0100
11140 @@ -703,12 +703,77 @@ sys_writev(unsigned long fd, const struc
11144 +ssize_t vfs_sendfile(struct file *out_file, struct file *in_file, loff_t *ppos,
11145 + size_t count, loff_t max)
11147 + struct inode * in_inode, * out_inode;
11151 + /* verify in_file */
11152 + in_inode = in_file->f_dentry->d_inode;
11155 + if (!in_file->f_op || !in_file->f_op->sendfile)
11159 + ppos = &in_file->f_pos;
11161 + if (!(in_file->f_mode & FMODE_PREAD))
11164 + ret = rw_verify_area(READ, in_file, ppos, count);
11169 + /* verify out_file */
11170 + out_inode = out_file->f_dentry->d_inode;
11173 + if (!out_file->f_op || !out_file->f_op->sendpage)
11176 + ret = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
11181 + ret = security_file_permission (out_file, MAY_WRITE);
11186 + max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
11189 + if (unlikely(pos < 0))
11191 + if (unlikely(pos + count > max)) {
11193 + return -EOVERFLOW;
11194 + count = max - pos;
11197 + ret = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
11200 + current->rchar += ret;
11201 + current->wchar += ret;
11205 + return -EOVERFLOW;
11209 +EXPORT_SYMBOL(vfs_sendfile);
11211 static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
11212 size_t count, loff_t max)
11214 struct file * in_file, * out_file;
11215 - struct inode * in_inode, * out_inode;
11218 int fput_needed_in, fput_needed_out;
11220 @@ -721,22 +786,6 @@ static ssize_t do_sendfile(int out_fd, i
11222 if (!(in_file->f_mode & FMODE_READ))
11224 - retval = -EINVAL;
11225 - in_inode = in_file->f_dentry->d_inode;
11228 - if (!in_file->f_op || !in_file->f_op->sendfile)
11230 - retval = -ESPIPE;
11232 - ppos = &in_file->f_pos;
11234 - if (!(in_file->f_mode & FMODE_PREAD))
11236 - retval = rw_verify_area(READ, in_file, ppos, count);
11241 retval = security_file_permission (in_file, MAY_READ);
11243 @@ -751,45 +800,12 @@ static ssize_t do_sendfile(int out_fd, i
11245 if (!(out_file->f_mode & FMODE_WRITE))
11247 - retval = -EINVAL;
11248 - if (!out_file->f_op || !out_file->f_op->sendpage)
11250 - out_inode = out_file->f_dentry->d_inode;
11251 - retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
11256 - retval = security_file_permission (out_file, MAY_WRITE);
11261 - max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
11264 - retval = -EINVAL;
11265 - if (unlikely(pos < 0))
11267 - if (unlikely(pos + count > max)) {
11268 - retval = -EOVERFLOW;
11271 - count = max - pos;
11274 - retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
11275 + retval = vfs_sendfile(out_file, in_file, ppos, count, max);
11277 - if (retval > 0) {
11278 - current->rchar += retval;
11279 - current->wchar += retval;
11285 - retval = -EOVERFLOW;
11288 fput_light(out_file, fput_needed_out);
11290 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/bitmap.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/bitmap.c
11291 --- linux-2.6.19.1/fs/reiserfs/bitmap.c 2006-11-30 21:19:28 +0100
11292 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/bitmap.c 2006-11-08 04:57:50 +0100
11294 #include <linux/reiserfs_fs_sb.h>
11295 #include <linux/reiserfs_fs_i.h>
11296 #include <linux/quotaops.h>
11297 +#include <linux/vs_dlimit.h>
11299 #define PREALLOCATION_SIZE 9
11301 @@ -425,8 +426,10 @@ static void _reiserfs_free_block(struct
11302 set_sb_free_blocks(rs, sb_free_blocks(rs) + 1);
11304 journal_mark_dirty(th, s, sbh);
11305 - if (for_unformatted)
11306 + if (for_unformatted) {
11307 + DLIMIT_FREE_BLOCK(inode, 1);
11308 DQUOT_FREE_BLOCK_NODIRTY(inode, 1);
11312 void reiserfs_free_block(struct reiserfs_transaction_handle *th,
11313 @@ -1034,6 +1037,7 @@ static inline int blocknrs_and_prealloc_
11314 b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1;
11316 int nr_allocated = 0;
11319 determine_prealloc_size(hint);
11320 if (!hint->formatted_node) {
11321 @@ -1043,19 +1047,30 @@ static inline int blocknrs_and_prealloc_
11322 "reiserquota: allocating %d blocks id=%u",
11323 amount_needed, hint->inode->i_uid);
11326 - DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed);
11327 - if (quota_ret) /* Quota exceeded? */
11328 + quota_ret = DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode,
11331 return QUOTA_EXCEEDED;
11332 + if (DLIMIT_ALLOC_BLOCK(hint->inode, amount_needed)) {
11333 + DQUOT_FREE_BLOCK_NODIRTY(hint->inode,
11335 + return NO_DISK_SPACE;
11338 if (hint->preallocate && hint->prealloc_size) {
11339 #ifdef REISERQUOTA_DEBUG
11340 reiserfs_debug(s, REISERFS_DEBUG_CODE,
11341 "reiserquota: allocating (prealloc) %d blocks id=%u",
11342 hint->prealloc_size, hint->inode->i_uid);
11345 - DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
11346 - hint->prealloc_size);
11347 + quota_ret = DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
11348 + hint->prealloc_size);
11349 + if (!quota_ret &&
11350 + DLIMIT_ALLOC_BLOCK(hint->inode, hint->prealloc_size)) {
11351 + DQUOT_FREE_BLOCK_NODIRTY(hint->inode,
11352 + hint->prealloc_size);
11356 hint->preallocate = hint->prealloc_size = 0;
11358 @@ -1087,7 +1102,10 @@ static inline int blocknrs_and_prealloc_
11360 hint->inode->i_uid);
11362 - DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated); /* Free not allocated blocks */
11363 + /* Free not allocated blocks */
11364 + blocks = amount_needed + hint->prealloc_size - nr_allocated;
11365 + DLIMIT_FREE_BLOCK(hint->inode, blocks);
11366 + DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks);
11368 while (nr_allocated--)
11369 reiserfs_free_block(hint->th, hint->inode,
11370 @@ -1118,10 +1136,10 @@ static inline int blocknrs_and_prealloc_
11371 REISERFS_I(hint->inode)->i_prealloc_count,
11372 hint->inode->i_uid);
11374 - DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed +
11375 - hint->prealloc_size - nr_allocated -
11376 - REISERFS_I(hint->inode)->
11377 - i_prealloc_count);
11378 + blocks = amount_needed + hint->prealloc_size - nr_allocated -
11379 + REISERFS_I(hint->inode)->i_prealloc_count;
11380 + DLIMIT_FREE_BLOCK(hint->inode, blocks);
11381 + DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks);
11385 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/file.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/file.c
11386 --- linux-2.6.19.1/fs/reiserfs/file.c 2006-11-30 21:19:28 +0100
11387 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/file.c 2006-11-30 20:55:45 +0100
11388 @@ -1575,6 +1575,7 @@ const struct file_operations reiserfs_fi
11389 .release = reiserfs_file_release,
11390 .fsync = reiserfs_sync_file,
11391 .sendfile = generic_file_sendfile,
11392 + .sendpage = generic_file_sendpage,
11393 .aio_read = generic_file_aio_read,
11394 .aio_write = generic_file_aio_write,
11395 .splice_read = generic_file_splice_read,
11396 @@ -1589,4 +1590,5 @@ struct inode_operations reiserfs_file_in
11397 .listxattr = reiserfs_listxattr,
11398 .removexattr = reiserfs_removexattr,
11399 .permission = reiserfs_permission,
11400 + .sync_flags = reiserfs_sync_flags,
11402 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/inode.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/inode.c
11403 --- linux-2.6.19.1/fs/reiserfs/inode.c 2006-11-30 21:19:28 +0100
11404 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/inode.c 2006-11-30 18:53:18 +0100
11406 #include <linux/mpage.h>
11407 #include <linux/writeback.h>
11408 #include <linux/quotaops.h>
11409 +#include <linux/vs_dlimit.h>
11410 +#include <linux/vs_tag.h>
11412 static int reiserfs_commit_write(struct file *f, struct page *page,
11413 unsigned from, unsigned to);
11414 @@ -50,6 +52,7 @@ void reiserfs_delete_inode(struct inode
11415 * stat data deletion */
11417 DQUOT_FREE_INODE(inode);
11418 + DLIMIT_FREE_INODE(inode);
11420 if (journal_end(&th, inode->i_sb, jbegin_count))
11422 @@ -1114,6 +1117,8 @@ static void init_inode(struct inode *ino
11423 struct buffer_head *bh;
11424 struct item_head *ih;
11428 //int version = ITEM_VERSION_1;
11430 bh = PATH_PLAST_BUFFER(path);
11431 @@ -1136,12 +1141,13 @@ static void init_inode(struct inode *ino
11432 (struct stat_data_v1 *)B_I_PITEM(bh, ih);
11433 unsigned long blocks;
11435 + uid = sd_v1_uid(sd);
11436 + gid = sd_v1_gid(sd);
11438 set_inode_item_key_version(inode, KEY_FORMAT_3_5);
11439 set_inode_sd_version(inode, STAT_DATA_V1);
11440 inode->i_mode = sd_v1_mode(sd);
11441 inode->i_nlink = sd_v1_nlink(sd);
11442 - inode->i_uid = sd_v1_uid(sd);
11443 - inode->i_gid = sd_v1_gid(sd);
11444 inode->i_size = sd_v1_size(sd);
11445 inode->i_atime.tv_sec = sd_v1_atime(sd);
11446 inode->i_mtime.tv_sec = sd_v1_mtime(sd);
11447 @@ -1183,11 +1189,12 @@ static void init_inode(struct inode *ino
11448 // (directories and symlinks)
11449 struct stat_data *sd = (struct stat_data *)B_I_PITEM(bh, ih);
11451 + uid = sd_v2_uid(sd);
11452 + gid = sd_v2_gid(sd);
11454 inode->i_mode = sd_v2_mode(sd);
11455 inode->i_nlink = sd_v2_nlink(sd);
11456 - inode->i_uid = sd_v2_uid(sd);
11457 inode->i_size = sd_v2_size(sd);
11458 - inode->i_gid = sd_v2_gid(sd);
11459 inode->i_mtime.tv_sec = sd_v2_mtime(sd);
11460 inode->i_atime.tv_sec = sd_v2_atime(sd);
11461 inode->i_ctime.tv_sec = sd_v2_ctime(sd);
11462 @@ -1217,6 +1224,10 @@ static void init_inode(struct inode *ino
11463 sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode);
11466 + inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
11467 + inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
11468 + inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid, 0);
11471 if (S_ISREG(inode->i_mode)) {
11472 inode->i_op = &reiserfs_file_inode_operations;
11473 @@ -1239,13 +1250,15 @@ static void init_inode(struct inode *ino
11474 static void inode2sd(void *sd, struct inode *inode, loff_t size)
11476 struct stat_data *sd_v2 = (struct stat_data *)sd;
11477 + uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
11478 + gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
11481 + set_sd_v2_uid(sd_v2, uid);
11482 + set_sd_v2_gid(sd_v2, gid);
11483 set_sd_v2_mode(sd_v2, inode->i_mode);
11484 set_sd_v2_nlink(sd_v2, inode->i_nlink);
11485 - set_sd_v2_uid(sd_v2, inode->i_uid);
11486 set_sd_v2_size(sd_v2, size);
11487 - set_sd_v2_gid(sd_v2, inode->i_gid);
11488 set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec);
11489 set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec);
11490 set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec);
11491 @@ -1776,6 +1789,10 @@ int reiserfs_new_inode(struct reiserfs_t
11493 BUG_ON(!th->t_trans_id);
11495 + if (DLIMIT_ALLOC_INODE(inode)) {
11497 + goto out_bad_dlimit;
11499 if (DQUOT_ALLOC_INODE(inode)) {
11501 goto out_end_trans;
11502 @@ -1960,6 +1977,9 @@ int reiserfs_new_inode(struct reiserfs_t
11503 DQUOT_FREE_INODE(inode);
11506 + DLIMIT_FREE_INODE(inode);
11509 journal_end(th, th->t_super, th->t_blocks_allocated);
11510 /* Drop can be outside and it needs more credits so it's better to have it outside */
11512 @@ -2699,6 +2719,14 @@ void sd_attrs_to_i_attrs(__u16 sd_attrs,
11513 inode->i_flags |= S_IMMUTABLE;
11515 inode->i_flags &= ~S_IMMUTABLE;
11516 + if (sd_attrs & REISERFS_IUNLINK_FL)
11517 + inode->i_flags |= S_IUNLINK;
11519 + inode->i_flags &= ~S_IUNLINK;
11520 + if (sd_attrs & REISERFS_BARRIER_FL)
11521 + inode->i_flags |= S_BARRIER;
11523 + inode->i_flags &= ~S_BARRIER;
11524 if (sd_attrs & REISERFS_APPEND_FL)
11525 inode->i_flags |= S_APPEND;
11527 @@ -2721,6 +2749,14 @@ void i_attrs_to_sd_attrs(struct inode *i
11528 *sd_attrs |= REISERFS_IMMUTABLE_FL;
11530 *sd_attrs &= ~REISERFS_IMMUTABLE_FL;
11531 + if (inode->i_flags & S_IUNLINK)
11532 + *sd_attrs |= REISERFS_IUNLINK_FL;
11534 + *sd_attrs &= ~REISERFS_IUNLINK_FL;
11535 + if (inode->i_flags & S_BARRIER)
11536 + *sd_attrs |= REISERFS_BARRIER_FL;
11538 + *sd_attrs &= ~REISERFS_BARRIER_FL;
11539 if (inode->i_flags & S_SYNC)
11540 *sd_attrs |= REISERFS_SYNC_FL;
11542 @@ -2900,6 +2936,22 @@ static ssize_t reiserfs_direct_IO(int rw
11543 reiserfs_get_blocks_direct_io, NULL);
11546 +int reiserfs_sync_flags(struct inode *inode)
11548 + u16 oldflags, newflags;
11550 + oldflags = REISERFS_I(inode)->i_attrs;
11551 + newflags = oldflags;
11552 + i_attrs_to_sd_attrs(inode, &newflags);
11554 + if (oldflags ^ newflags) {
11555 + REISERFS_I(inode)->i_attrs = newflags;
11556 + inode->i_ctime = CURRENT_TIME_SEC;
11557 + mark_inode_dirty(inode);
11562 int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
11564 struct inode *inode = dentry->d_inode;
11565 @@ -2949,9 +3001,11 @@ int reiserfs_setattr(struct dentry *dent
11568 error = inode_change_ok(inode, attr);
11571 if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
11572 - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
11573 + (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
11574 + (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
11575 error = reiserfs_chown_xattrs(inode, attr);
11578 @@ -2981,6 +3035,9 @@ int reiserfs_setattr(struct dentry *dent
11579 inode->i_uid = attr->ia_uid;
11580 if (attr->ia_valid & ATTR_GID)
11581 inode->i_gid = attr->ia_gid;
11582 + if ((attr->ia_valid & ATTR_TAG) &&
11583 + IS_TAGGED(inode))
11584 + inode->i_tag = attr->ia_tag;
11585 mark_inode_dirty(inode);
11587 journal_end(&th, inode->i_sb, jbegin_count);
11588 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/ioctl.c
11589 --- linux-2.6.19.1/fs/reiserfs/ioctl.c 2006-11-30 21:19:28 +0100
11590 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/ioctl.c 2006-11-08 04:57:52 +0100
11593 #include <linux/capability.h>
11594 #include <linux/fs.h>
11595 +#include <linux/mount.h>
11596 #include <linux/reiserfs_fs.h>
11597 #include <linux/time.h>
11598 #include <asm/uaccess.h>
11599 @@ -24,7 +25,7 @@ static int reiserfs_unpack(struct inode
11600 int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
11603 - unsigned int flags;
11604 + unsigned int flags, oldflags;
11607 case REISERFS_IOC_UNPACK:
11608 @@ -43,12 +44,14 @@ int reiserfs_ioctl(struct inode *inode,
11610 flags = REISERFS_I(inode)->i_attrs;
11611 i_attrs_to_sd_attrs(inode, (__u16 *) & flags);
11612 + flags &= REISERFS_FL_USER_VISIBLE;
11613 return put_user(flags, (int __user *)arg);
11614 case REISERFS_IOC_SETFLAGS:{
11615 if (!reiserfs_attrs(inode->i_sb))
11618 - if (IS_RDONLY(inode))
11619 + if (IS_RDONLY(inode) ||
11620 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
11623 if ((current->fsuid != inode->i_uid)
11624 @@ -58,10 +61,12 @@ int reiserfs_ioctl(struct inode *inode,
11625 if (get_user(flags, (int __user *)arg))
11628 - if (((flags ^ REISERFS_I(inode)->
11629 - i_attrs) & (REISERFS_IMMUTABLE_FL |
11630 - REISERFS_APPEND_FL))
11631 - && !capable(CAP_LINUX_IMMUTABLE))
11632 + oldflags = REISERFS_I(inode) -> i_attrs;
11633 + if (((oldflags & REISERFS_IMMUTABLE_FL) ||
11634 + ((flags ^ oldflags) &
11635 + (REISERFS_IMMUTABLE_FL | REISERFS_IUNLINK_FL |
11636 + REISERFS_APPEND_FL))) &&
11637 + !capable(CAP_LINUX_IMMUTABLE))
11640 if ((flags & REISERFS_NOTAIL_FL) &&
11641 @@ -72,6 +77,9 @@ int reiserfs_ioctl(struct inode *inode,
11646 + flags = flags & REISERFS_FL_USER_MODIFIABLE;
11647 + flags |= oldflags & ~REISERFS_FL_USER_MODIFIABLE;
11648 sd_attrs_to_i_attrs(flags, inode);
11649 REISERFS_I(inode)->i_attrs = flags;
11650 inode->i_ctime = CURRENT_TIME_SEC;
11651 @@ -83,7 +91,8 @@ int reiserfs_ioctl(struct inode *inode,
11652 case REISERFS_IOC_SETVERSION:
11653 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
11655 - if (IS_RDONLY(inode))
11656 + if (IS_RDONLY(inode) ||
11657 + (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
11659 if (get_user(inode->i_generation, (int __user *)arg))
11661 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/namei.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/namei.c
11662 --- linux-2.6.19.1/fs/reiserfs/namei.c 2006-11-30 21:19:28 +0100
11663 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/namei.c 2006-11-08 04:57:47 +0100
11665 #include <linux/reiserfs_xattr.h>
11666 #include <linux/smp_lock.h>
11667 #include <linux/quotaops.h>
11668 +#include <linux/vs_tag.h>
11670 #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; }
11671 #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i);
11672 @@ -361,6 +362,7 @@ static struct dentry *reiserfs_lookup(st
11673 reiserfs_write_unlock(dir->i_sb);
11674 return ERR_PTR(-EACCES);
11676 + dx_propagate_tag(nd, inode);
11678 /* Propogate the priv_object flag so we know we're in the priv tree */
11679 if (is_reiserfs_priv_object(dir))
11680 @@ -596,6 +598,7 @@ static int new_inode_init(struct inode *
11682 inode->i_gid = current->fsgid;
11684 + inode->i_tag = dx_current_fstag(inode->i_sb);
11688 @@ -1542,6 +1545,7 @@ struct inode_operations reiserfs_dir_ino
11689 .listxattr = reiserfs_listxattr,
11690 .removexattr = reiserfs_removexattr,
11691 .permission = reiserfs_permission,
11692 + .sync_flags = reiserfs_sync_flags,
11696 @@ -1558,6 +1562,7 @@ struct inode_operations reiserfs_symlink
11697 .listxattr = reiserfs_listxattr,
11698 .removexattr = reiserfs_removexattr,
11699 .permission = reiserfs_permission,
11700 + .sync_flags = reiserfs_sync_flags,
11704 @@ -1571,5 +1576,6 @@ struct inode_operations reiserfs_special
11705 .listxattr = reiserfs_listxattr,
11706 .removexattr = reiserfs_removexattr,
11707 .permission = reiserfs_permission,
11708 + .sync_flags = reiserfs_sync_flags,
11711 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/stree.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/stree.c
11712 --- linux-2.6.19.1/fs/reiserfs/stree.c 2006-11-30 21:19:28 +0100
11713 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/stree.c 2006-11-08 04:57:50 +0100
11715 #include <linux/smp_lock.h>
11716 #include <linux/buffer_head.h>
11717 #include <linux/quotaops.h>
11718 +#include <linux/vs_dlimit.h>
11720 /* Does the buffer contain a disk block which is in the tree. */
11721 inline int B_IS_IN_TREE(const struct buffer_head *p_s_bh)
11722 @@ -1297,6 +1298,7 @@ int reiserfs_delete_item(struct reiserfs
11723 "reiserquota delete_item(): freeing %u, id=%u type=%c",
11724 quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih));
11726 + DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes);
11727 DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
11729 /* Return deleted body length */
11730 @@ -1385,6 +1387,7 @@ void reiserfs_delete_solid_item(struct r
11732 DQUOT_FREE_SPACE_NODIRTY(inode,
11734 + DLIMIT_FREE_SPACE(inode, quota_cut_bytes);
11738 @@ -1738,6 +1741,7 @@ int reiserfs_cut_from_item(struct reiser
11739 "reiserquota cut_from_item(): freeing %u id=%u type=%c",
11740 quota_cut_bytes, p_s_inode->i_uid, '?');
11742 + DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes);
11743 DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
11744 return n_ret_value;
11746 @@ -1979,6 +1983,11 @@ int reiserfs_paste_into_item(struct reis
11747 pathrelse(p_s_search_path);
11750 + if (DLIMIT_ALLOC_SPACE(inode, n_pasted_size)) {
11751 + DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
11752 + pathrelse(p_s_search_path);
11755 init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path,
11757 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
11758 @@ -2031,6 +2040,7 @@ int reiserfs_paste_into_item(struct reis
11759 n_pasted_size, inode->i_uid,
11760 key2type(&(p_s_key->on_disk_key)));
11762 + DLIMIT_FREE_SPACE(inode, n_pasted_size);
11763 DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
11766 @@ -2068,6 +2078,11 @@ int reiserfs_insert_item(struct reiserfs
11767 pathrelse(p_s_path);
11770 + if (DLIMIT_ALLOC_SPACE(inode, quota_bytes)) {
11771 + DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
11772 + pathrelse(p_s_path);
11776 init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path,
11777 IH_SIZE + ih_item_len(p_s_ih));
11778 @@ -2115,7 +2130,9 @@ int reiserfs_insert_item(struct reiserfs
11779 "reiserquota insert_item(): freeing %u id=%u type=%c",
11780 quota_bytes, inode->i_uid, head2type(p_s_ih));
11784 + DLIMIT_FREE_SPACE(inode, quota_bytes);
11785 DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
11789 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/super.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/super.c
11790 --- linux-2.6.19.1/fs/reiserfs/super.c 2006-11-30 21:19:28 +0100
11791 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/super.c 2006-11-08 21:52:09 +0100
11792 @@ -137,7 +137,7 @@ static int remove_save_link_only(struct
11795 #ifdef CONFIG_QUOTA
11796 -static int reiserfs_quota_on_mount(struct super_block *, int);
11797 +static int reiserfs_quota_on_mount(struct dqhash *, int);
11800 /* look for uncompleted unlinks and truncates and complete them */
11801 @@ -177,7 +177,7 @@ static int finish_unfinished(struct supe
11802 /* Turn on quotas so that they are updated correctly */
11803 for (i = 0; i < MAXQUOTAS; i++) {
11804 if (REISERFS_SB(s)->s_qf_names[i]) {
11805 - int ret = reiserfs_quota_on_mount(s, i);
11806 + int ret = reiserfs_quota_on_mount(s->s_dqh, i);
11808 reiserfs_warning(s,
11809 "reiserfs: cannot turn on journalled quota: error %d",
11810 @@ -291,8 +291,8 @@ static int finish_unfinished(struct supe
11811 #ifdef CONFIG_QUOTA
11812 /* Turn quotas off */
11813 for (i = 0; i < MAXQUOTAS; i++) {
11814 - if (sb_dqopt(s)->files[i])
11815 - vfs_quota_off_mount(s, i);
11816 + if (dqh_dqopt(s->s_dqh)->files[i])
11817 + vfs_quota_off_mount(s->s_dqh, i);
11820 /* Restore the flag back */
11821 @@ -587,9 +587,9 @@ static void reiserfs_clear_inode(struct
11824 #ifdef CONFIG_QUOTA
11825 -static ssize_t reiserfs_quota_write(struct super_block *, int, const char *,
11826 +static ssize_t reiserfs_quota_write(struct dqhash *, int, const char *,
11828 -static ssize_t reiserfs_quota_read(struct super_block *, int, char *, size_t,
11829 +static ssize_t reiserfs_quota_read(struct dqhash *, int, char *, size_t,
11833 @@ -622,8 +622,8 @@ static int reiserfs_write_dquot(struct d
11834 static int reiserfs_acquire_dquot(struct dquot *);
11835 static int reiserfs_release_dquot(struct dquot *);
11836 static int reiserfs_mark_dquot_dirty(struct dquot *);
11837 -static int reiserfs_write_info(struct super_block *, int);
11838 -static int reiserfs_quota_on(struct super_block *, int, int, char *);
11839 +static int reiserfs_write_info(struct dqhash *, int);
11840 +static int reiserfs_quota_on(struct dqhash *, int, int, char *);
11842 static struct dquot_operations reiserfs_quota_operations = {
11843 .initialize = reiserfs_dquot_initialize,
11844 @@ -885,6 +885,14 @@ static int reiserfs_parse_options(struct
11845 {"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},
11846 {"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},
11848 +#ifndef CONFIG_TAGGING_NONE
11849 + {"tagxid",.setmask = 1 << REISERFS_TAGGED},
11850 + {"tag",.setmask = 1 << REISERFS_TAGGED},
11851 + {"notag",.clrmask = 1 << REISERFS_TAGGED},
11853 +#ifdef CONFIG_PROPAGATE
11854 + {"tag",.arg_required = 'T',.values = NULL},
11856 #ifdef CONFIG_REISERFS_FS_POSIX_ACL
11857 {"acl",.setmask = 1 << REISERFS_POSIXACL},
11858 {"noacl",.clrmask = 1 << REISERFS_POSIXACL},
11859 @@ -981,7 +989,7 @@ static int reiserfs_parse_options(struct
11860 if (c == 'u' || c == 'g') {
11861 int qtype = c == 'u' ? USRQUOTA : GRPQUOTA;
11863 - if (sb_any_quota_enabled(s)) {
11864 + if (dqh_any_quota_enabled(s->s_dqh)) {
11865 reiserfs_warning(s,
11866 "reiserfs_parse_options: cannot change journalled quota options when quota turned on.");
11868 @@ -1044,7 +1052,7 @@ static int reiserfs_parse_options(struct
11870 /* This checking is not precise wrt the quota type but for our purposes it is sufficient */
11871 if (!(*mount_options & (1 << REISERFS_QUOTA))
11872 - && sb_any_quota_enabled(s)) {
11873 + && dqh_any_quota_enabled(s->s_dqh)) {
11874 reiserfs_warning(s,
11875 "reiserfs_parse_options: quota options must be present when quota is turned on.");
11877 @@ -1146,6 +1154,12 @@ static int reiserfs_remount(struct super
11881 + if ((mount_options & (1 << REISERFS_TAGGED)) &&
11882 + !(s->s_flags & MS_TAGGED)) {
11883 + reiserfs_warning(s, "reiserfs: tagging not permitted on remount.");
11889 /* Add options that are safe here */
11890 @@ -1336,7 +1350,7 @@ static int read_super_block(struct super
11891 s->s_export_op = &reiserfs_export_ops;
11892 #ifdef CONFIG_QUOTA
11893 s->s_qcop = &reiserfs_qctl_operations;
11894 - s->dq_op = &reiserfs_quota_operations;
11895 + s->s_qop = &reiserfs_quota_operations;
11898 /* new format is limited by the 32 bit wide i_blocks field, want to
11899 @@ -1594,6 +1608,10 @@ static int reiserfs_fill_super(struct su
11903 + /* map mount option tagxid */
11904 + if (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_TAGGED))
11905 + s->s_flags |= MS_TAGGED;
11907 rs = SB_DISK_SUPER_BLOCK(s);
11908 /* Let's do basic sanity check to verify that underlying device is not
11909 smaller than the filesystem. If the check fails then abort and scream,
11910 @@ -1869,16 +1887,16 @@ static int reiserfs_write_dquot(struct d
11911 struct reiserfs_transaction_handle th;
11914 - reiserfs_write_lock(dquot->dq_sb);
11915 + reiserfs_write_lock(dquot->dq_dqh->dqh_sb);
11917 - journal_begin(&th, dquot->dq_sb,
11918 - REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
11919 + journal_begin(&th, dquot->dq_dqh->dqh_sb,
11920 + REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb));
11923 ret = dquot_commit(dquot);
11925 - journal_end(&th, dquot->dq_sb,
11926 - REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
11927 + journal_end(&th, dquot->dq_dqh->dqh_sb,
11928 + REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb));
11932 @@ -1891,20 +1909,20 @@ static int reiserfs_acquire_dquot(struct
11933 struct reiserfs_transaction_handle th;
11936 - reiserfs_write_lock(dquot->dq_sb);
11937 + reiserfs_write_lock(dquot->dq_dqh->dqh_sb);
11939 - journal_begin(&th, dquot->dq_sb,
11940 - REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
11941 + journal_begin(&th, dquot->dq_dqh->dqh_sb,
11942 + REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb));
11945 ret = dquot_acquire(dquot);
11947 - journal_end(&th, dquot->dq_sb,
11948 - REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
11949 + journal_end(&th, dquot->dq_dqh->dqh_sb,
11950 + REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb));
11954 - reiserfs_write_unlock(dquot->dq_sb);
11955 + reiserfs_write_unlock(dquot->dq_dqh->dqh_sb);
11959 @@ -1913,37 +1931,38 @@ static int reiserfs_release_dquot(struct
11960 struct reiserfs_transaction_handle th;
11963 - reiserfs_write_lock(dquot->dq_sb);
11964 + reiserfs_write_lock(dquot->dq_dqh->dqh_sb);
11966 - journal_begin(&th, dquot->dq_sb,
11967 - REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
11968 + journal_begin(&th, dquot->dq_dqh->dqh_sb,
11969 + REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb));
11972 ret = dquot_release(dquot);
11974 - journal_end(&th, dquot->dq_sb,
11975 - REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
11976 + journal_end(&th, dquot->dq_dqh->dqh_sb,
11977 + REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb));
11981 - reiserfs_write_unlock(dquot->dq_sb);
11982 + reiserfs_write_unlock(dquot->dq_dqh->dqh_sb);
11986 static int reiserfs_mark_dquot_dirty(struct dquot *dquot)
11988 /* Are we journalling quotas? */
11989 - if (REISERFS_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
11990 - REISERFS_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
11991 + if (REISERFS_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[USRQUOTA] ||
11992 + REISERFS_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[GRPQUOTA]) {
11993 dquot_mark_dquot_dirty(dquot);
11994 return reiserfs_write_dquot(dquot);
11996 return dquot_mark_dquot_dirty(dquot);
11999 -static int reiserfs_write_info(struct super_block *sb, int type)
12000 +static int reiserfs_write_info(struct dqhash *hash, int type)
12002 struct reiserfs_transaction_handle th;
12003 + struct super_block *sb = hash->dqh_sb;
12006 /* Data block + inode block */
12007 @@ -1951,7 +1970,7 @@ static int reiserfs_write_info(struct su
12008 ret = journal_begin(&th, sb, 2);
12011 - ret = dquot_commit_info(sb, type);
12012 + ret = dquot_commit_info(hash, type);
12013 err = journal_end(&th, sb, 2);
12016 @@ -1963,18 +1982,21 @@ static int reiserfs_write_info(struct su
12018 * Turn on quotas during mount time - we need to find the quota file and such...
12020 -static int reiserfs_quota_on_mount(struct super_block *sb, int type)
12021 +static int reiserfs_quota_on_mount(struct dqhash *hash, int type)
12023 - return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type],
12024 + struct super_block *sb = hash->dqh_sb;
12026 + return vfs_quota_on_mount(hash, REISERFS_SB(sb)->s_qf_names[type],
12027 REISERFS_SB(sb)->s_jquota_fmt, type);
12031 * Standard function to be called on quota_on
12033 -static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
12034 +static int reiserfs_quota_on(struct dqhash *hash, int type, int format_id,
12037 + struct super_block *sb = hash->dqh_sb;
12039 struct nameidata nd;
12041 @@ -1999,7 +2021,7 @@ static int reiserfs_quota_on(struct supe
12042 if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&
12043 !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) {
12045 - return vfs_quota_on(sb, type, format_id, path);
12046 + return vfs_quota_on(hash, type, format_id, path);
12048 /* Quotafile not of fs root? */
12049 if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
12050 @@ -2007,17 +2029,18 @@ static int reiserfs_quota_on(struct supe
12051 "reiserfs: Quota file not on filesystem root. "
12052 "Journalled quota will not work.");
12054 - return vfs_quota_on(sb, type, format_id, path);
12055 + return vfs_quota_on(hash, type, format_id, path);
12058 /* Read data from quotafile - avoid pagecache and such because we cannot afford
12059 * acquiring the locks... As quota files are never truncated and quota code
12060 * itself serializes the operations (and noone else should touch the files)
12061 * we don't have to be afraid of races */
12062 -static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data,
12063 +static ssize_t reiserfs_quota_read(struct dqhash *hash, int type, char *data,
12064 size_t len, loff_t off)
12066 - struct inode *inode = sb_dqopt(sb)->files[type];
12067 + struct inode *inode = dqh_dqopt(hash)->files[type];
12068 + struct super_block *sb = hash->dqh_sb;
12069 unsigned long blk = off >> sb->s_blocksize_bits;
12070 int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
12072 @@ -2059,10 +2082,11 @@ static ssize_t reiserfs_quota_read(struc
12074 /* Write to quotafile (we know the transaction is already started and has
12075 * enough credits) */
12076 -static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
12077 +static ssize_t reiserfs_quota_write(struct dqhash *hash, int type,
12078 const char *data, size_t len, loff_t off)
12080 - struct inode *inode = sb_dqopt(sb)->files[type];
12081 + struct inode *inode = dqh_dqopt(hash)->files[type];
12082 + struct super_block *sb = hash->dqh_sb;
12083 unsigned long blk = off >> sb->s_blocksize_bits;
12084 int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
12085 int journal_quota = REISERFS_SB(sb)->s_qf_names[type] != NULL;
12086 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/xattr.c
12087 --- linux-2.6.19.1/fs/reiserfs/xattr.c 2006-11-30 21:19:28 +0100
12088 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/xattr.c 2006-11-08 04:57:52 +0100
12090 #include <linux/namei.h>
12091 #include <linux/errno.h>
12092 #include <linux/fs.h>
12093 +#include <linux/mount.h>
12094 #include <linux/file.h>
12095 #include <linux/pagemap.h>
12096 #include <linux/xattr.h>
12097 @@ -823,7 +824,7 @@ int reiserfs_delete_xattrs(struct inode
12098 if (dir->d_inode->i_nlink <= 2) {
12099 root = get_xa_root(inode->i_sb);
12100 reiserfs_write_lock_xattrs(inode->i_sb);
12101 - err = vfs_rmdir(root->d_inode, dir);
12102 + err = vfs_rmdir(root->d_inode, dir, NULL);
12103 reiserfs_write_unlock_xattrs(inode->i_sb);
12106 diff -NurpP --minimal linux-2.6.19.1/fs/stat.c linux-2.6.19.1-vs2.3.0.6/fs/stat.c
12107 --- linux-2.6.19.1/fs/stat.c 2006-11-30 21:19:28 +0100
12108 +++ linux-2.6.19.1-vs2.3.0.6/fs/stat.c 2006-11-08 04:57:46 +0100
12109 @@ -27,6 +27,7 @@ void generic_fillattr(struct inode *inod
12110 stat->nlink = inode->i_nlink;
12111 stat->uid = inode->i_uid;
12112 stat->gid = inode->i_gid;
12113 + stat->tag = inode->i_tag;
12114 stat->rdev = inode->i_rdev;
12115 stat->atime = inode->i_atime;
12116 stat->mtime = inode->i_mtime;
12117 diff -NurpP --minimal linux-2.6.19.1/fs/super.c linux-2.6.19.1-vs2.3.0.6/fs/super.c
12118 --- linux-2.6.19.1/fs/super.c 2006-11-30 21:19:28 +0100
12119 +++ linux-2.6.19.1-vs2.3.0.6/fs/super.c 2006-11-30 19:49:06 +0100
12121 #include <linux/idr.h>
12122 #include <linux/kobject.h>
12123 #include <linux/mutex.h>
12124 +#include <linux/devpts_fs.h>
12125 +#include <linux/proc_fs.h>
12126 +#include <linux/vs_context.h>
12127 #include <asm/uaccess.h>
12130 @@ -84,15 +87,14 @@ static struct super_block *alloc_super(s
12131 s->s_count = S_BIAS;
12132 atomic_set(&s->s_active, 1);
12133 mutex_init(&s->s_vfs_rename_mutex);
12134 - mutex_init(&s->s_dquot.dqio_mutex);
12135 - mutex_init(&s->s_dquot.dqonoff_mutex);
12136 - init_rwsem(&s->s_dquot.dqptr_sem);
12137 init_waitqueue_head(&s->s_wait_unfrozen);
12138 s->s_maxbytes = MAX_NON_LFS;
12139 - s->dq_op = sb_dquot_ops;
12140 + s->s_qop = sb_dquot_ops;
12141 s->s_qcop = sb_quotactl_ops;
12142 s->s_op = &default_op;
12143 s->s_time_gran = 1000000000;
12144 + /* quick hack to make dqhash id unique, sufficient for now */
12145 + s->s_dqh = new_dqhash(s, (unsigned long)s);
12149 @@ -107,6 +109,7 @@ out:
12150 static inline void destroy_super(struct super_block *s)
12152 security_sb_free(s);
12153 + dqhput(s->s_dqh);
12157 @@ -178,7 +181,7 @@ void deactivate_super(struct super_block
12158 if (atomic_dec_and_lock(&s->s_active, &sb_lock)) {
12159 s->s_count -= S_BIAS-1;
12160 spin_unlock(&sb_lock);
12162 + DQUOT_OFF(s->s_dqh);
12163 down_write(&s->s_umount);
12165 put_filesystem(fs);
12166 @@ -229,7 +232,7 @@ static int grab_super(struct super_block
12167 void __fsync_super(struct super_block *sb)
12169 sync_inodes_sb(sb, 0);
12171 + DQUOT_SYNC(sb->s_dqh);
12173 if (sb->s_dirt && sb->s_op->write_super)
12174 sb->s_op->write_super(sb);
12175 @@ -853,6 +856,7 @@ struct vfsmount *
12176 vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
12178 struct vfsmount *mnt;
12179 + struct super_block *sb;
12180 char *secdata = NULL;
12183 @@ -878,7 +882,14 @@ vfs_kern_mount(struct file_system_type *
12185 goto out_free_secdata;
12187 - error = security_sb_kern_mount(mnt->mnt_sb, secdata);
12188 + sb = mnt->mnt_sb;
12190 + if (!vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT) && !sb->s_bdev &&
12191 + (sb->s_magic != PROC_SUPER_MAGIC) &&
12192 + (sb->s_magic != DEVPTS_SUPER_MAGIC))
12195 + error = security_sb_kern_mount(sb, secdata);
12199 @@ -906,9 +917,17 @@ do_kern_mount(const char *fstype, int fl
12201 struct file_system_type *type = get_fs_type(fstype);
12202 struct vfsmount *mnt;
12205 return ERR_PTR(-ENODEV);
12207 + mnt = ERR_PTR(-EPERM);
12208 + if ((type->fs_flags & FS_BINARY_MOUNTDATA) &&
12209 + !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT))
12212 mnt = vfs_kern_mount(type, flags, name, data);
12214 put_filesystem(type);
12217 diff -NurpP --minimal linux-2.6.19.1/fs/sysfs/mount.c linux-2.6.19.1-vs2.3.0.6/fs/sysfs/mount.c
12218 --- linux-2.6.19.1/fs/sysfs/mount.c 2006-11-30 21:19:28 +0100
12219 +++ linux-2.6.19.1-vs2.3.0.6/fs/sysfs/mount.c 2006-11-08 04:57:53 +0100
12224 -/* Random magic number */
12225 -#define SYSFS_MAGIC 0x62656572
12227 struct vfsmount *sysfs_mount;
12228 struct super_block * sysfs_sb = NULL;
12229 @@ -38,7 +36,7 @@ static int sysfs_fill_super(struct super
12231 sb->s_blocksize = PAGE_CACHE_SIZE;
12232 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
12233 - sb->s_magic = SYSFS_MAGIC;
12234 + sb->s_magic = SYSFS_SUPER_MAGIC;
12235 sb->s_op = &sysfs_ops;
12236 sb->s_time_gran = 1;
12238 diff -NurpP --minimal linux-2.6.19.1/fs/udf/super.c linux-2.6.19.1-vs2.3.0.6/fs/udf/super.c
12239 --- linux-2.6.19.1/fs/udf/super.c 2006-11-30 21:19:28 +0100
12240 +++ linux-2.6.19.1-vs2.3.0.6/fs/udf/super.c 2006-11-08 04:57:51 +0100
12241 @@ -1576,7 +1576,7 @@ static int udf_fill_super(struct super_b
12243 /* Fill in the rest of the superblock */
12244 sb->s_op = &udf_sb_ops;
12245 - sb->dq_op = NULL;
12246 + sb->s_qop = NULL;
12248 sb->s_magic = UDF_SUPER_MAGIC;
12249 sb->s_time_gran = 1000;
12250 diff -NurpP --minimal linux-2.6.19.1/fs/ufs/super.c linux-2.6.19.1-vs2.3.0.6/fs/ufs/super.c
12251 --- linux-2.6.19.1/fs/ufs/super.c 2006-11-30 21:19:28 +0100
12252 +++ linux-2.6.19.1-vs2.3.0.6/fs/ufs/super.c 2006-11-08 04:57:51 +0100
12253 @@ -930,7 +930,7 @@ magic_found:
12254 * Read ufs_super_block into internal data structures
12256 sb->s_op = &ufs_super_ops;
12257 - sb->dq_op = NULL; /***/
12258 + sb->s_qop = NULL; /***/
12259 sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic);
12261 uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno);
12262 @@ -1248,8 +1248,8 @@ static void destroy_inodecache(void)
12265 #ifdef CONFIG_QUOTA
12266 -static ssize_t ufs_quota_read(struct super_block *, int, char *,size_t, loff_t);
12267 -static ssize_t ufs_quota_write(struct super_block *, int, const char *, size_t, loff_t);
12268 +static ssize_t ufs_quota_read(struct dqhash *, int, char *,size_t, loff_t);
12269 +static ssize_t ufs_quota_write(struct dqhash *, int, const char *, size_t, loff_t);
12272 static struct super_operations ufs_super_ops = {
12273 @@ -1274,10 +1274,11 @@ static struct super_operations ufs_super
12274 * acquiring the locks... As quota files are never truncated and quota code
12275 * itself serializes the operations (and noone else should touch the files)
12276 * we don't have to be afraid of races */
12277 -static ssize_t ufs_quota_read(struct super_block *sb, int type, char *data,
12278 +static ssize_t ufs_quota_read(struct dqhash *hash, int type, char *data,
12279 size_t len, loff_t off)
12281 - struct inode *inode = sb_dqopt(sb)->files[type];
12282 + struct inode *inode = dqh_dqopt(hash)->files[type];
12283 + struct super_block *sb = hash->dqh_sb;
12284 sector_t blk = off >> sb->s_blocksize_bits;
12286 int offset = off & (sb->s_blocksize - 1);
12287 @@ -1313,10 +1314,11 @@ static ssize_t ufs_quota_read(struct sup
12290 /* Write to quotafile */
12291 -static ssize_t ufs_quota_write(struct super_block *sb, int type,
12292 +static ssize_t ufs_quota_write(struct dqhash *hash, int type,
12293 const char *data, size_t len, loff_t off)
12295 - struct inode *inode = sb_dqopt(sb)->files[type];
12296 + struct inode *inode = dqh_dqopt(hash)->files[type];
12297 + struct super_block *sb = hash->dqh_sb;
12298 sector_t blk = off >> sb->s_blocksize_bits;
12300 int offset = off & (sb->s_blocksize - 1);
12301 diff -NurpP --minimal linux-2.6.19.1/fs/utimes.c linux-2.6.19.1-vs2.3.0.6/fs/utimes.c
12302 --- linux-2.6.19.1/fs/utimes.c 2006-11-30 21:19:28 +0100
12303 +++ linux-2.6.19.1-vs2.3.0.6/fs/utimes.c 2006-11-08 22:44:42 +0100
12305 #include <linux/linkage.h>
12306 #include <linux/namei.h>
12307 #include <linux/utime.h>
12308 +#include <linux/mount.h>
12309 +#include <linux/vs_cowbl.h>
12310 #include <asm/uaccess.h>
12311 #include <asm/unistd.h>
12313 @@ -32,7 +34,7 @@ asmlinkage long sys_utime(char __user *
12314 inode = nd.dentry->d_inode;
12317 - if (IS_RDONLY(inode))
12318 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
12321 /* Don't worry, the checks are done in inode_change_ok() */
12322 @@ -83,14 +85,13 @@ long do_utimes(int dfd, char __user *fil
12323 struct iattr newattrs;
12325 error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
12329 - inode = nd.dentry->d_inode;
12332 - if (IS_RDONLY(inode))
12333 + error = cow_check_and_break(&nd);
12336 + inode = nd.dentry->d_inode;
12338 /* Don't worry, the checks are done in inode_change_ok() */
12339 newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
12340 diff -NurpP --minimal linux-2.6.19.1/fs/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/xattr.c
12341 --- linux-2.6.19.1/fs/xattr.c 2006-11-30 21:19:28 +0100
12342 +++ linux-2.6.19.1-vs2.3.0.6/fs/xattr.c 2006-11-08 21:52:09 +0100
12344 #include <linux/module.h>
12345 #include <linux/fsnotify.h>
12346 #include <linux/audit.h>
12347 +#include <linux/mount.h>
12348 #include <asm/uaccess.h>
12351 @@ -195,7 +196,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
12354 setxattr(struct dentry *d, char __user *name, void __user *value,
12355 - size_t size, int flags)
12356 + size_t size, int flags, struct vfsmount *mnt)
12359 void *kvalue = NULL;
12360 @@ -222,6 +223,9 @@ setxattr(struct dentry *d, char __user *
12364 + if (MNT_IS_RDONLY(mnt))
12367 error = vfs_setxattr(d, kname, kvalue, size, flags);
12370 @@ -237,7 +241,7 @@ sys_setxattr(char __user *path, char __u
12371 error = user_path_walk(path, &nd);
12374 - error = setxattr(nd.dentry, name, value, size, flags);
12375 + error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
12379 @@ -252,7 +256,7 @@ sys_lsetxattr(char __user *path, char __
12380 error = user_path_walk_link(path, &nd);
12383 - error = setxattr(nd.dentry, name, value, size, flags);
12384 + error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
12388 @@ -270,7 +274,7 @@ sys_fsetxattr(int fd, char __user *name,
12390 dentry = f->f_dentry;
12391 audit_inode(NULL, dentry->d_inode);
12392 - error = setxattr(dentry, name, value, size, flags);
12393 + error = setxattr(dentry, name, value, size, flags, f->f_vfsmnt);
12397 @@ -432,7 +436,7 @@ sys_flistxattr(int fd, char __user *list
12398 * Extended attribute REMOVE operations
12401 -removexattr(struct dentry *d, char __user *name)
12402 +removexattr(struct dentry *d, char __user *name, struct vfsmount *mnt)
12405 char kname[XATTR_NAME_MAX + 1];
12406 @@ -443,6 +447,9 @@ removexattr(struct dentry *d, char __use
12410 + if (MNT_IS_RDONLY(mnt))
12413 return vfs_removexattr(d, kname);
12416 @@ -455,7 +462,7 @@ sys_removexattr(char __user *path, char
12417 error = user_path_walk(path, &nd);
12420 - error = removexattr(nd.dentry, name);
12421 + error = removexattr(nd.dentry, name, nd.mnt);
12425 @@ -469,7 +476,7 @@ sys_lremovexattr(char __user *path, char
12426 error = user_path_walk_link(path, &nd);
12429 - error = removexattr(nd.dentry, name);
12430 + error = removexattr(nd.dentry, name, nd.mnt);
12434 @@ -486,7 +493,7 @@ sys_fremovexattr(int fd, char __user *na
12436 dentry = f->f_dentry;
12437 audit_inode(NULL, dentry->d_inode);
12438 - error = removexattr(dentry, name);
12439 + error = removexattr(dentry, name, f->f_vfsmnt);
12443 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_file.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_file.c
12444 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_file.c 2006-11-30 21:19:29 +0100
12445 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_file.c 2006-11-08 04:57:51 +0100
12446 @@ -453,6 +453,7 @@ const struct file_operations xfs_file_op
12447 .aio_read = xfs_file_aio_read,
12448 .aio_write = xfs_file_aio_write,
12449 .sendfile = xfs_file_sendfile,
12450 + .sendpage = generic_file_sendpage,
12451 .splice_read = xfs_file_splice_read,
12452 .splice_write = xfs_file_splice_write,
12453 .unlocked_ioctl = xfs_file_ioctl,
12454 @@ -476,6 +477,7 @@ const struct file_operations xfs_invis_f
12455 .aio_read = xfs_file_aio_read_invis,
12456 .aio_write = xfs_file_aio_write_invis,
12457 .sendfile = xfs_file_sendfile_invis,
12458 + .sendpage = generic_file_sendpage,
12459 .splice_read = xfs_file_splice_read_invis,
12460 .splice_write = xfs_file_splice_write_invis,
12461 .unlocked_ioctl = xfs_file_ioctl_invis,
12462 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_ioctl.c
12463 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_ioctl.c 2006-11-30 21:19:29 +0100
12464 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_ioctl.c 2006-11-20 21:12:32 +0100
12465 @@ -1100,6 +1100,8 @@ xfs_ioc_fsgeometry(
12466 #define LINUX_XFLAG_APPEND 0x00000020 /* writes to file may only append */
12467 #define LINUX_XFLAG_NODUMP 0x00000040 /* do not dump file */
12468 #define LINUX_XFLAG_NOATIME 0x00000080 /* do not update atime */
12469 +#define LINUX_XFLAG_BARRIER 0x04000000 /* chroot() barrier */
12470 +#define LINUX_XFLAG_IUNLINK 0x08000000 /* immutable unlink */
12472 STATIC unsigned int
12473 xfs_merge_ioc_xflags(
12474 @@ -1140,6 +1142,10 @@ xfs_di2lxflags(
12476 if (di_flags & XFS_DIFLAG_IMMUTABLE)
12477 flags |= LINUX_XFLAG_IMMUTABLE;
12478 + if (di_flags & XFS_DIFLAG_IUNLINK)
12479 + flags |= LINUX_XFLAG_IUNLINK;
12480 + if (di_flags & XFS_DIFLAG_BARRIER)
12481 + flags |= LINUX_XFLAG_BARRIER;
12482 if (di_flags & XFS_DIFLAG_APPEND)
12483 flags |= LINUX_XFLAG_APPEND;
12484 if (di_flags & XFS_DIFLAG_SYNC)
12485 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_iops.c
12486 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_iops.c 2006-11-30 21:19:29 +0100
12487 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_iops.c 2006-11-30 18:53:18 +0100
12489 #include <linux/xattr.h>
12490 #include <linux/namei.h>
12491 #include <linux/security.h>
12492 +#include <linux/vs_tag.h>
12495 * Get a XFS inode from a given vnode.
12496 @@ -402,6 +403,7 @@ xfs_vn_lookup(
12497 d_add(dentry, NULL);
12500 + dx_propagate_tag(nd, vn_to_inode(cvp));
12502 return d_splice_alias(vn_to_inode(cvp), dentry);
12504 @@ -659,6 +661,10 @@ xfs_vn_setattr(
12508 + error = inode_change_ok(inode, attr);
12512 if (ia_valid & ATTR_UID) {
12513 vattr.va_mask |= XFS_AT_UID;
12514 vattr.va_uid = attr->ia_uid;
12515 @@ -667,6 +673,10 @@ xfs_vn_setattr(
12516 vattr.va_mask |= XFS_AT_GID;
12517 vattr.va_gid = attr->ia_gid;
12519 + if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode)) {
12520 + vattr.va_mask |= XFS_AT_TAG;
12521 + vattr.va_tag = attr->ia_tag;
12523 if (ia_valid & ATTR_SIZE) {
12524 vattr.va_mask |= XFS_AT_SIZE;
12525 vattr.va_size = attr->ia_size;
12526 @@ -712,6 +722,42 @@ xfs_vn_truncate(
12530 +xfs_vn_sync_flags(struct inode *inode)
12532 + unsigned int oldflags, newflags;
12535 + bhv_vattr_t vattr;
12536 + bhv_vnode_t *vp = vn_from_inode(inode);
12538 + memset(&vattr, 0, sizeof vattr);
12540 + vattr.va_mask = XFS_AT_XFLAGS;
12541 + error = bhv_vop_getattr(vp, &vattr, 0, NULL);
12545 + oldflags = vattr.va_xflags;
12546 + newflags = oldflags & ~(XFS_XFLAG_IMMUTABLE |
12547 + XFS_XFLAG_IUNLINK | XFS_XFLAG_BARRIER);
12549 + if (IS_IMMUTABLE(inode))
12550 + newflags |= XFS_XFLAG_IMMUTABLE;
12551 + if (IS_IUNLINK(inode))
12552 + newflags |= XFS_XFLAG_IUNLINK;
12553 + if (IS_BARRIER(inode))
12554 + newflags |= XFS_XFLAG_BARRIER;
12556 + if (oldflags ^ newflags) {
12557 + vattr.va_xflags = newflags;
12558 + vattr.va_mask |= XFS_AT_XFLAGS;
12559 + error = bhv_vop_setattr(vp, &vattr, flags, NULL);
12561 + vn_revalidate(vp);
12567 struct dentry *dentry,
12569 @@ -824,6 +870,7 @@ struct inode_operations xfs_inode_operat
12570 .getxattr = xfs_vn_getxattr,
12571 .listxattr = xfs_vn_listxattr,
12572 .removexattr = xfs_vn_removexattr,
12573 + .sync_flags = xfs_vn_sync_flags,
12576 struct inode_operations xfs_dir_inode_operations = {
12577 @@ -843,6 +890,7 @@ struct inode_operations xfs_dir_inode_op
12578 .getxattr = xfs_vn_getxattr,
12579 .listxattr = xfs_vn_listxattr,
12580 .removexattr = xfs_vn_removexattr,
12581 + .sync_flags = xfs_vn_sync_flags,
12584 struct inode_operations xfs_symlink_inode_operations = {
12585 @@ -856,4 +904,5 @@ struct inode_operations xfs_symlink_inod
12586 .getxattr = xfs_vn_getxattr,
12587 .listxattr = xfs_vn_listxattr,
12588 .removexattr = xfs_vn_removexattr,
12589 + .sync_flags = xfs_vn_sync_flags,
12591 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_linux.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_linux.h
12592 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_linux.h 2006-11-30 21:19:29 +0100
12593 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_linux.h 2006-11-08 04:57:47 +0100
12594 @@ -139,6 +139,7 @@ BUFFER_FNS(PrivateStart, unwritten);
12595 #define current_pid() (current->pid)
12596 #define current_fsuid(cred) (current->fsuid)
12597 #define current_fsgid(cred) (current->fsgid)
12598 +#define current_fstag(cred,vp) (dx_current_fstag(vn_to_inode(vp)->i_sb))
12599 #define current_test_flags(f) (current->flags & (f))
12600 #define current_set_flags_nested(sp, f) \
12601 (*(sp) = current->flags, current->flags |= (f))
12602 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_super.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_super.c
12603 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_super.c 2006-11-30 21:19:29 +0100
12604 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_super.c 2006-11-20 21:12:32 +0100
12605 @@ -158,6 +158,7 @@ xfs_revalidate_inode(
12606 inode->i_nlink = ip->i_d.di_nlink;
12607 inode->i_uid = ip->i_d.di_uid;
12608 inode->i_gid = ip->i_d.di_gid;
12609 + inode->i_tag = ip->i_d.di_tag;
12611 switch (inode->i_mode & S_IFMT) {
12613 @@ -185,6 +186,14 @@ xfs_revalidate_inode(
12614 inode->i_flags |= S_IMMUTABLE;
12616 inode->i_flags &= ~S_IMMUTABLE;
12617 + if (ip->i_d.di_flags & XFS_DIFLAG_IUNLINK)
12618 + inode->i_flags |= S_IUNLINK;
12620 + inode->i_flags &= ~S_IUNLINK;
12621 + if (ip->i_d.di_flags & XFS_DIFLAG_BARRIER)
12622 + inode->i_flags |= S_BARRIER;
12624 + inode->i_flags &= ~S_BARRIER;
12625 if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
12626 inode->i_flags |= S_APPEND;
12628 @@ -708,6 +717,12 @@ xfs_fs_remount(
12631 error = bhv_vfs_parseargs(vfsp, options, args, 1);
12632 + if ((args->flags2 & XFSMNT2_TAGGED) &&
12633 + !(sb->s_flags & MS_TAGGED)) {
12634 + printk("XFS: %s: tagging not permitted on remount.\n",
12639 error = bhv_vfs_mntupdate(vfsp, flags, args);
12640 kmem_free(args, sizeof(*args));
12641 @@ -731,36 +746,40 @@ xfs_fs_show_options(
12645 - struct super_block *sb,
12646 + struct dqhash *hash,
12649 + struct super_block *sb = hash->dqh_sb;
12650 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL);
12655 - struct super_block *sb,
12656 + struct dqhash *hash,
12657 struct fs_quota_stat *fqs)
12659 + struct super_block *sb = hash->dqh_sb;
12660 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
12665 - struct super_block *sb,
12666 + struct dqhash *hash,
12667 unsigned int flags,
12670 + struct super_block *sb = hash->dqh_sb;
12671 return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags);
12676 - struct super_block *sb,
12677 + struct dqhash *hash,
12680 struct fs_disk_quota *fdq)
12682 + struct super_block *sb = hash->dqh_sb;
12683 return -bhv_vfs_quotactl(vfs_from_sb(sb),
12684 (type == USRQUOTA) ? Q_XGETQUOTA :
12685 ((type == GRPQUOTA) ? Q_XGETGQUOTA :
12686 @@ -769,11 +788,12 @@ xfs_fs_getxquota(
12690 - struct super_block *sb,
12691 + struct dqhash *hash,
12694 struct fs_disk_quota *fdq)
12696 + struct super_block *sb = hash->dqh_sb;
12697 return -bhv_vfs_quotactl(vfs_from_sb(sb),
12698 (type == USRQUOTA) ? Q_XSETQLIM :
12699 ((type == GRPQUOTA) ? Q_XSETGQLIM :
12700 @@ -803,6 +823,9 @@ xfs_fs_fill_super(
12701 sb_min_blocksize(sb, BBSIZE);
12702 sb->s_export_op = &xfs_export_operations;
12703 sb->s_qcop = &xfs_quotactl_operations;
12704 +#ifdef CONFIG_QUOTACTL
12705 + sb->s_dqh->dqh_qcop = &xfs_quotactl_operations;
12707 sb->s_op = &xfs_super_operations;
12709 error = bhv_vfs_mount(vfsp, args, NULL);
12710 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_sysctl.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_sysctl.c
12711 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_sysctl.c 2006-09-20 16:58:39 +0200
12712 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_sysctl.c 2006-11-08 04:57:40 +0100
12713 @@ -57,79 +57,79 @@ xfs_stats_clear_proc_handler(
12714 STATIC ctl_table xfs_table[] = {
12715 {XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown.val,
12716 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12717 - &sysctl_intvec, NULL,
12718 + NULL, &sysctl_intvec, NULL,
12719 &xfs_params.restrict_chown.min, &xfs_params.restrict_chown.max},
12721 {XFS_SGID_INHERIT, "irix_sgid_inherit", &xfs_params.sgid_inherit.val,
12722 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12723 - &sysctl_intvec, NULL,
12724 + NULL, &sysctl_intvec, NULL,
12725 &xfs_params.sgid_inherit.min, &xfs_params.sgid_inherit.max},
12727 {XFS_SYMLINK_MODE, "irix_symlink_mode", &xfs_params.symlink_mode.val,
12728 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12729 - &sysctl_intvec, NULL,
12730 + NULL, &sysctl_intvec, NULL,
12731 &xfs_params.symlink_mode.min, &xfs_params.symlink_mode.max},
12733 {XFS_PANIC_MASK, "panic_mask", &xfs_params.panic_mask.val,
12734 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12735 - &sysctl_intvec, NULL,
12736 + NULL, &sysctl_intvec, NULL,
12737 &xfs_params.panic_mask.min, &xfs_params.panic_mask.max},
12739 {XFS_ERRLEVEL, "error_level", &xfs_params.error_level.val,
12740 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12741 - &sysctl_intvec, NULL,
12742 + NULL, &sysctl_intvec, NULL,
12743 &xfs_params.error_level.min, &xfs_params.error_level.max},
12745 {XFS_SYNCD_TIMER, "xfssyncd_centisecs", &xfs_params.syncd_timer.val,
12746 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12747 - &sysctl_intvec, NULL,
12748 + NULL, &sysctl_intvec, NULL,
12749 &xfs_params.syncd_timer.min, &xfs_params.syncd_timer.max},
12751 {XFS_INHERIT_SYNC, "inherit_sync", &xfs_params.inherit_sync.val,
12752 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12753 - &sysctl_intvec, NULL,
12754 + NULL, &sysctl_intvec, NULL,
12755 &xfs_params.inherit_sync.min, &xfs_params.inherit_sync.max},
12757 {XFS_INHERIT_NODUMP, "inherit_nodump", &xfs_params.inherit_nodump.val,
12758 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12759 - &sysctl_intvec, NULL,
12760 + NULL, &sysctl_intvec, NULL,
12761 &xfs_params.inherit_nodump.min, &xfs_params.inherit_nodump.max},
12763 {XFS_INHERIT_NOATIME, "inherit_noatime", &xfs_params.inherit_noatim.val,
12764 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12765 - &sysctl_intvec, NULL,
12766 + NULL, &sysctl_intvec, NULL,
12767 &xfs_params.inherit_noatim.min, &xfs_params.inherit_noatim.max},
12769 {XFS_BUF_TIMER, "xfsbufd_centisecs", &xfs_params.xfs_buf_timer.val,
12770 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12771 - &sysctl_intvec, NULL,
12772 + NULL, &sysctl_intvec, NULL,
12773 &xfs_params.xfs_buf_timer.min, &xfs_params.xfs_buf_timer.max},
12775 {XFS_BUF_AGE, "age_buffer_centisecs", &xfs_params.xfs_buf_age.val,
12776 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12777 - &sysctl_intvec, NULL,
12778 + NULL, &sysctl_intvec, NULL,
12779 &xfs_params.xfs_buf_age.min, &xfs_params.xfs_buf_age.max},
12781 {XFS_INHERIT_NOSYM, "inherit_nosymlinks", &xfs_params.inherit_nosym.val,
12782 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12783 - &sysctl_intvec, NULL,
12784 + NULL, &sysctl_intvec, NULL,
12785 &xfs_params.inherit_nosym.min, &xfs_params.inherit_nosym.max},
12787 {XFS_ROTORSTEP, "rotorstep", &xfs_params.rotorstep.val,
12788 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12789 - &sysctl_intvec, NULL,
12790 + NULL, &sysctl_intvec, NULL,
12791 &xfs_params.rotorstep.min, &xfs_params.rotorstep.max},
12793 {XFS_INHERIT_NODFRG, "inherit_nodefrag", &xfs_params.inherit_nodfrg.val,
12794 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12795 - &sysctl_intvec, NULL,
12796 + NULL, &sysctl_intvec, NULL,
12797 &xfs_params.inherit_nodfrg.min, &xfs_params.inherit_nodfrg.max},
12799 /* please keep this the last entry */
12800 #ifdef CONFIG_PROC_FS
12801 {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
12802 sizeof(int), 0644, NULL, &xfs_stats_clear_proc_handler,
12803 - &sysctl_intvec, NULL,
12804 + NULL, &sysctl_intvec, NULL,
12805 &xfs_params.stats_clear.min, &xfs_params.stats_clear.max},
12806 #endif /* CONFIG_PROC_FS */
12808 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_vnode.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_vnode.c
12809 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_vnode.c 2006-11-30 21:19:29 +0100
12810 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_vnode.c 2006-11-08 04:57:46 +0100
12811 @@ -119,6 +119,7 @@ vn_revalidate_core(
12812 inode->i_nlink = vap->va_nlink;
12813 inode->i_uid = vap->va_uid;
12814 inode->i_gid = vap->va_gid;
12815 + inode->i_tag = vap->va_tag;
12816 inode->i_blocks = vap->va_nblocks;
12817 inode->i_mtime = vap->va_mtime;
12818 inode->i_ctime = vap->va_ctime;
12819 @@ -126,6 +127,14 @@ vn_revalidate_core(
12820 inode->i_flags |= S_IMMUTABLE;
12822 inode->i_flags &= ~S_IMMUTABLE;
12823 + if (vap->va_xflags & XFS_XFLAG_IUNLINK)
12824 + inode->i_flags |= S_IUNLINK;
12826 + inode->i_flags &= ~S_IUNLINK;
12827 + if (vap->va_xflags & XFS_XFLAG_BARRIER)
12828 + inode->i_flags |= S_BARRIER;
12830 + inode->i_flags &= ~S_BARRIER;
12831 if (vap->va_xflags & XFS_XFLAG_APPEND)
12832 inode->i_flags |= S_APPEND;
12834 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_vnode.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_vnode.h
12835 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_vnode.h 2006-11-30 21:19:29 +0100
12836 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_vnode.h 2006-11-08 04:57:46 +0100
12837 @@ -350,6 +350,7 @@ typedef struct bhv_vattr {
12838 xfs_nlink_t va_nlink; /* number of references to file */
12839 uid_t va_uid; /* owner user id */
12840 gid_t va_gid; /* owner group id */
12841 + tag_t va_tag; /* owner group id */
12842 xfs_ino_t va_nodeid; /* file id */
12843 xfs_off_t va_size; /* file size in bytes */
12844 u_long va_blocksize; /* blocksize preferred for i/o */
12845 @@ -398,13 +399,15 @@ typedef struct bhv_vattr {
12846 #define XFS_AT_PROJID 0x04000000
12847 #define XFS_AT_SIZE_NOPERM 0x08000000
12848 #define XFS_AT_GENCOUNT 0x10000000
12849 +#define XFS_AT_TAG 0x20000000
12851 #define XFS_AT_ALL (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
12852 XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
12853 XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\
12854 XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|XFS_AT_MAC|\
12855 XFS_AT_ACL|XFS_AT_CAP|XFS_AT_INF|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|\
12856 - XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT)
12857 + XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT\
12860 #define XFS_AT_STAT (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
12861 XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
12862 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/quota/xfs_qm_syscalls.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/quota/xfs_qm_syscalls.c
12863 --- linux-2.6.19.1/fs/xfs/quota/xfs_qm_syscalls.c 2006-09-20 16:58:40 +0200
12864 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/quota/xfs_qm_syscalls.c 2006-11-30 18:53:18 +0100
12868 #include <linux/capability.h>
12869 +#include <linux/vs_context.h>
12872 #include "xfs_fs.h"
12873 @@ -213,7 +214,7 @@ xfs_qm_scall_quotaoff(
12874 xfs_qoff_logitem_t *qoffstart;
12877 - if (!force && !capable(CAP_SYS_ADMIN))
12878 + if (!force && !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12879 return XFS_ERROR(EPERM);
12881 * No file system can have quotas enabled on disk but not in core.
12882 @@ -382,7 +383,7 @@ xfs_qm_scall_trunc_qfiles(
12886 - if (!capable(CAP_SYS_ADMIN))
12887 + if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12888 return XFS_ERROR(EPERM);
12890 if (!XFS_SB_VERSION_HASQUOTA(&mp->m_sb) || flags == 0) {
12891 @@ -427,7 +428,7 @@ xfs_qm_scall_quotaon(
12895 - if (!capable(CAP_SYS_ADMIN))
12896 + if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12897 return XFS_ERROR(EPERM);
12899 flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
12900 @@ -598,7 +599,7 @@ xfs_qm_scall_setqlim(
12902 xfs_qcnt_t hard, soft;
12904 - if (!capable(CAP_SYS_ADMIN))
12905 + if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12906 return XFS_ERROR(EPERM);
12908 if ((newlim->d_fieldmask &
12909 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_clnt.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_clnt.h
12910 --- linux-2.6.19.1/fs/xfs/xfs_clnt.h 2006-06-18 04:54:50 +0200
12911 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_clnt.h 2006-11-08 04:57:46 +0100
12912 @@ -99,5 +99,7 @@ struct xfs_mount_args {
12914 #define XFSMNT2_COMPAT_IOSIZE 0x00000001 /* don't report large preferred
12915 * I/O size in stat(2) */
12916 +#define XFSMNT2_TAGGED 0x80000000 /* context tagging */
12919 #endif /* __XFS_CLNT_H__ */
12920 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_dinode.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_dinode.h
12921 --- linux-2.6.19.1/fs/xfs/xfs_dinode.h 2006-09-20 16:58:40 +0200
12922 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_dinode.h 2006-11-08 04:57:46 +0100
12923 @@ -53,7 +53,8 @@ typedef struct xfs_dinode_core
12924 __uint32_t di_gid; /* owner's group id */
12925 __uint32_t di_nlink; /* number of links to file */
12926 __uint16_t di_projid; /* owner's project id */
12927 - __uint8_t di_pad[8]; /* unused, zeroed space */
12928 + __uint16_t di_tag; /* context tagging */
12929 + __uint8_t di_pad[6]; /* unused, zeroed space */
12930 __uint16_t di_flushiter; /* incremented on flush */
12931 xfs_timestamp_t di_atime; /* time last accessed */
12932 xfs_timestamp_t di_mtime; /* time last modified */
12933 @@ -257,6 +258,9 @@ typedef enum xfs_dinode_fmt
12934 #define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */
12935 #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */
12936 #define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */
12937 +#define XFS_DIFLAG_BARRIER_BIT 14 /* chroot() barrier */
12938 +#define XFS_DIFLAG_IUNLINK_BIT 15 /* immutable unlink */
12940 #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT)
12941 #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT)
12942 #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT)
12943 @@ -271,12 +275,15 @@ typedef enum xfs_dinode_fmt
12944 #define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT)
12945 #define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
12946 #define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT)
12947 +#define XFS_DIFLAG_BARRIER (1 << XFS_DIFLAG_BARRIER_BIT)
12948 +#define XFS_DIFLAG_IUNLINK (1 << XFS_DIFLAG_IUNLINK_BIT)
12950 #define XFS_DIFLAG_ANY \
12951 (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
12952 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
12953 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
12954 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
12955 - XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG)
12956 + XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_BARRIER | \
12957 + XFS_DIFLAG_IUNLINK)
12959 #endif /* __XFS_DINODE_H__ */
12960 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_fs.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_fs.h
12961 --- linux-2.6.19.1/fs/xfs/xfs_fs.h 2006-11-30 21:19:29 +0100
12962 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_fs.h 2006-11-08 04:57:46 +0100
12963 @@ -66,6 +66,8 @@ struct fsxattr {
12964 #define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
12965 #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
12966 #define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
12967 +#define XFS_XFLAG_BARRIER 0x00004000 /* chroot() barrier */
12968 +#define XFS_XFLAG_IUNLINK 0x00008000 /* immutable unlink */
12969 #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
12972 @@ -294,7 +296,8 @@ typedef struct xfs_bstat {
12973 __s32 bs_extents; /* number of extents */
12974 __u32 bs_gen; /* generation count */
12975 __u16 bs_projid; /* project id */
12976 - unsigned char bs_pad[14]; /* pad space, unused */
12977 + __u16 bs_tag; /* context tagging */
12978 + unsigned char bs_pad[12]; /* pad space, unused */
12979 __u32 bs_dmevmask; /* DMIG event mask */
12980 __u16 bs_dmstate; /* DMIG state info */
12981 __u16 bs_aextents; /* attribute number of extents */
12982 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_inode.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_inode.c
12983 --- linux-2.6.19.1/fs/xfs/xfs_inode.c 2006-11-30 21:19:29 +0100
12984 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_inode.c 2006-11-30 20:55:45 +0100
12986 #include "xfs_mac.h"
12987 #include "xfs_acl.h"
12989 +#include <linux/vs_tag.h>
12991 kmem_zone_t *xfs_ifork_zone;
12992 kmem_zone_t *xfs_inode_zone;
12993 @@ -736,20 +737,35 @@ xfs_xlate_dinode_core(
12994 xfs_dinode_core_t *buf_core = (xfs_dinode_core_t *)buf;
12995 xfs_dinode_core_t *mem_core = (xfs_dinode_core_t *)dip;
12996 xfs_arch_t arch = ARCH_CONVERT;
12997 + uint32_t uid = 0, gid = 0;
12998 + uint16_t tag = 0;
13003 + tag = mem_core->di_tag;
13004 + /* FIXME: supposed to use superblock flag */
13005 + uid = TAGINO_UID(1, mem_core->di_uid, tag);
13006 + gid = TAGINO_GID(1, mem_core->di_gid, tag);
13007 + tag = TAGINO_TAG(1, tag);
13010 INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch);
13011 INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch);
13012 INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch);
13013 INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch);
13014 INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch);
13015 - INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch);
13016 - INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch);
13017 + INT_XLATE(buf_core->di_uid, uid, dir, arch);
13018 + INT_XLATE(buf_core->di_gid, gid, dir, arch);
13019 + INT_XLATE(buf_core->di_tag, tag, dir, arch);
13020 INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch);
13021 INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch);
13024 + /* FIXME: supposed to use superblock flag */
13025 + mem_core->di_uid = INOTAG_UID(1, uid, gid);
13026 + mem_core->di_gid = INOTAG_GID(1, uid, gid);
13027 + mem_core->di_tag = INOTAG_TAG(1, uid, gid, tag);
13028 memcpy(mem_core->di_pad, buf_core->di_pad,
13029 sizeof(buf_core->di_pad));
13031 @@ -797,6 +813,10 @@ _xfs_dic2xflags(
13032 flags |= XFS_XFLAG_PREALLOC;
13033 if (di_flags & XFS_DIFLAG_IMMUTABLE)
13034 flags |= XFS_XFLAG_IMMUTABLE;
13035 + if (di_flags & XFS_DIFLAG_IUNLINK)
13036 + flags |= XFS_XFLAG_IUNLINK;
13037 + if (di_flags & XFS_DIFLAG_BARRIER)
13038 + flags |= XFS_XFLAG_BARRIER;
13039 if (di_flags & XFS_DIFLAG_APPEND)
13040 flags |= XFS_XFLAG_APPEND;
13041 if (di_flags & XFS_DIFLAG_SYNC)
13042 @@ -1128,6 +1148,7 @@ xfs_ialloc(
13043 ASSERT(ip->i_d.di_nlink == nlink);
13044 ip->i_d.di_uid = current_fsuid(cr);
13045 ip->i_d.di_gid = current_fsgid(cr);
13046 + ip->i_d.di_tag = current_fstag(cr, vp);
13047 ip->i_d.di_projid = prid;
13048 memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
13050 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_itable.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_itable.c
13051 --- linux-2.6.19.1/fs/xfs/xfs_itable.c 2006-11-30 21:19:29 +0100
13052 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_itable.c 2006-11-08 04:57:46 +0100
13053 @@ -89,6 +89,7 @@ xfs_bulkstat_one_iget(
13054 buf->bs_mode = dic->di_mode;
13055 buf->bs_uid = dic->di_uid;
13056 buf->bs_gid = dic->di_gid;
13057 + buf->bs_tag = dic->di_tag;
13058 buf->bs_size = dic->di_size;
13059 vn_atime_to_bstime(vp, &buf->bs_atime);
13060 buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
13061 @@ -163,6 +164,7 @@ xfs_bulkstat_one_dinode(
13062 buf->bs_mode = INT_GET(dic->di_mode, ARCH_CONVERT);
13063 buf->bs_uid = INT_GET(dic->di_uid, ARCH_CONVERT);
13064 buf->bs_gid = INT_GET(dic->di_gid, ARCH_CONVERT);
13065 + buf->bs_tag = INT_GET(dic->di_tag, ARCH_CONVERT);
13066 buf->bs_size = INT_GET(dic->di_size, ARCH_CONVERT);
13067 buf->bs_atime.tv_sec = INT_GET(dic->di_atime.t_sec, ARCH_CONVERT);
13068 buf->bs_atime.tv_nsec = INT_GET(dic->di_atime.t_nsec, ARCH_CONVERT);
13069 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_mount.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_mount.h
13070 --- linux-2.6.19.1/fs/xfs/xfs_mount.h 2006-11-30 21:19:29 +0100
13071 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_mount.h 2006-11-08 04:57:46 +0100
13072 @@ -460,6 +460,7 @@ typedef struct xfs_mount {
13073 #define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23) /* don't use per-cpu superblock
13076 +#define XFS_MOUNT_TAGGED (1ULL << 31) /* context tagging */
13079 * Default minimum read and write sizes.
13080 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_vfsops.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_vfsops.c
13081 --- linux-2.6.19.1/fs/xfs/xfs_vfsops.c 2006-11-30 21:19:29 +0100
13082 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_vfsops.c 2006-11-08 04:57:47 +0100
13083 @@ -300,6 +300,8 @@ xfs_start_flags(
13085 if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE)
13086 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
13087 + if (ap->flags2 & XFSMNT2_TAGGED)
13088 + mp->m_flags |= XFS_MOUNT_TAGGED;
13091 * no recovery flag requires a read-only mount
13092 @@ -394,6 +396,8 @@ xfs_finish_flags(
13093 return XFS_ERROR(EINVAL);
13096 + if (ap->flags2 & XFSMNT2_TAGGED)
13097 + vfs->vfs_super->s_flags |= MS_TAGGED;
13101 @@ -1645,6 +1649,9 @@ xfs_vget(
13103 #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
13104 #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
13105 +#define MNTOPT_TAGXID "tagxid" /* context tagging for inodes */
13106 +#define MNTOPT_TAGGED "tag" /* context tagging for inodes */
13107 +#define MNTOPT_NOTAGTAG "notag" /* do not use context tagging */
13109 STATIC unsigned long
13110 suffix_strtoul(char *s, char **endp, unsigned int base)
13111 @@ -1831,6 +1838,19 @@ xfs_parseargs(
13112 args->flags |= XFSMNT_ATTR2;
13113 } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
13114 args->flags &= ~XFSMNT_ATTR2;
13115 +#ifndef CONFIG_TAGGING_NONE
13116 + } else if (!strcmp(this_char, MNTOPT_TAGGED)) {
13117 + args->flags2 |= XFSMNT2_TAGGED;
13118 + } else if (!strcmp(this_char, MNTOPT_NOTAGTAG)) {
13119 + args->flags2 &= ~XFSMNT2_TAGGED;
13120 + } else if (!strcmp(this_char, MNTOPT_TAGXID)) {
13121 + args->flags2 |= XFSMNT2_TAGGED;
13123 +#ifdef CONFIG_PROPAGATE
13124 + } else if (!strcmp(this_char, MNTOPT_TAGGED)) {
13126 + args->flags2 |= XFSMNT2_TAGGED;
13128 } else if (!strcmp(this_char, "osyncisdsync")) {
13129 /* no-op, this is now the default */
13131 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_vnodeops.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_vnodeops.c
13132 --- linux-2.6.19.1/fs/xfs/xfs_vnodeops.c 2006-11-30 21:19:29 +0100
13133 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_vnodeops.c 2006-11-20 21:12:32 +0100
13134 @@ -160,6 +160,7 @@ xfs_getattr(
13135 vap->va_mode = ip->i_d.di_mode;
13136 vap->va_uid = ip->i_d.di_uid;
13137 vap->va_gid = ip->i_d.di_gid;
13138 + vap->va_tag = ip->i_d.di_tag;
13139 vap->va_projid = ip->i_d.di_projid;
13142 @@ -260,6 +261,7 @@ xfs_setattr(
13143 uint commit_flags=0;
13144 uid_t uid=0, iuid=0;
13145 gid_t gid=0, igid=0;
13146 + tag_t tag=0, itag=0;
13149 xfs_prid_t projid=0, iprojid=0;
13150 @@ -316,6 +318,7 @@ xfs_setattr(
13151 (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
13154 + /* FIXME: handle tagging? */
13155 if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
13157 qflags |= XFS_QMOPT_UQUOTA;
13158 @@ -395,6 +398,8 @@ xfs_setattr(
13160 (XFS_AT_MODE|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_UID|
13161 XFS_AT_GID|XFS_AT_PROJID)) {
13162 + /* FIXME: handle tagging? */
13165 * CAP_FOWNER overrides the following restrictions:
13167 @@ -443,7 +448,7 @@ xfs_setattr(
13168 * and can change the group id only to a group of which he
13169 * or she is a member.
13171 - if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
13172 + if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|XFS_AT_PROJID)) {
13174 * These IDs could have changed since we last looked at them.
13175 * But, we're assured that if the ownership did change
13176 @@ -451,10 +456,12 @@ xfs_setattr(
13177 * would have changed also.
13179 iuid = ip->i_d.di_uid;
13180 - iprojid = ip->i_d.di_projid;
13181 igid = ip->i_d.di_gid;
13182 - gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
13183 + itag = ip->i_d.di_tag;
13184 + iprojid = ip->i_d.di_projid;
13185 uid = (mask & XFS_AT_UID) ? vap->va_uid : iuid;
13186 + gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
13187 + tag = (mask & XFS_AT_TAG) ? vap->va_tag : itag;
13188 projid = (mask & XFS_AT_PROJID) ? (xfs_prid_t)vap->va_projid :
13191 @@ -482,6 +489,7 @@ xfs_setattr(
13192 if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
13193 (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
13194 (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
13195 + /* FIXME: handle tagging? */
13197 code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
13198 capable(CAP_FOWNER) ?
13199 @@ -707,7 +715,7 @@ xfs_setattr(
13200 * and can change the group id only to a group of which he
13201 * or she is a member.
13203 - if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
13204 + if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|XFS_AT_PROJID)) {
13206 * CAP_FSETID overrides the following restrictions:
13208 @@ -723,6 +731,12 @@ xfs_setattr(
13209 * Change the ownerships and register quota modifications
13210 * in the transaction.
13212 + if (itag != tag) {
13213 + if (XFS_IS_GQUOTA_ON(mp)) {
13214 + /* FIXME: handle tag quota? */
13216 + ip->i_d.di_tag = tag;
13219 if (XFS_IS_UQUOTA_ON(mp)) {
13220 ASSERT(mask & XFS_AT_UID);
13221 @@ -803,6 +817,10 @@ xfs_setattr(
13222 di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
13223 if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
13224 di_flags |= XFS_DIFLAG_IMMUTABLE;
13225 + if (vap->va_xflags & XFS_XFLAG_IUNLINK)
13226 + di_flags |= XFS_DIFLAG_IUNLINK;
13227 + if (vap->va_xflags & XFS_XFLAG_BARRIER)
13228 + di_flags |= XFS_DIFLAG_BARRIER;
13229 if (vap->va_xflags & XFS_XFLAG_APPEND)
13230 di_flags |= XFS_DIFLAG_APPEND;
13231 if (vap->va_xflags & XFS_XFLAG_SYNC)
13232 diff -NurpP --minimal linux-2.6.19.1/include/asm-arm/tlb.h linux-2.6.19.1-vs2.3.0.6/include/asm-arm/tlb.h
13233 --- linux-2.6.19.1/include/asm-arm/tlb.h 2006-06-18 04:54:58 +0200
13234 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-arm/tlb.h 2006-11-08 04:57:40 +0100
13236 #else /* !CONFIG_MMU */
13238 #include <asm/pgalloc.h>
13239 +#include <linux/vs_memory.h>
13242 * TLB handling. This allows us to remove pages from the page
13243 diff -NurpP --minimal linux-2.6.19.1/include/asm-arm26/tlb.h linux-2.6.19.1-vs2.3.0.6/include/asm-arm26/tlb.h
13244 --- linux-2.6.19.1/include/asm-arm26/tlb.h 2006-01-03 17:30:02 +0100
13245 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-arm26/tlb.h 2006-11-08 04:57:40 +0100
13248 #include <asm/pgalloc.h>
13249 #include <asm/tlbflush.h>
13250 +#include <linux/vs_memory.h>
13253 * TLB handling. This allows us to remove pages from the page
13254 diff -NurpP --minimal linux-2.6.19.1/include/asm-arm26/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-arm26/unistd.h
13255 --- linux-2.6.19.1/include/asm-arm26/unistd.h 2006-11-30 21:19:31 +0100
13256 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-arm26/unistd.h 2006-11-08 04:57:41 +0100
13257 @@ -302,6 +302,8 @@
13258 #define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
13259 #define __NR_waitid (__NR_SYSCALL_BASE+280)
13261 +#define __NR_vserver (__NR_SYSCALL_BASE+313)
13264 * The following SWIs are ARM private. FIXME - make appropriate for arm26
13266 diff -NurpP --minimal linux-2.6.19.1/include/asm-generic/tlb.h linux-2.6.19.1-vs2.3.0.6/include/asm-generic/tlb.h
13267 --- linux-2.6.19.1/include/asm-generic/tlb.h 2006-11-30 21:19:31 +0100
13268 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-generic/tlb.h 2006-11-08 04:57:40 +0100
13270 #define _ASM_GENERIC__TLB_H
13272 #include <linux/swap.h>
13273 +#include <linux/vs_memory.h>
13274 #include <asm/pgalloc.h>
13275 #include <asm/tlbflush.h>
13277 diff -NurpP --minimal linux-2.6.19.1/include/asm-i386/elf.h linux-2.6.19.1-vs2.3.0.6/include/asm-i386/elf.h
13278 --- linux-2.6.19.1/include/asm-i386/elf.h 2006-11-30 21:19:31 +0100
13279 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-i386/elf.h 2006-11-08 04:57:53 +0100
13280 @@ -75,7 +75,7 @@ typedef struct user_fxsr_struct elf_fpxr
13281 the loader. We need to make sure that it is out of the way of the program
13282 that it will "exec", and that there is sufficient room for the brk. */
13284 -#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
13285 +#define ELF_ET_DYN_BASE ((TASK_UNMAPPED_BASE) * 2)
13287 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
13288 now struct_user_regs, they are different) */
13289 diff -NurpP --minimal linux-2.6.19.1/include/asm-ia64/tlb.h linux-2.6.19.1-vs2.3.0.6/include/asm-ia64/tlb.h
13290 --- linux-2.6.19.1/include/asm-ia64/tlb.h 2006-09-20 16:58:40 +0200
13291 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-ia64/tlb.h 2006-11-08 04:57:40 +0100
13293 #include <linux/mm.h>
13294 #include <linux/pagemap.h>
13295 #include <linux/swap.h>
13296 +#include <linux/vs_memory.h>
13298 #include <asm/pgalloc.h>
13299 #include <asm/processor.h>
13300 diff -NurpP --minimal linux-2.6.19.1/include/asm-powerpc/systbl.h linux-2.6.19.1-vs2.3.0.6/include/asm-powerpc/systbl.h
13301 --- linux-2.6.19.1/include/asm-powerpc/systbl.h 2006-11-30 21:19:33 +0100
13302 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-powerpc/systbl.h 2006-11-20 21:12:32 +0100
13303 @@ -260,7 +260,7 @@ COMPAT_SYS_SPU(fstatfs64)
13304 SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64)
13306 OLDSYS(debug_setcontext)
13307 -SYSCALL(ni_syscall)
13308 +SYSX(sys_vserver, sys32_vserver, sys_vserver)
13309 COMPAT_SYS(migrate_pages)
13311 COMPAT_SYS(get_mempolicy)
13312 diff -NurpP --minimal linux-2.6.19.1/include/asm-powerpc/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-powerpc/unistd.h
13313 --- linux-2.6.19.1/include/asm-powerpc/unistd.h 2006-11-30 21:19:33 +0100
13314 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-powerpc/unistd.h 2006-11-20 21:12:32 +0100
13315 @@ -275,7 +275,7 @@
13317 #define __NR_rtas 255
13318 #define __NR_sys_debug_setcontext 256
13319 -/* Number 257 is reserved for vserver */
13320 +#define __NR_vserver 257
13321 #define __NR_migrate_pages 258
13322 #define __NR_mbind 259
13323 #define __NR_get_mempolicy 260
13324 diff -NurpP --minimal linux-2.6.19.1/include/asm-s390/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-s390/unistd.h
13325 --- linux-2.6.19.1/include/asm-s390/unistd.h 2006-11-30 21:19:33 +0100
13326 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-s390/unistd.h 2006-11-08 04:57:41 +0100
13327 @@ -202,7 +202,7 @@
13328 #define __NR_clock_gettime (__NR_timer_create+6)
13329 #define __NR_clock_getres (__NR_timer_create+7)
13330 #define __NR_clock_nanosleep (__NR_timer_create+8)
13331 -/* Number 263 is reserved for vserver */
13332 +#define __NR_vserver 263
13333 #define __NR_statfs64 265
13334 #define __NR_fstatfs64 266
13335 #define __NR_remap_file_pages 267
13336 diff -NurpP --minimal linux-2.6.19.1/include/asm-sparc/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-sparc/unistd.h
13337 --- linux-2.6.19.1/include/asm-sparc/unistd.h 2006-11-30 21:19:34 +0100
13338 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-sparc/unistd.h 2006-11-08 21:52:09 +0100
13339 @@ -283,7 +283,7 @@
13340 #define __NR_timer_getoverrun 264
13341 #define __NR_timer_delete 265
13342 #define __NR_timer_create 266
13343 -/* #define __NR_vserver 267 Reserved for VSERVER */
13344 +#define __NR_vserver 267
13345 #define __NR_io_setup 268
13346 #define __NR_io_destroy 269
13347 #define __NR_io_submit 270
13348 diff -NurpP --minimal linux-2.6.19.1/include/asm-sparc64/tlb.h linux-2.6.19.1-vs2.3.0.6/include/asm-sparc64/tlb.h
13349 --- linux-2.6.19.1/include/asm-sparc64/tlb.h 2006-09-20 16:58:43 +0200
13350 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-sparc64/tlb.h 2006-11-08 04:57:40 +0100
13352 #define _SPARC64_TLB_H
13354 #include <linux/swap.h>
13355 +#include <linux/vs_memory.h>
13356 #include <asm/pgalloc.h>
13357 #include <asm/tlbflush.h>
13358 #include <asm/mmu_context.h>
13359 diff -NurpP --minimal linux-2.6.19.1/include/asm-sparc64/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-sparc64/unistd.h
13360 --- linux-2.6.19.1/include/asm-sparc64/unistd.h 2006-11-30 21:19:35 +0100
13361 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-sparc64/unistd.h 2006-11-08 21:52:09 +0100
13362 @@ -285,7 +285,7 @@
13363 #define __NR_timer_getoverrun 264
13364 #define __NR_timer_delete 265
13365 #define __NR_timer_create 266
13366 -/* #define __NR_vserver 267 Reserved for VSERVER */
13367 +#define __NR_vserver 267
13368 #define __NR_io_setup 268
13369 #define __NR_io_destroy 269
13370 #define __NR_io_submit 270
13371 diff -NurpP --minimal linux-2.6.19.1/include/asm-x86_64/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-x86_64/unistd.h
13372 --- linux-2.6.19.1/include/asm-x86_64/unistd.h 2006-11-30 21:19:37 +0100
13373 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-x86_64/unistd.h 2006-11-08 04:57:41 +0100
13374 @@ -532,7 +532,7 @@ __SYSCALL(__NR_tgkill, sys_tgkill)
13375 #define __NR_utimes 235
13376 __SYSCALL(__NR_utimes, sys_utimes)
13377 #define __NR_vserver 236
13378 -__SYSCALL(__NR_vserver, sys_ni_syscall)
13379 +__SYSCALL(__NR_vserver, sys_vserver)
13380 #define __NR_mbind 237
13381 __SYSCALL(__NR_mbind, sys_mbind)
13382 #define __NR_set_mempolicy 238
13383 diff -NurpP --minimal linux-2.6.19.1/include/linux/Kbuild linux-2.6.19.1-vs2.3.0.6/include/linux/Kbuild
13384 --- linux-2.6.19.1/include/linux/Kbuild 2006-11-30 21:19:37 +0100
13385 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/Kbuild 2006-11-08 04:57:49 +0100
13386 @@ -345,3 +345,6 @@ unifdef-y += xfrm.h
13387 unifdef-y += zftape.h
13389 objhdr-y += version.h
13391 +header-y += vserver/
13393 diff -NurpP --minimal linux-2.6.19.1/include/linux/capability.h linux-2.6.19.1-vs2.3.0.6/include/linux/capability.h
13394 --- linux-2.6.19.1/include/linux/capability.h 2006-06-18 04:55:15 +0200
13395 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/capability.h 2006-11-08 04:57:40 +0100
13396 @@ -235,6 +235,7 @@ typedef __u32 kernel_cap_t;
13397 arbitrary SCSI commands */
13398 /* Allow setting encryption key on loopback filesystem */
13399 /* Allow setting zone reclaim policy */
13400 +/* Allow the selection of a security context */
13402 #define CAP_SYS_ADMIN 21
13404 @@ -288,6 +289,11 @@ typedef __u32 kernel_cap_t;
13406 #define CAP_AUDIT_CONTROL 30
13408 +/* Allow context manipulations */
13409 +/* Allow changing context info on files */
13411 +#define CAP_CONTEXT 31
13416 diff -NurpP --minimal linux-2.6.19.1/include/linux/devpts_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/devpts_fs.h
13417 --- linux-2.6.19.1/include/linux/devpts_fs.h 2004-08-14 12:55:59 +0200
13418 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/devpts_fs.h 2006-11-08 04:57:53 +0100
13419 @@ -30,5 +30,7 @@ static inline void devpts_pty_kill(int n
13423 +#define DEVPTS_SUPER_MAGIC 0x00001cd1
13426 #endif /* _LINUX_DEVPTS_FS_H */
13427 diff -NurpP --minimal linux-2.6.19.1/include/linux/ext2_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/ext2_fs.h
13428 --- linux-2.6.19.1/include/linux/ext2_fs.h 2006-11-30 21:19:37 +0100
13429 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/ext2_fs.h 2006-11-08 04:57:46 +0100
13430 @@ -188,6 +188,8 @@ struct ext2_group_desc
13431 #define EXT2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */
13432 #define EXT2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */
13433 #define EXT2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/
13434 +#define EXT2_BARRIER_FL FS_BARRIER_FL /* Barrier for chroot() */
13435 +#define EXT2_IUNLINK_FL FS_IUNLINK_FL /* Immutable unlink */
13436 #define EXT2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */
13438 #define EXT2_FL_USER_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */
13439 @@ -244,7 +246,7 @@ struct ext2_inode {
13441 __u8 l_i_frag; /* Fragment number */
13442 __u8 l_i_fsize; /* Fragment size */
13444 + __u16 l_i_tag; /* Context Tag */
13445 __le16 l_i_uid_high; /* these 2 fields */
13446 __le16 l_i_gid_high; /* were reserved2[0] */
13447 __u32 l_i_reserved2;
13448 @@ -276,6 +278,7 @@ struct ext2_inode {
13449 #define i_gid_low i_gid
13450 #define i_uid_high osd2.linux2.l_i_uid_high
13451 #define i_gid_high osd2.linux2.l_i_gid_high
13452 +#define i_raw_tag osd2.linux2.l_i_tag
13453 #define i_reserved2 osd2.linux2.l_i_reserved2
13456 @@ -317,8 +320,9 @@ struct ext2_inode {
13457 #define EXT2_MOUNT_XATTR_USER 0x004000 /* Extended user attributes */
13458 #define EXT2_MOUNT_POSIX_ACL 0x008000 /* POSIX Access Control Lists */
13459 #define EXT2_MOUNT_XIP 0x010000 /* Execute in place */
13460 -#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */
13461 -#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */
13462 +#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */
13463 +#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */
13464 +#define EXT2_MOUNT_TAGGED (1<<24) /* Enable Context Tags */
13467 #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
13468 diff -NurpP --minimal linux-2.6.19.1/include/linux/ext3_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/ext3_fs.h
13469 --- linux-2.6.19.1/include/linux/ext3_fs.h 2006-11-30 21:19:37 +0100
13470 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/ext3_fs.h 2006-12-17 04:14:42 +0100
13471 @@ -177,6 +177,8 @@ struct ext3_group_desc
13472 #define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */
13473 #define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
13474 #define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
13475 +#define EXT3_BARRIER_FL 0x04000000 /* Barrier for chroot() */
13476 +#define EXT3_IUNLINK_FL 0x08000000 /* Immutable unlink */
13477 #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */
13479 #define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
13480 @@ -296,7 +298,7 @@ struct ext3_inode {
13482 __u8 l_i_frag; /* Fragment number */
13483 __u8 l_i_fsize; /* Fragment size */
13485 + __u16 l_i_tag; /* Context Tag */
13486 __le16 l_i_uid_high; /* these 2 fields */
13487 __le16 l_i_gid_high; /* were reserved2[0] */
13488 __u32 l_i_reserved2;
13489 @@ -330,6 +332,7 @@ struct ext3_inode {
13490 #define i_gid_low i_gid
13491 #define i_uid_high osd2.linux2.l_i_uid_high
13492 #define i_gid_high osd2.linux2.l_i_gid_high
13493 +#define i_raw_tag osd2.linux2.l_i_tag
13494 #define i_reserved2 osd2.linux2.l_i_reserved2
13496 #elif defined(__GNU__)
13497 @@ -384,6 +387,7 @@ struct ext3_inode {
13498 #define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */
13499 #define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
13500 #define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
13501 +#define EXT3_MOUNT_TAGGED (1<<24) /* Enable Context Tags */
13503 /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
13504 #ifndef _LINUX_EXT2_FS_H
13505 @@ -812,6 +816,7 @@ struct buffer_head * ext3_bread (handle_
13506 int ext3_get_blocks_handle(handle_t *handle, struct inode *inode,
13507 sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
13508 int create, int extend_disksize);
13509 +extern int ext3_sync_flags(struct inode *inode);
13511 extern void ext3_read_inode (struct inode *);
13512 extern int ext3_write_inode (struct inode *, int);
13513 diff -NurpP --minimal linux-2.6.19.1/include/linux/ext3_jbd.h linux-2.6.19.1-vs2.3.0.6/include/linux/ext3_jbd.h
13514 --- linux-2.6.19.1/include/linux/ext3_jbd.h 2006-11-30 21:19:37 +0100
13515 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/ext3_jbd.h 2006-11-08 04:57:51 +0100
13516 @@ -77,10 +77,10 @@
13517 #define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0)
13518 /* Amount of blocks needed for quota insert/delete - we do some block writes
13519 * but inode, sb and group updates are done only once */
13520 -#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\
13521 - (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0)
13522 -#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\
13523 - (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0)
13524 +#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? \
13525 + (DQUOT_INIT_ALLOC*(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0)
13526 +#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? \
13527 + (DQUOT_DEL_ALLOC*(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0)
13529 #define EXT3_QUOTA_TRANS_BLOCKS(sb) 0
13530 #define EXT3_QUOTA_INIT_BLOCKS(sb) 0
13531 diff -NurpP --minimal linux-2.6.19.1/include/linux/ext4_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/ext4_fs.h
13532 --- linux-2.6.19.1/include/linux/ext4_fs.h 2006-11-30 21:19:37 +0100
13533 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/ext4_fs.h 2006-12-17 04:16:26 +0100
13534 @@ -189,8 +189,10 @@ struct ext4_group_desc
13535 #define EXT4_NOTAIL_FL 0x00008000 /* file tail should not be merged */
13536 #define EXT4_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
13537 #define EXT4_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
13538 -#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
13539 #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
13540 +#define EXT4_BARRIER_FL 0x04000000 /* Barrier for chroot() */
13541 +#define EXT4_IUNLINK_FL 0x08000000 /* Immutable unlink */
13542 +#define EXT4_RESERVED_FL 0x80000000 /* reserved for ext4 lib */
13544 #define EXT4_FL_USER_VISIBLE 0x000BDFFF /* User visible flags */
13545 #define EXT4_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
13546 @@ -312,7 +314,8 @@ struct ext4_inode {
13547 __le16 l_i_file_acl_high;
13548 __le16 l_i_uid_high; /* these 2 fields */
13549 __le16 l_i_gid_high; /* were reserved2[0] */
13550 - __u32 l_i_reserved2;
13551 + __u16 l_i_tag; /* Context Tag */
13552 + __u16 l_i_reserved2;
13555 __u8 h_i_frag; /* Fragment number */
13556 @@ -344,6 +347,7 @@ struct ext4_inode {
13557 #define i_gid_low i_gid
13558 #define i_uid_high osd2.linux2.l_i_uid_high
13559 #define i_gid_high osd2.linux2.l_i_gid_high
13560 +#define i_raw_tag osd2.linux2.l_i_tag
13561 #define i_reserved2 osd2.linux2.l_i_reserved2
13563 #elif defined(__GNU__)
13564 @@ -400,6 +404,7 @@ struct ext4_inode {
13565 #define EXT4_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
13566 #define EXT4_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
13567 #define EXT4_MOUNT_EXTENTS 0x400000 /* Extents support */
13568 +#define EXT4_MOUNT_TAGGED (1<<24) /* Enable Context Tags */
13570 /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */
13571 #ifndef _LINUX_EXT2_FS_H
13572 @@ -843,6 +848,7 @@ struct buffer_head * ext4_bread (handle_
13573 int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
13574 sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
13575 int create, int extend_disksize);
13576 +extern int ext4_sync_flags(struct inode *inode);
13578 extern void ext4_read_inode (struct inode *);
13579 extern int ext4_write_inode (struct inode *, int);
13580 diff -NurpP --minimal linux-2.6.19.1/include/linux/fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/fs.h
13581 --- linux-2.6.19.1/include/linux/fs.h 2006-11-30 21:19:38 +0100
13582 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/fs.h 2006-12-17 04:16:36 +0100
13583 @@ -120,6 +120,8 @@ extern int dir_notify_enable;
13584 #define MS_PRIVATE (1<<18) /* change to private */
13585 #define MS_SLAVE (1<<19) /* change to slave */
13586 #define MS_SHARED (1<<20) /* change to shared */
13587 +#define MS_TAGGED (1<<24) /* use generic inode tagging */
13588 +#define MS_TAGID (1<<25) /* use specific tag for this mount */
13589 #define MS_ACTIVE (1<<30)
13590 #define MS_NOUSER (1<<31)
13592 @@ -146,6 +148,8 @@ extern int dir_notify_enable;
13593 #define S_NOCMTIME 128 /* Do not update file c/mtime */
13594 #define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */
13595 #define S_PRIVATE 512 /* Inode is fs-internal */
13596 +#define S_BARRIER 1024 /* Barrier for chroot() */
13597 +#define S_IUNLINK 2048 /* Immutable unlink */
13600 * Note that nosuid etc flags are inode-specific: setting some file-system
13601 @@ -162,23 +166,35 @@ extern int dir_notify_enable;
13603 #define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))
13605 -#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
13606 +#define IS_RDONLY(inode) __IS_FLG(inode, MS_RDONLY)
13607 #define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \
13608 ((inode)->i_flags & S_SYNC))
13609 #define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \
13610 ((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
13611 #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
13612 +#define IS_TAGGED(inode) __IS_FLG(inode, MS_TAGGED)
13614 #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
13615 #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
13616 #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
13617 +#define IS_IUNLINK(inode) ((inode)->i_flags & S_IUNLINK)
13618 +#define IS_IXORUNLINK(inode) ((IS_IUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode))
13619 #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
13621 +#define IS_BARRIER(inode) (S_ISDIR((inode)->i_mode) && ((inode)->i_flags & S_BARRIER))
13622 #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
13623 #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME)
13624 #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE)
13625 #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE)
13627 +#ifdef CONFIG_VSERVER_COWBL
13628 +# define IS_COW(inode) (IS_IUNLINK(inode) && IS_IMMUTABLE(inode))
13629 +# define IS_COW_LINK(inode) (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1))
13631 +# define IS_COW(inode) (0)
13632 +# define IS_COW_LINK(inode) (0)
13635 /* the read-only stuff doesn't really belong here, but any other place is
13636 probably as bad and I don't want to create yet another include file. */
13638 @@ -252,12 +268,13 @@ extern int dir_notify_enable;
13639 #define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
13640 #define FS_EXTENT_FL 0x00080000 /* Extents */
13641 #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */
13642 +#define FS_BARRIER_FL 0x04000000 /* Barrier for chroot() */
13643 +#define FS_IUNLINK_FL 0x08000000 /* Immutable unlink */
13644 #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
13646 #define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
13647 #define FS_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
13650 #define SYNC_FILE_RANGE_WAIT_BEFORE 1
13651 #define SYNC_FILE_RANGE_WRITE 2
13652 #define SYNC_FILE_RANGE_WAIT_AFTER 4
13653 @@ -322,6 +339,7 @@ typedef void (dio_iodone_t)(struct kiocb
13654 #define ATTR_KILL_SUID 2048
13655 #define ATTR_KILL_SGID 4096
13656 #define ATTR_FILE 8192
13657 +#define ATTR_TAG 16384
13660 * This is the Inode Attributes structure, used for notify_change(). It
13661 @@ -337,6 +355,7 @@ struct iattr {
13667 struct timespec ia_atime;
13668 struct timespec ia_mtime;
13669 @@ -350,6 +369,9 @@ struct iattr {
13670 struct file *ia_file;
13673 +#define ATTR_FLAG_BARRIER 512 /* Barrier for chroot() */
13674 +#define ATTR_FLAG_IUNLINK 1024 /* Immutable unlink */
13677 * Includes for diskquotas.
13679 @@ -547,6 +569,7 @@ struct inode {
13680 unsigned int i_nlink;
13686 struct timespec i_atime;
13687 @@ -565,6 +588,9 @@ struct inode {
13688 struct file_lock *i_flock;
13689 struct address_space *i_mapping;
13690 struct address_space i_data;
13691 +#ifdef CONFIG_QUOTACTL
13692 + struct dqhash *i_dqh;
13694 #ifdef CONFIG_QUOTA
13695 struct dquot *i_dquot[MAXQUOTAS];
13697 @@ -735,6 +761,7 @@ struct file {
13699 struct fown_struct f_owner;
13700 unsigned int f_uid, f_gid;
13702 struct file_ra_state f_ra;
13704 unsigned long f_version;
13705 @@ -817,6 +844,7 @@ struct file_lock {
13706 unsigned char fl_type;
13711 struct fasync_struct * fl_fasync; /* for lease break notifications */
13712 unsigned long fl_break_time; /* for nonblocking lease breaks */
13713 @@ -918,7 +946,7 @@ struct super_block {
13714 unsigned long long s_maxbytes; /* Max file size */
13715 struct file_system_type *s_type;
13716 struct super_operations *s_op;
13717 - struct dquot_operations *dq_op;
13718 + struct dquot_operations *s_qop;
13719 struct quotactl_ops *s_qcop;
13720 struct export_operations *s_export_op;
13721 unsigned long s_flags;
13722 @@ -943,7 +971,7 @@ struct super_block {
13724 struct block_device *s_bdev;
13725 struct list_head s_instances;
13726 - struct quota_info s_dquot; /* Diskquota specific options */
13727 + struct dqhash *s_dqh; /* Diskquota hash */
13730 wait_queue_head_t s_wait_unfrozen;
13731 @@ -1013,12 +1041,12 @@ static inline void unlock_super(struct s
13733 extern int vfs_permission(struct nameidata *, int);
13734 extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
13735 -extern int vfs_mkdir(struct inode *, struct dentry *, int);
13736 -extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
13737 -extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
13738 -extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
13739 -extern int vfs_rmdir(struct inode *, struct dentry *);
13740 -extern int vfs_unlink(struct inode *, struct dentry *);
13741 +extern int vfs_mkdir(struct inode *, struct dentry *, int, struct nameidata *);
13742 +extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t, struct nameidata *);
13743 +extern int vfs_symlink(struct inode *, struct dentry *, const char *, int, struct nameidata *);
13744 +extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct nameidata *);
13745 +extern int vfs_rmdir(struct inode *, struct dentry *, struct nameidata *);
13746 +extern int vfs_unlink(struct inode *, struct dentry *, struct nameidata *);
13747 extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
13750 @@ -1158,6 +1186,7 @@ struct inode_operations {
13751 ssize_t (*listxattr) (struct dentry *, char *, size_t);
13752 int (*removexattr) (struct dentry *, const char *);
13753 void (*truncate_range)(struct inode *, loff_t, loff_t);
13754 + int (*sync_flags) (struct inode *);
13758 @@ -1173,6 +1202,7 @@ extern ssize_t vfs_readv(struct file *,
13759 unsigned long, loff_t *);
13760 extern ssize_t vfs_writev(struct file *, const struct iovec __user *,
13761 unsigned long, loff_t *);
13762 +ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
13765 * NOTE: write_inode, delete_inode, clear_inode, put_inode can be called
13766 @@ -1202,8 +1232,8 @@ struct super_operations {
13767 int (*show_options)(struct seq_file *, struct vfsmount *);
13768 int (*show_stats)(struct seq_file *, struct vfsmount *);
13769 #ifdef CONFIG_QUOTA
13770 - ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
13771 - ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
13772 + ssize_t (*quota_read)(struct dqhash *, int, char *, size_t, loff_t);
13773 + ssize_t (*quota_write)(struct dqhash *, int, const char *, size_t, loff_t);
13777 @@ -1715,7 +1745,7 @@ extern struct inode *new_inode(struct su
13778 extern int __remove_suid(struct dentry *, int);
13779 extern int should_remove_suid(struct dentry *);
13780 extern int remove_suid(struct dentry *);
13781 -extern void remove_dquot_ref(struct super_block *, int, struct list_head *);
13782 +extern void remove_dquot_ref(struct dqhash *, int, struct list_head *);
13784 extern void __insert_inode_hash(struct inode *, unsigned long hashval);
13785 extern void remove_inode_hash(struct inode *);
13786 @@ -1751,6 +1781,7 @@ extern ssize_t generic_file_buffered_wri
13787 extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
13788 extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
13789 extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
13790 +extern ssize_t generic_file_sendpage(struct file *, struct page *, int, size_t, loff_t *, int);
13791 extern void do_generic_mapping_read(struct address_space *mapping,
13792 struct file_ra_state *, struct file *,
13793 loff_t *, read_descriptor_t *, read_actor_t);
13794 @@ -1884,6 +1915,7 @@ extern int dcache_dir_open(struct inode
13795 extern int dcache_dir_close(struct inode *, struct file *);
13796 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
13797 extern int dcache_readdir(struct file *, void *, filldir_t);
13798 +extern int dcache_readdir_filter(struct file *, void *, filldir_t, int (*)(struct dentry *));
13799 extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
13800 extern int simple_statfs(struct dentry *, struct kstatfs *);
13801 extern int simple_link(struct dentry *, struct inode *, struct dentry *);
13802 diff -NurpP --minimal linux-2.6.19.1/include/linux/init_task.h linux-2.6.19.1-vs2.3.0.6/include/linux/init_task.h
13803 --- linux-2.6.19.1/include/linux/init_task.h 2006-11-30 21:19:38 +0100
13804 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/init_task.h 2006-11-08 04:57:40 +0100
13805 @@ -140,6 +140,10 @@ extern struct group_info init_groups;
13806 .pi_lock = SPIN_LOCK_UNLOCKED, \
13807 INIT_TRACE_IRQFLAGS \
13810 + .vx_info = NULL, \
13812 + .nx_info = NULL, \
13816 diff -NurpP --minimal linux-2.6.19.1/include/linux/ipc.h linux-2.6.19.1-vs2.3.0.6/include/linux/ipc.h
13817 --- linux-2.6.19.1/include/linux/ipc.h 2006-11-30 21:19:38 +0100
13818 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/ipc.h 2006-11-08 20:20:37 +0100
13819 @@ -63,6 +63,7 @@ struct kern_ipc_perm
13827 diff -NurpP --minimal linux-2.6.19.1/include/linux/jffs2.h linux-2.6.19.1-vs2.3.0.6/include/linux/jffs2.h
13828 --- linux-2.6.19.1/include/linux/jffs2.h 2006-11-30 21:19:38 +0100
13829 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/jffs2.h 2006-12-16 10:19:32 +0100
13830 @@ -82,12 +82,16 @@
13831 //#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
13834 -#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
13835 +#define JFFS2_INO_FLAG_PREREAD 0x01 /* Do read_inode() for this one at
13836 mount time, don't wait for it to
13838 -#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific
13839 +#define JFFS2_INO_FLAG_USERCOMPR 0x02 /* User has requested a specific
13840 compression type */
13842 +#define JFFS2_INO_FLAG_IMMUTABLE 0x10 /* immutable node */
13843 +#define JFFS2_INO_FLAG_IUNLINK 0x20 /* immutable unlink */
13844 +#define JFFS2_INO_FLAG_BARRIER 0x40 /* barrier */
13847 /* These can go once we've made sure we've caught all uses without
13849 diff -NurpP --minimal linux-2.6.19.1/include/linux/loop.h linux-2.6.19.1-vs2.3.0.6/include/linux/loop.h
13850 --- linux-2.6.19.1/include/linux/loop.h 2006-11-30 21:19:38 +0100
13851 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/loop.h 2006-11-08 04:57:52 +0100
13852 @@ -45,6 +45,7 @@ struct loop_device {
13853 struct loop_func_table *lo_encryption;
13855 uid_t lo_key_owner; /* Who set the key */
13857 int (*ioctl)(struct loop_device *, int cmd,
13858 unsigned long arg);
13860 diff -NurpP --minimal linux-2.6.19.1/include/linux/major.h linux-2.6.19.1-vs2.3.0.6/include/linux/major.h
13861 --- linux-2.6.19.1/include/linux/major.h 2006-06-18 04:55:19 +0200
13862 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/major.h 2006-11-08 04:57:51 +0100
13864 #define HD_MAJOR IDE0_MAJOR
13865 #define PTY_SLAVE_MAJOR 3
13866 #define TTY_MAJOR 4
13867 +#define VROOT_MAJOR 4
13868 #define TTYAUX_MAJOR 5
13870 #define VCS_MAJOR 7
13871 diff -NurpP --minimal linux-2.6.19.1/include/linux/mount.h linux-2.6.19.1-vs2.3.0.6/include/linux/mount.h
13872 --- linux-2.6.19.1/include/linux/mount.h 2006-09-20 16:58:44 +0200
13873 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/mount.h 2006-11-08 04:57:52 +0100
13874 @@ -27,12 +27,16 @@ struct namespace;
13875 #define MNT_NOEXEC 0x04
13876 #define MNT_NOATIME 0x08
13877 #define MNT_NODIRATIME 0x10
13878 +#define MNT_RDONLY 0x20
13880 +#define MNT_IS_RDONLY(m) ((m) && ((m)->mnt_flags & MNT_RDONLY))
13882 #define MNT_SHRINKABLE 0x100
13884 #define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */
13885 #define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */
13886 #define MNT_PNODE_MASK 0x3000 /* propogation flag mask */
13887 +#define MNT_TAGID 0x8000
13890 struct list_head mnt_hash;
13891 @@ -54,6 +58,7 @@ struct vfsmount {
13892 struct vfsmount *mnt_master; /* slave is on master->mnt_slave_list */
13893 struct namespace *mnt_namespace; /* containing namespace */
13895 + tag_t mnt_tag; /* tagging used for vfsmount */
13898 static inline struct vfsmount *mntget(struct vfsmount *mnt)
13899 diff -NurpP --minimal linux-2.6.19.1/include/linux/net.h linux-2.6.19.1-vs2.3.0.6/include/linux/net.h
13900 --- linux-2.6.19.1/include/linux/net.h 2006-11-30 21:19:38 +0100
13901 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/net.h 2006-11-08 04:57:42 +0100
13902 @@ -63,6 +63,7 @@ typedef enum {
13903 #define SOCK_NOSPACE 2
13904 #define SOCK_PASSCRED 3
13905 #define SOCK_PASSSEC 4
13906 +#define SOCK_USER_SOCKET 5
13908 #ifndef ARCH_HAS_SOCKET_TYPES
13910 diff -NurpP --minimal linux-2.6.19.1/include/linux/nfs_mount.h linux-2.6.19.1-vs2.3.0.6/include/linux/nfs_mount.h
13911 --- linux-2.6.19.1/include/linux/nfs_mount.h 2005-08-29 22:25:42 +0200
13912 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/nfs_mount.h 2006-11-08 04:57:47 +0100
13913 @@ -61,6 +61,7 @@ struct nfs_mount_data {
13914 #define NFS_MOUNT_NOACL 0x0800 /* 4 */
13915 #define NFS_MOUNT_STRICTLOCK 0x1000 /* reserved for NFSv4 */
13916 #define NFS_MOUNT_SECFLAVOUR 0x2000 /* 5 */
13917 +#define NFS_MOUNT_TAGGED 0x8000 /* context tagging */
13918 #define NFS_MOUNT_FLAGMASK 0xFFFF
13921 diff -NurpP --minimal linux-2.6.19.1/include/linux/nsproxy.h linux-2.6.19.1-vs2.3.0.6/include/linux/nsproxy.h
13922 --- linux-2.6.19.1/include/linux/nsproxy.h 2006-11-30 21:19:39 +0100
13923 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/nsproxy.h 2006-11-30 20:55:45 +0100
13924 @@ -51,4 +51,10 @@ static inline void exit_task_namespaces(
13929 +static inline void get_nsproxy(struct nsproxy *ns)
13931 + atomic_inc(&ns->count);
13935 diff -NurpP --minimal linux-2.6.19.1/include/linux/percpu.h linux-2.6.19.1-vs2.3.0.6/include/linux/percpu.h
13936 --- linux-2.6.19.1/include/linux/percpu.h 2006-11-30 21:19:39 +0100
13937 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/percpu.h 2006-11-08 04:57:40 +0100
13940 /* Enough to cover all DEFINE_PER_CPUs in kernel, including modules. */
13941 #ifndef PERCPU_ENOUGH_ROOM
13942 -#define PERCPU_ENOUGH_ROOM 32768
13943 +#define PERCPU_ENOUGH_ROOM 65536
13947 diff -NurpP --minimal linux-2.6.19.1/include/linux/pid.h linux-2.6.19.1-vs2.3.0.6/include/linux/pid.h
13948 --- linux-2.6.19.1/include/linux/pid.h 2006-11-30 21:19:39 +0100
13949 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/pid.h 2006-11-08 04:57:52 +0100
13950 @@ -8,7 +8,8 @@ enum pid_type
13960 diff -NurpP --minimal linux-2.6.19.1/include/linux/proc_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/proc_fs.h
13961 --- linux-2.6.19.1/include/linux/proc_fs.h 2006-11-30 21:19:39 +0100
13962 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/proc_fs.h 2006-12-09 03:46:57 +0100
13963 @@ -54,6 +54,7 @@ struct proc_dir_entry {
13969 struct inode_operations * proc_iops;
13970 const struct file_operations * proc_fops;
13971 @@ -247,10 +248,14 @@ extern void kclist_add(struct kcore_list
13973 int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
13974 int (*proc_read)(struct task_struct *task, char *page);
13975 + int (*proc_vs_read)(char *page);
13976 + int (*proc_vxi_read)(struct vx_info *vxi, char *page);
13977 + int (*proc_nxi_read)(struct nx_info *nxi, char *page);
13980 struct proc_inode {
13985 struct proc_dir_entry *pde;
13986 diff -NurpP --minimal linux-2.6.19.1/include/linux/quota.h linux-2.6.19.1-vs2.3.0.6/include/linux/quota.h
13987 --- linux-2.6.19.1/include/linux/quota.h 2006-09-20 16:58:44 +0200
13988 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/quota.h 2006-11-08 04:57:51 +0100
13989 @@ -55,6 +55,13 @@ extern spinlock_t dq_data_lock;
13990 #define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10))
13991 #define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
13993 +/* are NULL dqhash ptrs valid? */
13994 +#ifdef HANDLE_DQHASH_NULL
13995 +#define dqhash_valid(hash) ((hash) != NULL)
13997 +#define dqhash_valid(hash) (0 == 0)
14000 #define MAXQUOTAS 2
14001 #define USRQUOTA 0 /* element used for user quotas */
14002 #define GRPQUOTA 1 /* element used for group quotas */
14003 @@ -176,19 +183,20 @@ struct mem_dqinfo {
14007 -struct super_block;
14010 #define DQF_MASK 0xffff /* Mask for format specific flags */
14011 #define DQF_INFO_DIRTY_B 16
14012 #define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B) /* Is info dirty? */
14014 -extern void mark_info_dirty(struct super_block *sb, int type);
14015 +extern void mark_info_dirty(struct dqhash *hash, int type);
14017 #define info_dirty(info) test_bit(DQF_INFO_DIRTY_B, &(info)->dqi_flags)
14018 #define info_any_dquot_dirty(info) (!list_empty(&(info)->dqi_dirty_list))
14019 #define info_any_dirty(info) (info_dirty(info) || info_any_dquot_dirty(info))
14021 -#define sb_dqopt(sb) (&(sb)->s_dquot)
14022 -#define sb_dqinfo(sb, type) (sb_dqopt(sb)->info+(type))
14023 +#define dqh_dqopt(hash) (&(hash)->dqh_dqopt)
14024 +#define dqh_dqinfo(hash, type) (dqh_dqopt(hash)->info+(type))
14028 @@ -218,7 +226,7 @@ struct dquot {
14029 struct mutex dq_lock; /* dquot IO lock */
14030 atomic_t dq_count; /* Use count */
14031 wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */
14032 - struct super_block *dq_sb; /* superblock this applies to */
14033 + struct dqhash *dq_dqh; /* quota hash backpointer */
14034 unsigned int dq_id; /* ID this applies to (uid, gid) */
14035 loff_t dq_off; /* Offset of dquot on disk */
14036 unsigned long dq_flags; /* See DQ_* */
14037 @@ -233,13 +241,14 @@ struct dquot {
14039 /* Operations which must be implemented by each quota format */
14040 struct quota_format_ops {
14041 - int (*check_quota_file)(struct super_block *sb, int type); /* Detect whether file is in our format */
14042 - int (*read_file_info)(struct super_block *sb, int type); /* Read main info about file - called on quotaon() */
14043 - int (*write_file_info)(struct super_block *sb, int type); /* Write main info about file */
14044 - int (*free_file_info)(struct super_block *sb, int type); /* Called on quotaoff() */
14045 - int (*read_dqblk)(struct dquot *dquot); /* Read structure for one user */
14046 - int (*commit_dqblk)(struct dquot *dquot); /* Write structure for one user */
14047 - int (*release_dqblk)(struct dquot *dquot); /* Called when last reference to dquot is being dropped */
14048 + int (*check_quota_file)(struct dqhash *, int); /* Detect whether file is in our format */
14049 + int (*read_file_info)(struct dqhash *, int); /* Read main info about file - called on quotaon() */
14050 + int (*write_file_info)(struct dqhash *, int); /* Write main info about file */
14051 + int (*free_file_info)(struct dqhash *, int); /* Called on quotaoff() */
14053 + int (*read_dqblk)(struct dquot *); /* Read structure for one user */
14054 + int (*commit_dqblk)(struct dquot *); /* Write structure for one user */
14055 + int (*release_dqblk)(struct dquot *); /* Called when last reference to dquot is being dropped */
14058 /* Operations working with dquots */
14059 @@ -255,22 +264,22 @@ struct dquot_operations {
14060 int (*acquire_dquot) (struct dquot *); /* Quota is going to be created on disk */
14061 int (*release_dquot) (struct dquot *); /* Quota is going to be deleted from disk */
14062 int (*mark_dirty) (struct dquot *); /* Dquot is marked dirty */
14063 - int (*write_info) (struct super_block *, int); /* Write of quota "superblock" */
14064 + int (*write_info) (struct dqhash *, int); /* Write of quota "superblock" */
14067 /* Operations handling requests from userspace */
14068 struct quotactl_ops {
14069 - int (*quota_on)(struct super_block *, int, int, char *);
14070 - int (*quota_off)(struct super_block *, int);
14071 - int (*quota_sync)(struct super_block *, int);
14072 - int (*get_info)(struct super_block *, int, struct if_dqinfo *);
14073 - int (*set_info)(struct super_block *, int, struct if_dqinfo *);
14074 - int (*get_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
14075 - int (*set_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
14076 - int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
14077 - int (*set_xstate)(struct super_block *, unsigned int, int);
14078 - int (*get_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
14079 - int (*set_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
14080 + int (*quota_on)(struct dqhash *, int, int, char *);
14081 + int (*quota_off)(struct dqhash *, int);
14082 + int (*quota_sync)(struct dqhash *, int);
14083 + int (*get_info)(struct dqhash *, int, struct if_dqinfo *);
14084 + int (*set_info)(struct dqhash *, int, struct if_dqinfo *);
14085 + int (*get_dqblk)(struct dqhash *, int, qid_t, struct if_dqblk *);
14086 + int (*set_dqblk)(struct dqhash *, int, qid_t, struct if_dqblk *);
14087 + int (*get_xstate)(struct dqhash *, struct fs_quota_stat *);
14088 + int (*set_xstate)(struct dqhash *, unsigned int, int);
14089 + int (*get_xquota)(struct dqhash *, int, qid_t, struct fs_disk_quota *);
14090 + int (*set_xquota)(struct dqhash *, int, qid_t, struct fs_disk_quota *);
14093 struct quota_format_type {
14094 @@ -293,16 +302,15 @@ struct quota_info {
14095 struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */
14098 -/* Inline would be better but we need to dereference super_block which is not defined yet */
14099 -int mark_dquot_dirty(struct dquot *dquot);
14101 #define dquot_dirty(dquot) test_bit(DQ_MOD_B, &(dquot)->dq_flags)
14103 -#define sb_has_quota_enabled(sb, type) ((type)==USRQUOTA ? \
14104 - (sb_dqopt(sb)->flags & DQUOT_USR_ENABLED) : (sb_dqopt(sb)->flags & DQUOT_GRP_ENABLED))
14105 +#define dqh_has_quota_enabled(hash, type) (dqhash_valid(hash) && ((type)==USRQUOTA ? \
14106 + (dqh_dqopt(hash)->flags & DQUOT_USR_ENABLED) : (dqh_dqopt(hash)->flags & DQUOT_GRP_ENABLED)))
14108 +#define dqh_any_quota_enabled(hash) (dqhash_valid(hash) && \
14109 + (dqh_has_quota_enabled(hash, USRQUOTA) || dqh_has_quota_enabled(hash, GRPQUOTA)))
14111 -#define sb_any_quota_enabled(sb) (sb_has_quota_enabled(sb, USRQUOTA) | \
14112 - sb_has_quota_enabled(sb, GRPQUOTA))
14114 int register_quota_format(struct quota_format_type *fmt);
14115 void unregister_quota_format(struct quota_format_type *fmt);
14116 @@ -317,6 +325,50 @@ struct quota_module_name {
14117 {QFMT_VFS_V0, "quota_v2"},\
14121 + struct list_head dqh_list; /* List of all quota hashes */
14122 + unsigned int dqh_id; /* ID for hash */
14123 + atomic_t dqh_count; /* Use count */
14124 + struct quota_info dqh_dqopt; /* Diskquota specific options */
14125 + struct dquot_operations *dqh_qop;
14126 + struct quotactl_ops *dqh_qcop;
14127 + struct super_block *dqh_sb; /* super block */
14128 + unsigned int dqh_hash_bits;
14129 + unsigned int dqh_hash_mask;
14130 + struct hlist_head *dqh_hash;
14133 +#ifdef CONFIG_QUOTACTL
14135 +struct dqhash *new_dqhash(struct super_block *, unsigned int);
14136 +void destroy_dqhash(struct dqhash *);
14137 +struct dqhash *find_dqhash(unsigned int);
14139 +static inline void dqhput(struct dqhash *hash)
14141 + if (dqhash_valid(hash))
14142 + if (atomic_dec_and_test(&hash->dqh_count))
14143 + destroy_dqhash(hash);
14146 +static inline struct dqhash *dqhget(struct dqhash *hash)
14148 + if (dqhash_valid(hash))
14149 + atomic_inc(&hash->dqh_count);
14153 +#else /* CONFIG_QUOTACTL */
14155 +#define new_dqhash(sb, dqdom) (0)
14156 +#define find_dqhash(dqdom) (0)
14157 +#define destroy_dqhash(hash) do { } while(0)
14159 +#define dqhput(hash) do { } while(0)
14160 +#define dqhget(hash) (hash)
14162 +#endif /* CONFIG_QUOTACTL */
14166 # /* nodep */ include <sys/cdefs.h>
14167 diff -NurpP --minimal linux-2.6.19.1/include/linux/quotaops.h linux-2.6.19.1-vs2.3.0.6/include/linux/quotaops.h
14168 --- linux-2.6.19.1/include/linux/quotaops.h 2006-09-20 16:58:44 +0200
14169 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/quotaops.h 2006-11-08 04:57:51 +0100
14172 * declaration of quota_function calls in kernel.
14174 -extern void sync_dquots(struct super_block *sb, int type);
14175 +extern void sync_dquots(struct dqhash *hash, int type);
14177 extern int dquot_initialize(struct inode *inode, int type);
14178 extern int dquot_drop(struct inode *inode);
14179 @@ -34,19 +34,19 @@ extern int dquot_transfer(struct inode *
14180 extern int dquot_commit(struct dquot *dquot);
14181 extern int dquot_acquire(struct dquot *dquot);
14182 extern int dquot_release(struct dquot *dquot);
14183 -extern int dquot_commit_info(struct super_block *sb, int type);
14184 +extern int dquot_commit_info(struct dqhash *hash, int type);
14185 extern int dquot_mark_dquot_dirty(struct dquot *dquot);
14187 -extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path);
14188 -extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
14189 +extern int vfs_quota_on(struct dqhash *hash, int type, int format_id, char *path);
14190 +extern int vfs_quota_on_mount(struct dqhash *hash, char *qf_name,
14191 int format_id, int type);
14192 -extern int vfs_quota_off(struct super_block *sb, int type);
14193 -#define vfs_quota_off_mount(sb, type) vfs_quota_off(sb, type)
14194 -extern int vfs_quota_sync(struct super_block *sb, int type);
14195 -extern int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
14196 -extern int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
14197 -extern int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
14198 -extern int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
14199 +extern int vfs_quota_off(struct dqhash *hash, int type);
14200 +#define vfs_quota_off_mount(dqh, type) vfs_quota_off(dqh, type)
14201 +extern int vfs_quota_sync(struct dqhash *hash, int type);
14202 +extern int vfs_get_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii);
14203 +extern int vfs_set_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii);
14204 +extern int vfs_get_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di);
14205 +extern int vfs_set_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di);
14208 * Operations supported for diskquotas.
14209 @@ -61,9 +61,12 @@ extern struct quotactl_ops vfs_quotactl_
14210 * need a lot of space in journal for dquot structure allocation. */
14211 static __inline__ void DQUOT_INIT(struct inode *inode)
14213 - BUG_ON(!inode->i_sb);
14214 - if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode))
14215 - inode->i_sb->dq_op->initialize(inode, -1);
14216 + if (!dqhash_valid(inode->i_dqh))
14218 + BUG_ON(!inode->i_dqh);
14219 + // printk("DQUOT_INIT(%p,%p,%d)\n", inode, inode->i_dqh, dqh_any_quota_enabled(inode->i_dqh));
14220 + if (dqh_any_quota_enabled(inode->i_dqh) && !IS_NOQUOTA(inode))
14221 + inode->i_dqh->dqh_qop->initialize(inode, -1);
14224 /* The same as with DQUOT_INIT */
14225 @@ -72,8 +75,8 @@ static __inline__ void DQUOT_DROP(struct
14226 /* Here we can get arbitrary inode from clear_inode() so we have
14227 * to be careful. OTOH we don't need locking as quota operations
14228 * are allowed to change only at mount time */
14229 - if (!IS_NOQUOTA(inode) && inode->i_sb && inode->i_sb->dq_op
14230 - && inode->i_sb->dq_op->drop) {
14231 + if (!IS_NOQUOTA(inode) && inode->i_dqh && inode->i_dqh->dqh_qop
14232 + && inode->i_dqh->dqh_qop->drop) {
14234 /* Test before calling to rule out calls from proc and such
14235 * where we are not allowed to block. Note that this is
14236 @@ -84,7 +87,7 @@ static __inline__ void DQUOT_DROP(struct
14237 if (inode->i_dquot[cnt] != NODQUOT)
14239 if (cnt < MAXQUOTAS)
14240 - inode->i_sb->dq_op->drop(inode);
14241 + inode->i_dqh->dqh_qop->drop(inode);
14245 @@ -92,9 +95,9 @@ static __inline__ void DQUOT_DROP(struct
14246 * a transaction (deadlocks possible otherwise) */
14247 static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14249 - if (sb_any_quota_enabled(inode->i_sb)) {
14250 + if (dqh_any_quota_enabled(inode->i_dqh)) {
14251 /* Used space is updated in alloc_space() */
14252 - if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA)
14253 + if (inode->i_dqh->dqh_qop->alloc_space(inode, nr, 1) == NO_QUOTA)
14257 @@ -112,9 +115,9 @@ static __inline__ int DQUOT_PREALLOC_SPA
14259 static __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14261 - if (sb_any_quota_enabled(inode->i_sb)) {
14262 + if (dqh_any_quota_enabled(inode->i_dqh)) {
14263 /* Used space is updated in alloc_space() */
14264 - if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA)
14265 + if (inode->i_dqh->dqh_qop->alloc_space(inode, nr, 0) == NO_QUOTA)
14269 @@ -132,9 +135,9 @@ static __inline__ int DQUOT_ALLOC_SPACE(
14271 static __inline__ int DQUOT_ALLOC_INODE(struct inode *inode)
14273 - if (sb_any_quota_enabled(inode->i_sb)) {
14274 + if (dqh_any_quota_enabled(inode->i_dqh)) {
14276 - if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA)
14277 + if (inode->i_dqh->dqh_qop->alloc_inode(inode, 1) == NO_QUOTA)
14281 @@ -142,8 +145,8 @@ static __inline__ int DQUOT_ALLOC_INODE(
14283 static __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14285 - if (sb_any_quota_enabled(inode->i_sb))
14286 - inode->i_sb->dq_op->free_space(inode, nr);
14287 + if (dqh_any_quota_enabled(inode->i_dqh))
14288 + inode->i_dqh->dqh_qop->free_space(inode, nr);
14290 inode_sub_bytes(inode, nr);
14292 @@ -156,29 +159,30 @@ static __inline__ void DQUOT_FREE_SPACE(
14294 static __inline__ void DQUOT_FREE_INODE(struct inode *inode)
14296 - if (sb_any_quota_enabled(inode->i_sb))
14297 - inode->i_sb->dq_op->free_inode(inode, 1);
14298 + if (dqh_any_quota_enabled(inode->i_dqh))
14299 + inode->i_dqh->dqh_qop->free_inode(inode, 1);
14302 static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr)
14304 - if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) {
14305 + if (dqh_any_quota_enabled(inode->i_dqh) && !IS_NOQUOTA(inode)) {
14307 - if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA)
14308 + if (inode->i_dqh->dqh_qop->transfer(inode, iattr) == NO_QUOTA)
14314 /* The following two functions cannot be called inside a transaction */
14315 -#define DQUOT_SYNC(sb) sync_dquots(sb, -1)
14316 +#define DQUOT_SYNC(hash) sync_dquots(hash, -1)
14318 -static __inline__ int DQUOT_OFF(struct super_block *sb)
14319 +static __inline__ int DQUOT_OFF(struct dqhash *hash)
14323 - if (sb_any_quota_enabled(sb) && sb->s_qcop && sb->s_qcop->quota_off)
14324 - ret = sb->s_qcop->quota_off(sb, -1);
14325 + if (dqh_any_quota_enabled(hash) && hash->dqh_qcop &&
14326 + hash->dqh_qcop->quota_off)
14327 + ret = hash->dqh_qcop->quota_off(hash, -1);
14331 @@ -193,8 +197,8 @@ static __inline__ int DQUOT_OFF(struct s
14332 #define DQUOT_DROP(inode) do { } while(0)
14333 #define DQUOT_ALLOC_INODE(inode) (0)
14334 #define DQUOT_FREE_INODE(inode) do { } while(0)
14335 -#define DQUOT_SYNC(sb) do { } while(0)
14336 -#define DQUOT_OFF(sb) do { } while(0)
14337 +#define DQUOT_SYNC(hash) do { } while(0)
14338 +#define DQUOT_OFF(hash) do { } while(0)
14339 #define DQUOT_TRANSFER(inode, iattr) (0)
14340 static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14342 diff -NurpP --minimal linux-2.6.19.1/include/linux/reiserfs_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/reiserfs_fs.h
14343 --- linux-2.6.19.1/include/linux/reiserfs_fs.h 2006-11-30 21:19:39 +0100
14344 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/reiserfs_fs.h 2006-12-17 04:16:56 +0100
14345 @@ -821,6 +821,10 @@ struct stat_data_v1 {
14346 #define REISERFS_COMPR_FL FS_COMPR_FL
14347 #define REISERFS_NOTAIL_FL FS_NOTAIL_FL
14349 +/* unfortunately reiserfs sdattr is only 16 bit */
14350 +#define REISERFS_BARRIER_FL (FS_BARRIER_FL >> 16)
14351 +#define REISERFS_IUNLINK_FL (FS_IUNLINK_FL >> 16)
14353 /* persistent flags that file inherits from the parent directory */
14354 #define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL | \
14355 REISERFS_SYNC_FL | \
14356 @@ -830,6 +834,9 @@ struct stat_data_v1 {
14357 REISERFS_COMPR_FL | \
14358 REISERFS_NOTAIL_FL )
14360 +#define REISERFS_FL_USER_VISIBLE 0x80FF
14361 +#define REISERFS_FL_USER_MODIFIABLE 0x80FF
14363 /* Stat Data on disk (reiserfs version of UFS disk inode minus the
14366 @@ -1901,6 +1908,7 @@ static inline void reiserfs_update_sd(st
14367 void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode);
14368 void i_attrs_to_sd_attrs(struct inode *inode, __u16 * sd_attrs);
14369 int reiserfs_setattr(struct dentry *dentry, struct iattr *attr);
14370 +int reiserfs_sync_flags(struct inode *inode);
14373 void set_de_name_and_namelen(struct reiserfs_dir_entry *de);
14374 diff -NurpP --minimal linux-2.6.19.1/include/linux/reiserfs_fs_sb.h linux-2.6.19.1-vs2.3.0.6/include/linux/reiserfs_fs_sb.h
14375 --- linux-2.6.19.1/include/linux/reiserfs_fs_sb.h 2006-11-30 21:19:39 +0100
14376 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/reiserfs_fs_sb.h 2006-11-08 04:57:46 +0100
14377 @@ -456,6 +456,7 @@ enum reiserfs_mount_options {
14379 REISERFS_BARRIER_NONE,
14380 REISERFS_BARRIER_FLUSH,
14383 /* Actions on error */
14384 REISERFS_ERROR_PANIC,
14385 diff -NurpP --minimal linux-2.6.19.1/include/linux/sched.h linux-2.6.19.1-vs2.3.0.6/include/linux/sched.h
14386 --- linux-2.6.19.1/include/linux/sched.h 2006-11-30 21:19:39 +0100
14387 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/sched.h 2006-12-13 09:15:23 +0100
14389 #define CLONE_STOPPED 0x02000000 /* Start in stopped state */
14390 #define CLONE_NEWUTS 0x04000000 /* New utsname group? */
14391 #define CLONE_NEWIPC 0x08000000 /* New ipcs */
14392 +#define CLONE_KTHREAD 0x10000000 /* clone a kernel thread */
14395 * Scheduling policies
14396 @@ -54,6 +55,7 @@ struct sched_param {
14397 #include <linux/cpumask.h>
14398 #include <linux/errno.h>
14399 #include <linux/nodemask.h>
14400 +// #include <linux/vs_base.h>
14402 #include <asm/system.h>
14403 #include <asm/semaphore.h>
14404 @@ -92,7 +94,7 @@ struct futex_pi_state;
14405 * List of flags we want to share for kernel threads,
14406 * if only because they are not used by them anyway.
14408 -#define CLONE_KERNEL (CLONE_FS | CLONE_FILES | CLONE_SIGHAND)
14409 +#define CLONE_KERNEL (CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_KTHREAD)
14412 * These are the constant used to fake the fixed-point load-average
14413 @@ -144,12 +146,13 @@ extern unsigned long weighted_cpuload(co
14414 #define TASK_UNINTERRUPTIBLE 2
14415 #define TASK_STOPPED 4
14416 #define TASK_TRACED 8
14417 +#define TASK_ONHOLD 16
14418 /* in tsk->exit_state */
14419 -#define EXIT_ZOMBIE 16
14420 -#define EXIT_DEAD 32
14421 +#define EXIT_ZOMBIE 32
14422 +#define EXIT_DEAD 64
14423 /* in tsk->state again */
14424 -#define TASK_NONINTERACTIVE 64
14425 -#define TASK_DEAD 128
14426 +#define TASK_NONINTERACTIVE 128
14427 +#define TASK_DEAD 256
14429 #define __set_task_state(tsk, state_value) \
14430 do { (tsk)->state = (state_value); } while (0)
14431 @@ -264,27 +267,30 @@ extern void arch_unmap_area_topdown(stru
14432 * The mm counters are not protected by its page_table_lock,
14433 * so must be incremented atomically.
14435 -#define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value)
14436 -#define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member))
14437 -#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member)
14438 -#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)
14439 -#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)
14440 typedef atomic_long_t mm_counter_t;
14441 +#define __set_mm_counter(mm, member, value) \
14442 + atomic_long_set(&(mm)->_##member, value)
14443 +#define get_mm_counter(mm, member) \
14444 + ((unsigned long)atomic_long_read(&(mm)->_##member))
14446 #else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
14448 * The mm counters are protected by its page_table_lock,
14449 * so can be incremented directly.
14451 -#define set_mm_counter(mm, member, value) (mm)->_##member = (value)
14452 -#define get_mm_counter(mm, member) ((mm)->_##member)
14453 -#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
14454 -#define inc_mm_counter(mm, member) (mm)->_##member++
14455 -#define dec_mm_counter(mm, member) (mm)->_##member--
14456 typedef unsigned long mm_counter_t;
14457 +#define __set_mm_counter(mm, member, value) (mm)->_##member = (value)
14458 +#define get_mm_counter(mm, member) ((mm)->_##member)
14460 #endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
14462 +#define set_mm_counter(mm, member, value) \
14463 + vx_ ## member ## pages_sub((mm), (get_mm_counter(mm, member) - value))
14464 +#define add_mm_counter(mm, member, value) \
14465 + vx_ ## member ## pages_add((mm), (value))
14466 +#define inc_mm_counter(mm, member) vx_ ## member ## pages_inc((mm))
14467 +#define dec_mm_counter(mm, member) vx_ ## member ## pages_dec((mm))
14469 #define get_mm_rss(mm) \
14470 (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
14471 #define update_hiwater_rss(mm) do { \
14472 @@ -343,6 +349,7 @@ struct mm_struct {
14474 /* Architecture-specific MM context */
14475 mm_context_t context;
14476 + struct vx_info *mm_vx_info;
14478 /* Token based thrashing protection. */
14479 unsigned long swap_token_time;
14480 @@ -532,9 +539,10 @@ struct user_struct {
14481 /* Hash table maintenance information */
14482 struct list_head uidhash_list;
14487 -extern struct user_struct *find_user(uid_t);
14488 +extern struct user_struct *find_user(xid_t, uid_t);
14490 extern struct user_struct root_user;
14491 #define INIT_USER (&root_user)
14492 @@ -925,6 +933,14 @@ struct task_struct {
14495 struct audit_context *audit_context;
14497 +/* vserver context data */
14498 + struct vx_info *vx_info;
14499 + struct nx_info *nx_info;
14506 /* Thread group tracking */
14507 @@ -1221,13 +1237,18 @@ extern struct task_struct init_task;
14509 extern struct mm_struct init_mm;
14511 -#define find_task_by_pid(nr) find_task_by_pid_type(PIDTYPE_PID, nr)
14513 +#define find_task_by_real_pid(nr) \
14514 + find_task_by_pid_type(PIDTYPE_REALPID, nr)
14515 +#define find_task_by_pid(nr) \
14516 + find_task_by_pid_type(PIDTYPE_PID, nr)
14518 extern struct task_struct *find_task_by_pid_type(int type, int pid);
14519 extern void set_special_pids(pid_t session, pid_t pgrp);
14520 extern void __set_special_pids(pid_t session, pid_t pgrp);
14522 /* per-UID process charging. */
14523 -extern struct user_struct * alloc_uid(uid_t);
14524 +extern struct user_struct * alloc_uid(xid_t, uid_t);
14525 static inline struct user_struct *get_uid(struct user_struct *u)
14527 atomic_inc(&u->__count);
14528 diff -NurpP --minimal linux-2.6.19.1/include/linux/security.h linux-2.6.19.1-vs2.3.0.6/include/linux/security.h
14529 --- linux-2.6.19.1/include/linux/security.h 2006-11-30 21:19:39 +0100
14530 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/security.h 2006-11-08 04:57:51 +0100
14531 @@ -1172,7 +1172,7 @@ struct security_operations {
14532 int (*capable) (struct task_struct * tsk, int cap);
14533 int (*acct) (struct file * file);
14534 int (*sysctl) (struct ctl_table * table, int op);
14535 - int (*quotactl) (int cmds, int type, int id, struct super_block * sb);
14536 + int (*quotactl) (int cmds, int type, int id, struct dqhash *);
14537 int (*quota_on) (struct dentry * dentry);
14538 int (*syslog) (int type);
14539 int (*settime) (struct timespec *ts, struct timezone *tz);
14540 @@ -1456,9 +1456,9 @@ static inline int security_sysctl(struct
14543 static inline int security_quotactl (int cmds, int type, int id,
14544 - struct super_block *sb)
14545 + struct dqhash *hash)
14547 - return security_ops->quotactl (cmds, type, id, sb);
14548 + return security_ops->quotactl (cmds, type, id, hash);
14551 static inline int security_quota_on (struct dentry * dentry)
14552 @@ -2201,7 +2201,7 @@ static inline int security_sysctl(struct
14555 static inline int security_quotactl (int cmds, int type, int id,
14556 - struct super_block * sb)
14557 + struct dqhash * hash)
14561 diff -NurpP --minimal linux-2.6.19.1/include/linux/shmem_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/shmem_fs.h
14562 --- linux-2.6.19.1/include/linux/shmem_fs.h 2006-11-30 21:19:39 +0100
14563 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/shmem_fs.h 2006-11-08 04:57:53 +0100
14566 #define SHMEM_NR_DIRECT 16
14568 +#define TMPFS_SUPER_MAGIC 0x01021994
14571 struct shmem_inode_info {
14573 unsigned long flags;
14574 diff -NurpP --minimal linux-2.6.19.1/include/linux/stat.h linux-2.6.19.1-vs2.3.0.6/include/linux/stat.h
14575 --- linux-2.6.19.1/include/linux/stat.h 2006-11-30 21:19:40 +0100
14576 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/stat.h 2006-11-08 04:57:46 +0100
14577 @@ -63,6 +63,7 @@ struct kstat {
14578 unsigned int nlink;
14584 struct timespec atime;
14585 diff -NurpP --minimal linux-2.6.19.1/include/linux/sunrpc/auth.h linux-2.6.19.1-vs2.3.0.6/include/linux/sunrpc/auth.h
14586 --- linux-2.6.19.1/include/linux/sunrpc/auth.h 2006-11-30 21:19:40 +0100
14587 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/sunrpc/auth.h 2006-11-08 04:57:47 +0100
14593 struct group_info *group_info;
14596 diff -NurpP --minimal linux-2.6.19.1/include/linux/sunrpc/clnt.h linux-2.6.19.1-vs2.3.0.6/include/linux/sunrpc/clnt.h
14597 --- linux-2.6.19.1/include/linux/sunrpc/clnt.h 2006-11-30 21:19:40 +0100
14598 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/sunrpc/clnt.h 2006-11-08 04:57:47 +0100
14599 @@ -42,7 +42,8 @@ struct rpc_clnt {
14600 cl_intr : 1,/* interruptible */
14601 cl_autobind : 1,/* use getport() */
14602 cl_oneshot : 1,/* dispose after use */
14603 - cl_dead : 1;/* abandoned */
14604 + cl_dead : 1,/* abandoned */
14605 + cl_tag : 1;/* context tagging */
14607 struct rpc_rtt * cl_rtt; /* RTO estimator data */
14609 diff -NurpP --minimal linux-2.6.19.1/include/linux/syscalls.h linux-2.6.19.1-vs2.3.0.6/include/linux/syscalls.h
14610 --- linux-2.6.19.1/include/linux/syscalls.h 2006-11-30 21:19:40 +0100
14611 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/syscalls.h 2006-11-08 04:57:51 +0100
14612 @@ -294,6 +294,8 @@ asmlinkage long sys_symlink(const char _
14613 asmlinkage long sys_unlink(const char __user *pathname);
14614 asmlinkage long sys_rename(const char __user *oldname,
14615 const char __user *newname);
14616 +asmlinkage long sys_copyfile(const char __user *from, const char __user *to,
14618 asmlinkage long sys_chmod(const char __user *filename, mode_t mode);
14619 asmlinkage long sys_fchmod(unsigned int fd, mode_t mode);
14621 diff -NurpP --minimal linux-2.6.19.1/include/linux/sysctl.h linux-2.6.19.1-vs2.3.0.6/include/linux/sysctl.h
14622 --- linux-2.6.19.1/include/linux/sysctl.h 2006-11-30 21:19:40 +0100
14623 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/sysctl.h 2006-11-08 21:52:09 +0100
14624 @@ -101,6 +101,7 @@ enum
14625 KERN_CAP_BSET=14, /* int: capability bounding set */
14626 KERN_PANIC=15, /* int: panic timeout */
14627 KERN_REALROOTDEV=16, /* real root device to mount after initrd */
14628 + KERN_VSHELPER=17, /* string: path to vshelper policy agent */
14630 KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
14631 KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */
14632 @@ -932,6 +933,9 @@ typedef int ctl_handler (ctl_table *tabl
14633 typedef int proc_handler (ctl_table *ctl, int write, struct file * filp,
14634 void __user *buffer, size_t *lenp, loff_t *ppos);
14636 +typedef int virt_handler (struct ctl_table *ctl, int write, xid_t xid,
14637 + void **datap, size_t *lenp);
14639 extern int proc_dostring(ctl_table *, int, struct file *,
14640 void __user *, size_t *, loff_t *);
14641 extern int proc_dointvec(ctl_table *, int, struct file *,
14642 @@ -1016,6 +1020,7 @@ struct ctl_table
14645 proc_handler *proc_handler; /* Callback for text formatting */
14646 + virt_handler *virt_handler; /* Context virtualization */
14647 ctl_handler *strategy; /* Callback function for all r/w */
14648 struct proc_dir_entry *de; /* /proc control block */
14650 diff -NurpP --minimal linux-2.6.19.1/include/linux/sysfs.h linux-2.6.19.1-vs2.3.0.6/include/linux/sysfs.h
14651 --- linux-2.6.19.1/include/linux/sysfs.h 2006-11-30 21:19:40 +0100
14652 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/sysfs.h 2006-11-08 04:57:53 +0100
14654 #include <linux/compiler.h>
14655 #include <asm/atomic.h>
14657 +#define SYSFS_SUPER_MAGIC 0x62656572
14662 diff -NurpP --minimal linux-2.6.19.1/include/linux/time.h linux-2.6.19.1-vs2.3.0.6/include/linux/time.h
14663 --- linux-2.6.19.1/include/linux/time.h 2006-09-20 16:58:44 +0200
14664 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/time.h 2006-11-08 04:57:40 +0100
14665 @@ -174,6 +174,9 @@ static inline void timespec_add_ns(struc
14670 +#include <linux/vs_time.h>
14672 #endif /* __KERNEL__ */
14674 #define NFDBITS __NFDBITS
14675 diff -NurpP --minimal linux-2.6.19.1/include/linux/types.h linux-2.6.19.1-vs2.3.0.6/include/linux/types.h
14676 --- linux-2.6.19.1/include/linux/types.h 2006-11-30 21:19:40 +0100
14677 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/types.h 2006-11-08 04:57:40 +0100
14678 @@ -39,6 +39,9 @@ typedef __kernel_uid32_t uid_t;
14679 typedef __kernel_gid32_t gid_t;
14680 typedef __kernel_uid16_t uid16_t;
14681 typedef __kernel_gid16_t gid16_t;
14682 +typedef unsigned int xid_t;
14683 +typedef unsigned int nid_t;
14684 +typedef unsigned int tag_t;
14686 #ifdef CONFIG_UID16
14687 /* This is defined by include/asm-{arch}/posix_types.h */
14688 diff -NurpP --minimal linux-2.6.19.1/include/linux/vroot.h linux-2.6.19.1-vs2.3.0.6/include/linux/vroot.h
14689 --- linux-2.6.19.1/include/linux/vroot.h 1970-01-01 01:00:00 +0100
14690 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vroot.h 2006-11-08 04:57:51 +0100
14694 + * include/linux/vroot.h
14696 + * written by Herbert Pötzl, 9/11/2002
14697 + * ported to 2.6 by Herbert Pötzl, 30/12/2004
14699 + * Copyright (C) 2002-2005 by Herbert Pötzl.
14700 + * Redistribution of this file is permitted under the
14701 + * GNU General Public License.
14704 +#ifndef _LINUX_VROOT_H
14705 +#define _LINUX_VROOT_H
14710 +/* Possible states of device */
14716 +struct vroot_device {
14720 + struct semaphore vr_ctl_mutex;
14721 + struct block_device *vr_device;
14726 +typedef struct block_device *(vroot_grb_func)(struct block_device *);
14728 +extern int register_vroot_grb(vroot_grb_func *);
14729 +extern int unregister_vroot_grb(vroot_grb_func *);
14731 +#endif /* __KERNEL__ */
14733 +#define MAX_VROOT_DEFAULT 8
14736 + * IOCTL commands --- we will commandeer 0x56 ('V')
14739 +#define VROOT_SET_DEV 0x5600
14740 +#define VROOT_CLR_DEV 0x5601
14742 +#endif /* _LINUX_VROOT_H */
14743 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_base.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_base.h
14744 --- linux-2.6.19.1/include/linux/vs_base.h 1970-01-01 01:00:00 +0100
14745 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_base.h 2006-11-30 19:39:09 +0100
14747 +#ifndef _VS_BASE_H
14748 +#define _VS_BASE_H
14750 +#include "vserver/base.h"
14751 +#include "vserver/debug.h"
14754 +#warning duplicate inclusion
14756 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_context.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_context.h
14757 --- linux-2.6.19.1/include/linux/vs_context.h 1970-01-01 01:00:00 +0100
14758 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_context.h 2006-11-30 18:53:18 +0100
14760 +#ifndef _VS_CONTEXT_H
14761 +#define _VS_CONTEXT_H
14763 +#include "vserver/base.h"
14764 +#include "vserver/context.h"
14765 +#include "vserver/history.h"
14766 +#include "vserver/debug.h"
14769 +#define get_vx_info(i) __get_vx_info(i,__FILE__,__LINE__,__HERE__)
14771 +static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
14772 + const char *_file, int _line, void *_here)
14777 + vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])",
14778 + vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_usecnt):0,
14780 + __vxh_get_vx_info(vxi, _here);
14782 + atomic_inc(&vxi->vx_usecnt);
14787 +extern void free_vx_info(struct vx_info *);
14789 +#define put_vx_info(i) __put_vx_info(i,__FILE__,__LINE__,__HERE__)
14791 +static inline void __put_vx_info(struct vx_info *vxi,
14792 + const char *_file, int _line, void *_here)
14797 + vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])",
14798 + vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_usecnt):0,
14800 + __vxh_put_vx_info(vxi, _here);
14802 + if (atomic_dec_and_test(&vxi->vx_usecnt))
14803 + free_vx_info(vxi);
14807 +#define init_vx_info(p,i) __init_vx_info(p,i,__FILE__,__LINE__,__HERE__)
14809 +static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi,
14810 + const char *_file, int _line, void *_here)
14813 + vxlprintk(VXD_CBIT(xid, 3),
14814 + "init_vx_info(%p[#%d.%d])",
14815 + vxi, vxi?vxi->vx_id:0,
14816 + vxi?atomic_read(&vxi->vx_usecnt):0,
14818 + __vxh_init_vx_info(vxi, vxp, _here);
14820 + atomic_inc(&vxi->vx_usecnt);
14826 +#define set_vx_info(p,i) __set_vx_info(p,i,__FILE__,__LINE__,__HERE__)
14828 +static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
14829 + const char *_file, int _line, void *_here)
14831 + struct vx_info *vxo;
14836 + vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])",
14837 + vxi, vxi?vxi->vx_id:0,
14838 + vxi?atomic_read(&vxi->vx_usecnt):0,
14840 + __vxh_set_vx_info(vxi, vxp, _here);
14842 + atomic_inc(&vxi->vx_usecnt);
14843 + vxo = xchg(vxp, vxi);
14848 +#define clr_vx_info(p) __clr_vx_info(p,__FILE__,__LINE__,__HERE__)
14850 +static inline void __clr_vx_info(struct vx_info **vxp,
14851 + const char *_file, int _line, void *_here)
14853 + struct vx_info *vxo;
14855 + vxo = xchg(vxp, NULL);
14859 + vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])",
14860 + vxo, vxo?vxo->vx_id:0,
14861 + vxo?atomic_read(&vxo->vx_usecnt):0,
14863 + __vxh_clr_vx_info(vxo, vxp, _here);
14865 + if (atomic_dec_and_test(&vxo->vx_usecnt))
14866 + free_vx_info(vxo);
14870 +#define claim_vx_info(v,p) \
14871 + __claim_vx_info(v,p,__FILE__,__LINE__,__HERE__)
14873 +static inline void __claim_vx_info(struct vx_info *vxi,
14874 + struct task_struct *task,
14875 + const char *_file, int _line, void *_here)
14877 + vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p",
14878 + vxi, vxi?vxi->vx_id:0,
14879 + vxi?atomic_read(&vxi->vx_usecnt):0,
14880 + vxi?atomic_read(&vxi->vx_tasks):0,
14881 + task, _file, _line);
14882 + __vxh_claim_vx_info(vxi, task, _here);
14884 + atomic_inc(&vxi->vx_tasks);
14888 +extern void unhash_vx_info(struct vx_info *);
14890 +#define release_vx_info(v,p) \
14891 + __release_vx_info(v,p,__FILE__,__LINE__,__HERE__)
14893 +static inline void __release_vx_info(struct vx_info *vxi,
14894 + struct task_struct *task,
14895 + const char *_file, int _line, void *_here)
14897 + vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p",
14898 + vxi, vxi?vxi->vx_id:0,
14899 + vxi?atomic_read(&vxi->vx_usecnt):0,
14900 + vxi?atomic_read(&vxi->vx_tasks):0,
14901 + task, _file, _line);
14902 + __vxh_release_vx_info(vxi, task, _here);
14906 + if (atomic_dec_and_test(&vxi->vx_tasks))
14907 + unhash_vx_info(vxi);
14911 +#define task_get_vx_info(p) \
14912 + __task_get_vx_info(p,__FILE__,__LINE__,__HERE__)
14914 +static inline struct vx_info *__task_get_vx_info(struct task_struct *p,
14915 + const char *_file, int _line, void *_here)
14917 + struct vx_info *vxi;
14920 + vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)",
14921 + p, _file, _line);
14922 + vxi = __get_vx_info(p->vx_info, _file, _line, _here);
14928 +static inline void __wakeup_vx_info(struct vx_info *vxi)
14930 + if (waitqueue_active(&vxi->vx_wait))
14931 + wake_up_interruptible(&vxi->vx_wait);
14935 +#define enter_vx_info(v,s) __enter_vx_info(v,s,__FILE__,__LINE__)
14937 +static inline void __enter_vx_info(struct vx_info *vxi,
14938 + struct vx_info_save *vxis, const char *_file, int _line)
14940 + vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]",
14941 + vxi, vxi ? vxi->vx_id : 0, vxis, current,
14942 + current->xid, current->vx_info, _file, _line);
14943 + vxis->vxi = xchg(¤t->vx_info, vxi);
14944 + vxis->xid = current->xid;
14945 + current->xid = vxi ? vxi->vx_id : 0;
14948 +#define leave_vx_info(s) __leave_vx_info(s,__FILE__,__LINE__)
14950 +static inline void __leave_vx_info(struct vx_info_save *vxis,
14951 + const char *_file, int _line)
14953 + vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]",
14954 + vxis, vxis->xid, vxis->vxi, current,
14955 + current->xid, current->vx_info, _file, _line);
14956 + (void)xchg(¤t->vx_info, vxis->vxi);
14957 + current->xid = vxis->xid;
14961 +static inline void __enter_vx_admin(struct vx_info_save *vxis)
14963 + vxis->vxi = xchg(¤t->vx_info, NULL);
14964 + vxis->xid = xchg(¤t->xid, (xid_t)0);
14967 +static inline void __leave_vx_admin(struct vx_info_save *vxis)
14969 + (void)xchg(¤t->xid, vxis->xid);
14970 + (void)xchg(¤t->vx_info, vxis->vxi);
14973 +extern void exit_vx_info(struct task_struct *, int);
14974 +extern void exit_vx_info_early(struct task_struct *, int);
14978 +struct task_struct *vx_child_reaper(struct task_struct *p)
14980 + struct vx_info *vxi = p->vx_info;
14981 + struct task_struct *reaper = child_reaper;
14986 + BUG_ON(!p->vx_info->vx_reaper);
14988 + /* child reaper for the guest reaper */
14989 + if (vxi->vx_reaper == p)
14992 + reaper = vxi->vx_reaper;
14994 + vxdprintk(VXD_CBIT(xid, 3),
14995 + "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]\n",
14996 + p, p->xid, p->pid, reaper, reaper->xid, reaper->pid);
15002 +#warning duplicate inclusion
15004 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_cowbl.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_cowbl.h
15005 --- linux-2.6.19.1/include/linux/vs_cowbl.h 1970-01-01 01:00:00 +0100
15006 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_cowbl.h 2006-11-30 18:53:18 +0100
15008 +#ifndef _VS_COWBL_H
15009 +#define _VS_COWBL_H
15011 +#include <linux/fs.h>
15012 +#include <linux/dcache.h>
15013 +#include <linux/namei.h>
15015 +extern struct dentry *cow_break_link(const char *pathname);
15017 +static inline int cow_check_and_break(struct nameidata *nd)
15019 + struct inode *inode = nd->dentry->d_inode;
15021 + if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
15023 + if (IS_COW(inode)) {
15024 + if (IS_COW_LINK(inode)) {
15025 + struct dentry *new_dentry, *old_dentry = nd->dentry;
15026 + char *path, *buf;
15028 + buf = kmalloc(PATH_MAX, GFP_KERNEL);
15032 + path = d_path(nd->dentry, nd->mnt, buf, PATH_MAX);
15033 + new_dentry = cow_break_link(path);
15035 + if (!IS_ERR(new_dentry)) {
15036 + nd->dentry = new_dentry;
15037 + dput(old_dentry);
15039 + error = PTR_ERR(new_dentry);
15041 + inode->i_flags &= ~(S_IUNLINK|S_IMMUTABLE);
15042 + inode->i_ctime = CURRENT_TIME;
15043 + mark_inode_dirty(inode);
15050 +#warning duplicate inclusion
15052 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_cvirt.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_cvirt.h
15053 --- linux-2.6.19.1/include/linux/vs_cvirt.h 1970-01-01 01:00:00 +0100
15054 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_cvirt.h 2006-11-30 19:12:40 +0100
15056 +#ifndef _VS_CVIRT_H
15057 +#define _VS_CVIRT_H
15059 +#include "vserver/cvirt.h"
15060 +#include "vserver/context.h"
15061 +#include "vserver/base.h"
15062 +#include "vserver/debug.h"
15065 +static inline void vx_activate_task(struct task_struct *p)
15067 + struct vx_info *vxi;
15069 + if ((vxi = p->vx_info)) {
15070 + vx_update_load(vxi);
15071 + atomic_inc(&vxi->cvirt.nr_running);
15075 +static inline void vx_deactivate_task(struct task_struct *p)
15077 + struct vx_info *vxi;
15079 + if ((vxi = p->vx_info)) {
15080 + vx_update_load(vxi);
15081 + atomic_dec(&vxi->cvirt.nr_running);
15085 +static inline void vx_uninterruptible_inc(struct task_struct *p)
15087 + struct vx_info *vxi;
15089 + if ((vxi = p->vx_info))
15090 + atomic_inc(&vxi->cvirt.nr_uninterruptible);
15093 +static inline void vx_uninterruptible_dec(struct task_struct *p)
15095 + struct vx_info *vxi;
15097 + if ((vxi = p->vx_info))
15098 + atomic_dec(&vxi->cvirt.nr_uninterruptible);
15103 +#warning duplicate inclusion
15105 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_dlimit.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_dlimit.h
15106 --- linux-2.6.19.1/include/linux/vs_dlimit.h 1970-01-01 01:00:00 +0100
15107 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_dlimit.h 2006-12-01 23:37:57 +0100
15109 +#ifndef _VS_DLIMIT_H
15110 +#define _VS_DLIMIT_H
15112 +#include "vserver/dlimit.h"
15113 +#include "vserver/base.h"
15114 +#include "vserver/debug.h"
15117 +#define get_dl_info(i) __get_dl_info(i,__FILE__,__LINE__)
15119 +static inline struct dl_info *__get_dl_info(struct dl_info *dli,
15120 + const char *_file, int _line)
15124 + vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
15125 + dli, dli?dli->dl_tag:0, dli?atomic_read(&dli->dl_usecnt):0,
15127 + atomic_inc(&dli->dl_usecnt);
15132 +#define free_dl_info(i) \
15133 + call_rcu(&i->dl_rcu, rcu_free_dl_info);
15135 +#define put_dl_info(i) __put_dl_info(i,__FILE__,__LINE__)
15137 +static inline void __put_dl_info(struct dl_info *dli,
15138 + const char *_file, int _line)
15142 + vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
15143 + dli, dli?dli->dl_tag:0, dli?atomic_read(&dli->dl_usecnt):0,
15145 + if (atomic_dec_and_test(&dli->dl_usecnt))
15146 + free_dl_info(dli);
15150 +#define __dlimit_char(d) ((d)?'*':' ')
15152 +static inline int __dl_alloc_space(struct super_block *sb,
15153 + tag_t tag, dlsize_t nr, const char *file, int line)
15155 + struct dl_info *dli = NULL;
15160 + dli = locate_dl_info(sb, tag);
15164 + spin_lock(&dli->dl_lock);
15165 + ret = (dli->dl_space_used + nr > dli->dl_space_total);
15167 + dli->dl_space_used += nr;
15168 + spin_unlock(&dli->dl_lock);
15169 + put_dl_info(dli);
15171 + vxlprintk(VXD_CBIT(dlim, 1),
15172 + "ALLOC (%p,#%d)%c %lld bytes (%d)",
15173 + sb, tag, __dlimit_char(dli), (long long)nr,
15174 + ret, file, line);
15178 +static inline void __dl_free_space(struct super_block *sb,
15179 + tag_t tag, dlsize_t nr, const char *_file, int _line)
15181 + struct dl_info *dli = NULL;
15185 + dli = locate_dl_info(sb, tag);
15189 + spin_lock(&dli->dl_lock);
15190 + if (dli->dl_space_used > nr)
15191 + dli->dl_space_used -= nr;
15193 + dli->dl_space_used = 0;
15194 + spin_unlock(&dli->dl_lock);
15195 + put_dl_info(dli);
15197 + vxlprintk(VXD_CBIT(dlim, 1),
15198 + "FREE (%p,#%d)%c %lld bytes",
15199 + sb, tag, __dlimit_char(dli), (long long)nr,
15203 +static inline int __dl_alloc_inode(struct super_block *sb,
15204 + tag_t tag, const char *_file, int _line)
15206 + struct dl_info *dli;
15209 + dli = locate_dl_info(sb, tag);
15213 + spin_lock(&dli->dl_lock);
15214 + ret = (dli->dl_inodes_used >= dli->dl_inodes_total);
15216 + dli->dl_inodes_used++;
15219 + vxwprintk("DLIMIT hit (%p,#%d), inode %d>=%d @ %s:%d",
15221 + dli->dl_inodes_used, dli->dl_inodes_total,
15224 + spin_unlock(&dli->dl_lock);
15225 + put_dl_info(dli);
15227 + vxlprintk(VXD_CBIT(dlim, 0),
15228 + "ALLOC (%p,#%d)%c inode (%d)",
15229 + sb, tag, __dlimit_char(dli), ret, _file, _line);
15233 +static inline void __dl_free_inode(struct super_block *sb,
15234 + tag_t tag, const char *_file, int _line)
15236 + struct dl_info *dli;
15238 + dli = locate_dl_info(sb, tag);
15242 + spin_lock(&dli->dl_lock);
15243 + if (dli->dl_inodes_used > 1)
15244 + dli->dl_inodes_used--;
15246 + dli->dl_inodes_used = 0;
15247 + spin_unlock(&dli->dl_lock);
15248 + put_dl_info(dli);
15250 + vxlprintk(VXD_CBIT(dlim, 0),
15251 + "FREE (%p,#%d)%c inode",
15252 + sb, tag, __dlimit_char(dli), _file, _line);
15255 +static inline void __dl_adjust_block(struct super_block *sb, tag_t tag,
15256 + unsigned long long *free_blocks, unsigned long long *root_blocks,
15257 + const char *_file, int _line)
15259 + struct dl_info *dli;
15260 + uint64_t broot, bfree;
15262 + dli = locate_dl_info(sb, tag);
15266 + spin_lock(&dli->dl_lock);
15267 + broot = (dli->dl_space_total -
15268 + (dli->dl_space_total >> 10) * dli->dl_nrlmult)
15269 + >> sb->s_blocksize_bits;
15270 + bfree = (dli->dl_space_total - dli->dl_space_used)
15271 + >> sb->s_blocksize_bits;
15272 + spin_unlock(&dli->dl_lock);
15274 + vxlprintk(VXD_CBIT(dlim, 2),
15275 + "ADJUST: %lld,%lld on %lld,%lld [mult=%d]",
15276 + (long long)bfree, (long long)broot,
15277 + *free_blocks, *root_blocks, dli->dl_nrlmult,
15279 + if (free_blocks) {
15280 + if (*free_blocks > bfree)
15281 + *free_blocks = bfree;
15283 + if (root_blocks) {
15284 + if (*root_blocks > broot)
15285 + *root_blocks = broot;
15287 + put_dl_info(dli);
15290 +#define DLIMIT_ALLOC_SPACE(in, bytes) \
15291 + __dl_alloc_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
15292 + __FILE__, __LINE__ )
15294 +#define DLIMIT_FREE_SPACE(in, bytes) \
15295 + __dl_free_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
15296 + __FILE__, __LINE__ )
15298 +#define DLIMIT_ALLOC_BLOCK(in, nr) \
15299 + __dl_alloc_space((in)->i_sb, (in)->i_tag, \
15300 + ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
15301 + __FILE__, __LINE__ )
15303 +#define DLIMIT_FREE_BLOCK(in, nr) \
15304 + __dl_free_space((in)->i_sb, (in)->i_tag, \
15305 + ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
15306 + __FILE__, __LINE__ )
15309 +#define DLIMIT_ALLOC_INODE(in) \
15310 + __dl_alloc_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
15312 +#define DLIMIT_FREE_INODE(in) \
15313 + __dl_free_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
15316 +#define DLIMIT_ADJUST_BLOCK(sb, tag, fb, rb) \
15317 + __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
15321 +#warning duplicate inclusion
15323 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_inet.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_inet.h
15324 --- linux-2.6.19.1/include/linux/vs_inet.h 1970-01-01 01:00:00 +0100
15325 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_inet.h 2006-12-17 03:46:17 +0100
15327 +#ifndef _VS_INET_H
15328 +#define _VS_INET_H
15330 +#include <linux/vs_network.h>
15332 +#define IPI_LOOPBACK htonl(INADDR_LOOPBACK)
15335 +static inline int addr_in_nx_info(struct nx_info *nxi, uint32_t addr)
15343 + if (n && (nxi->ipv4[0] == 0))
15345 + for (i=0; i<n; i++) {
15346 + if (nxi->ipv4[i] == addr)
15354 + * Check if a given address matches for a socket
15356 + * nxi: the socket's nx_info if any
15357 + * addr: to be verified address
15358 + * saddr/baddr: socket addresses
15360 +static inline int raw_addr_match (
15361 + struct nx_info *nxi,
15366 + if (addr && (saddr == addr || baddr == addr))
15369 + return addr_in_nx_info(nxi, addr);
15374 +/* inet related checks and helpers */
15378 +struct net_device;
15381 +#ifdef CONFIG_INET
15383 +#include <linux/netdevice.h>
15384 +#include <linux/inetdevice.h>
15385 +#include <net/inet_timewait_sock.h>
15388 +int dev_in_nx_info(struct net_device *, struct nx_info *);
15389 +int nx_addr_conflict(struct nx_info *, uint32_t, struct sock *);
15393 + * check if address is covered by socket
15395 + * sk: the socket to check against
15396 + * addr: the address in question (must be != 0)
15400 +int __addr_in_socket(struct sock *sk, uint32_t addr)
15402 + struct nx_info *nxi = sk->sk_nx_info;
15403 + uint32_t saddr = inet_rcv_saddr(sk);
15405 + vxdprintk(VXD_CBIT(net, 5),
15406 + "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx",
15407 + sk, VXD_QUAD(addr), nxi, VXD_QUAD(saddr), sk->sk_socket,
15408 + (sk->sk_socket?sk->sk_socket->flags:0));
15411 + /* direct address match */
15412 + return (saddr == addr);
15413 + } else if (nxi) {
15414 + /* match against nx_info */
15415 + return addr_in_nx_info(nxi, addr);
15417 + /* unrestricted any socket */
15425 +int nx_dev_visible(struct nx_info *nxi, struct net_device *dev)
15427 + if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
15429 + if (dev_in_nx_info(dev, nxi))
15436 +int ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
15442 + return addr_in_nx_info(nxi, ifa->ifa_local);
15446 +int nx_ifa_visible(struct nx_info *nxi, struct in_ifaddr *ifa)
15448 + if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
15450 + if (ifa_in_nx_info(ifa, nxi))
15455 +#else /* CONFIG_INET */
15458 +int nx_dev_visible(struct nx_info *n, struct net_device *d)
15465 +int nx_addr_conflict(struct nx_info *n, uint32_t a, struct sock *s)
15471 +int ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
15476 +#endif /* CONFIG_INET */
15480 +#warning duplicate inclusion
15482 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_limit.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_limit.h
15483 --- linux-2.6.19.1/include/linux/vs_limit.h 1970-01-01 01:00:00 +0100
15484 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_limit.h 2006-11-30 18:53:18 +0100
15486 +#ifndef _VS_LIMIT_H
15487 +#define _VS_LIMIT_H
15489 +#include "vserver/limit.h"
15490 +#include "vserver/base.h"
15491 +#include "vserver/context.h"
15492 +#include "vserver/debug.h"
15493 +#include "vserver/context.h"
15494 +#include "vserver/limit_int.h"
15497 +#define vx_acc_cres(v,d,p,r) \
15498 + __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
15500 +#define vx_acc_cres_cond(x,d,p,r) \
15501 + __vx_acc_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \
15502 + r, d, p, __FILE__, __LINE__)
15505 +#define vx_add_cres(v,a,p,r) \
15506 + __vx_add_cres(v, r, a, p, __FILE__, __LINE__)
15507 +#define vx_sub_cres(v,a,p,r) vx_add_cres(v,-(a),p,r)
15509 +#define vx_add_cres_cond(x,a,p,r) \
15510 + __vx_add_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \
15511 + r, a, p, __FILE__, __LINE__)
15512 +#define vx_sub_cres_cond(x,a,p,r) vx_add_cres_cond(x,-(a),p,r)
15515 +/* process and file limits */
15517 +#define vx_nproc_inc(p) \
15518 + vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
15520 +#define vx_nproc_dec(p) \
15521 + vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
15523 +#define vx_files_inc(f) \
15524 + vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
15526 +#define vx_files_dec(f) \
15527 + vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
15529 +#define vx_locks_inc(l) \
15530 + vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
15532 +#define vx_locks_dec(l) \
15533 + vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
15535 +#define vx_openfd_inc(f) \
15536 + vx_acc_cres(current->vx_info, 1, (void *)(long)(f), VLIMIT_OPENFD)
15538 +#define vx_openfd_dec(f) \
15539 + vx_acc_cres(current->vx_info,-1, (void *)(long)(f), VLIMIT_OPENFD)
15542 +#define vx_cres_avail(v,n,r) \
15543 + __vx_cres_avail(v, r, n, __FILE__, __LINE__)
15546 +#define vx_nproc_avail(n) \
15547 + vx_cres_avail(current->vx_info, n, RLIMIT_NPROC)
15549 +#define vx_files_avail(n) \
15550 + vx_cres_avail(current->vx_info, n, RLIMIT_NOFILE)
15552 +#define vx_locks_avail(n) \
15553 + vx_cres_avail(current->vx_info, n, RLIMIT_LOCKS)
15555 +#define vx_openfd_avail(n) \
15556 + vx_cres_avail(current->vx_info, n, VLIMIT_OPENFD)
15559 +/* dentry limits */
15561 +#define vx_dentry_inc(d) do { \
15562 + if (atomic_read(&d->d_count) == 1) \
15563 + vx_acc_cres(current->vx_info, 1, d, VLIMIT_DENTRY); \
15566 +#define vx_dentry_dec(d) do { \
15567 + if (atomic_read(&d->d_count) == 0) \
15568 + vx_acc_cres(current->vx_info,-1, d, VLIMIT_DENTRY); \
15571 +#define vx_dentry_avail(n) \
15572 + vx_cres_avail(current->vx_info, n, VLIMIT_DENTRY)
15575 +/* socket limits */
15577 +#define vx_sock_inc(s) \
15578 + vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
15580 +#define vx_sock_dec(s) \
15581 + vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
15583 +#define vx_sock_avail(n) \
15584 + vx_cres_avail(current->vx_info, n, VLIMIT_NSOCK)
15587 +/* ipc resource limits */
15589 +#define vx_ipcmsg_add(v,u,a) \
15590 + vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
15592 +#define vx_ipcmsg_sub(v,u,a) \
15593 + vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
15595 +#define vx_ipcmsg_avail(v,a) \
15596 + vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
15599 +#define vx_ipcshm_add(v,k,a) \
15600 + vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
15602 +#define vx_ipcshm_sub(v,k,a) \
15603 + vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
15605 +#define vx_ipcshm_avail(v,a) \
15606 + vx_cres_avail(v, a, VLIMIT_SHMEM)
15609 +#define vx_semary_inc(a) \
15610 + vx_acc_cres(current->vx_info, 1, a, VLIMIT_SEMARY)
15612 +#define vx_semary_dec(a) \
15613 + vx_acc_cres(current->vx_info,-1, a, VLIMIT_SEMARY)
15616 +#define vx_nsems_add(a,n) \
15617 + vx_add_cres(current->vx_info, n, a, VLIMIT_NSEMS)
15619 +#define vx_nsems_sub(a,n) \
15620 + vx_sub_cres(current->vx_info, n, a, VLIMIT_NSEMS)
15624 +#warning duplicate inclusion
15626 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_memory.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_memory.h
15627 --- linux-2.6.19.1/include/linux/vs_memory.h 1970-01-01 01:00:00 +0100
15628 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_memory.h 2006-11-30 19:31:41 +0100
15630 +#ifndef _VS_MEMORY_H
15631 +#define _VS_MEMORY_H
15633 +#include "vserver/limit.h"
15634 +#include "vserver/base.h"
15635 +#include "vserver/context.h"
15636 +#include "vserver/debug.h"
15637 +#include "vserver/context.h"
15638 +#include "vserver/limit_int.h"
15641 +#define __acc_add_long(a,v) (*(v) += (a))
15642 +#define __acc_inc_long(v) (++*(v))
15643 +#define __acc_dec_long(v) (--*(v))
15645 +#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
15646 +#define __acc_add_atomic(a,v) atomic_long_add(a,v)
15647 +#define __acc_inc_atomic(v) atomic_long_inc(v)
15648 +#define __acc_dec_atomic(v) atomic_long_dec(v)
15649 +#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
15650 +#define __acc_add_atomic(a,v) __acc_add_long(a,v)
15651 +#define __acc_inc_atomic(v) __acc_inc_long(v)
15652 +#define __acc_dec_atomic(v) __acc_dec_long(v)
15653 +#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
15656 +#define vx_acc_page(m,d,v,r) do { \
15658 + __acc_inc_long(&(m->v)); \
15660 + __acc_dec_long(&(m->v)); \
15661 + __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__); \
15664 +#define vx_acc_page_atomic(m,d,v,r) do { \
15666 + __acc_inc_atomic(&(m->v)); \
15668 + __acc_dec_atomic(&(m->v)); \
15669 + __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__); \
15673 +#define vx_acc_pages(m,p,v,r) do { \
15674 + unsigned long __p = (p); \
15675 + __acc_add_long(__p, &(m->v)); \
15676 + __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__); \
15679 +#define vx_acc_pages_atomic(m,p,v,r) do { \
15680 + unsigned long __p = (p); \
15681 + __acc_add_atomic(__p, &(m->v)); \
15682 + __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__); \
15687 +#define vx_acc_vmpage(m,d) \
15688 + vx_acc_page(m, d, total_vm, RLIMIT_AS)
15689 +#define vx_acc_vmlpage(m,d) \
15690 + vx_acc_page(m, d, locked_vm, RLIMIT_MEMLOCK)
15691 +#define vx_acc_file_rsspage(m,d) \
15692 + vx_acc_page_atomic(m, d, _file_rss, VLIMIT_MAPPED)
15693 +#define vx_acc_anon_rsspage(m,d) \
15694 + vx_acc_page_atomic(m, d, _anon_rss, VLIMIT_ANON)
15696 +#define vx_acc_vmpages(m,p) \
15697 + vx_acc_pages(m, p, total_vm, RLIMIT_AS)
15698 +#define vx_acc_vmlpages(m,p) \
15699 + vx_acc_pages(m, p, locked_vm, RLIMIT_MEMLOCK)
15700 +#define vx_acc_file_rsspages(m,p) \
15701 + vx_acc_pages_atomic(m, p, _file_rss, VLIMIT_MAPPED)
15702 +#define vx_acc_anon_rsspages(m,p) \
15703 + vx_acc_pages_atomic(m, p, _anon_rss, VLIMIT_ANON)
15705 +#define vx_pages_add(s,r,p) __vx_add_cres(s, r, p, 0, __FILE__, __LINE__)
15706 +#define vx_pages_sub(s,r,p) vx_pages_add(s, r, -(p))
15708 +#define vx_vmpages_inc(m) vx_acc_vmpage(m, 1)
15709 +#define vx_vmpages_dec(m) vx_acc_vmpage(m,-1)
15710 +#define vx_vmpages_add(m,p) vx_acc_vmpages(m, p)
15711 +#define vx_vmpages_sub(m,p) vx_acc_vmpages(m,-(p))
15713 +#define vx_vmlocked_inc(m) vx_acc_vmlpage(m, 1)
15714 +#define vx_vmlocked_dec(m) vx_acc_vmlpage(m,-1)
15715 +#define vx_vmlocked_add(m,p) vx_acc_vmlpages(m, p)
15716 +#define vx_vmlocked_sub(m,p) vx_acc_vmlpages(m,-(p))
15718 +#define vx_file_rsspages_inc(m) vx_acc_file_rsspage(m, 1)
15719 +#define vx_file_rsspages_dec(m) vx_acc_file_rsspage(m,-1)
15720 +#define vx_file_rsspages_add(m,p) vx_acc_file_rsspages(m, p)
15721 +#define vx_file_rsspages_sub(m,p) vx_acc_file_rsspages(m,-(p))
15723 +#define vx_anon_rsspages_inc(m) vx_acc_anon_rsspage(m, 1)
15724 +#define vx_anon_rsspages_dec(m) vx_acc_anon_rsspage(m,-1)
15725 +#define vx_anon_rsspages_add(m,p) vx_acc_anon_rsspages(m, p)
15726 +#define vx_anon_rsspages_sub(m,p) vx_acc_anon_rsspages(m,-(p))
15729 +#define vx_pages_avail(m,p,r) \
15730 + __vx_cres_avail((m)->mm_vx_info, r, p, __FILE__, __LINE__)
15732 +#define vx_vmpages_avail(m,p) vx_pages_avail(m, p, RLIMIT_AS)
15733 +#define vx_vmlocked_avail(m,p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)
15734 +#define vx_anon_avail(m,p) vx_pages_avail(m, p, VLIMIT_ANON)
15735 +#define vx_mapped_avail(m,p) vx_pages_avail(m, p, VLIMIT_MAPPED)
15737 +#define vx_rss_avail(m,p) \
15738 + __vx_cres_array_avail((m)->mm_vx_info, VLA_RSS, p, __FILE__, __LINE__)
15742 + VXPT_UNKNOWN = 0,
15751 +#define vx_page_fault(mm,vma,type,ret)
15755 +void __vx_page_fault(struct mm_struct *mm,
15756 + struct vm_area_struct *vma, int type, int ret)
15758 + struct vx_info *vxi = mm->mm_vx_info;
15761 + static char *page_type[6] =
15762 + { "UNKNOWN", "ANON","NONE", "FILE", "SWAP", "WRITE" };
15763 + static char *page_what[4] =
15764 + { "FAULT_OOM", "FAULT_SIGBUS", "FAULT_MINOR", "FAULT_MAJOR" };
15770 + what = (ret & 0x3);
15772 +/* printk("[%d] page[%d][%d] %2x %s %s\n", vxi->vx_id,
15773 + type, what, ret, page_type[type], page_what[what]);
15775 + if (ret & VM_FAULT_WRITE)
15777 + atomic_inc(&vxi->cacct.page[type][what]);
15780 +#define vx_page_fault(mm,vma,type,ret) __vx_page_fault(mm,vma,type,ret)
15784 +extern unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm);
15787 +#warning duplicate inclusion
15789 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_network.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_network.h
15790 --- linux-2.6.19.1/include/linux/vs_network.h 1970-01-01 01:00:00 +0100
15791 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_network.h 2006-12-17 03:46:02 +0100
15793 +#ifndef _NX_VS_NETWORK_H
15794 +#define _NX_VS_NETWORK_H
15796 +#include "vserver/context.h"
15797 +#include "vserver/network.h"
15798 +#include "vserver/base.h"
15799 +#include "vserver/debug.h"
15802 +#define get_nx_info(i) __get_nx_info(i,__FILE__,__LINE__)
15804 +static inline struct nx_info *__get_nx_info(struct nx_info *nxi,
15805 + const char *_file, int _line)
15810 + vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
15811 + nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0,
15814 + atomic_inc(&nxi->nx_usecnt);
15819 +extern void free_nx_info(struct nx_info *);
15821 +#define put_nx_info(i) __put_nx_info(i,__FILE__,__LINE__)
15823 +static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
15828 + vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
15829 + nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0,
15832 + if (atomic_dec_and_test(&nxi->nx_usecnt))
15833 + free_nx_info(nxi);
15837 +#define init_nx_info(p,i) __init_nx_info(p,i,__FILE__,__LINE__)
15839 +static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
15840 + const char *_file, int _line)
15843 + vxlprintk(VXD_CBIT(nid, 3),
15844 + "init_nx_info(%p[#%d.%d])",
15845 + nxi, nxi?nxi->nx_id:0,
15846 + nxi?atomic_read(&nxi->nx_usecnt):0,
15849 + atomic_inc(&nxi->nx_usecnt);
15855 +#define set_nx_info(p,i) __set_nx_info(p,i,__FILE__,__LINE__)
15857 +static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
15858 + const char *_file, int _line)
15860 + struct nx_info *nxo;
15865 + vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
15866 + nxi, nxi?nxi->nx_id:0,
15867 + nxi?atomic_read(&nxi->nx_usecnt):0,
15870 + atomic_inc(&nxi->nx_usecnt);
15871 + nxo = xchg(nxp, nxi);
15875 +#define clr_nx_info(p) __clr_nx_info(p,__FILE__,__LINE__)
15877 +static inline void __clr_nx_info(struct nx_info **nxp,
15878 + const char *_file, int _line)
15880 + struct nx_info *nxo;
15882 + nxo = xchg(nxp, NULL);
15886 + vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
15887 + nxo, nxo?nxo->nx_id:0,
15888 + nxo?atomic_read(&nxo->nx_usecnt):0,
15891 + if (atomic_dec_and_test(&nxo->nx_usecnt))
15892 + free_nx_info(nxo);
15896 +#define claim_nx_info(v,p) __claim_nx_info(v,p,__FILE__,__LINE__)
15898 +static inline void __claim_nx_info(struct nx_info *nxi,
15899 + struct task_struct *task, const char *_file, int _line)
15901 + vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
15902 + nxi, nxi?nxi->nx_id:0,
15903 + nxi?atomic_read(&nxi->nx_usecnt):0,
15904 + nxi?atomic_read(&nxi->nx_tasks):0,
15905 + task, _file, _line);
15907 + atomic_inc(&nxi->nx_tasks);
15911 +extern void unhash_nx_info(struct nx_info *);
15913 +#define release_nx_info(v,p) __release_nx_info(v,p,__FILE__,__LINE__)
15915 +static inline void __release_nx_info(struct nx_info *nxi,
15916 + struct task_struct *task, const char *_file, int _line)
15918 + vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
15919 + nxi, nxi?nxi->nx_id:0,
15920 + nxi?atomic_read(&nxi->nx_usecnt):0,
15921 + nxi?atomic_read(&nxi->nx_tasks):0,
15922 + task, _file, _line);
15926 + if (atomic_dec_and_test(&nxi->nx_tasks))
15927 + unhash_nx_info(nxi);
15931 +#define task_get_nx_info(i) __task_get_nx_info(i,__FILE__,__LINE__)
15933 +static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
15934 + const char *_file, int _line)
15936 + struct nx_info *nxi;
15939 + vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
15940 + p, _file, _line);
15941 + nxi = __get_nx_info(p->nx_info, _file, _line);
15948 +static inline void exit_nx_info(struct task_struct *p)
15951 + release_nx_info(p->nx_info, p);
15956 +#warning duplicate inclusion
15958 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_pid.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_pid.h
15959 --- linux-2.6.19.1/include/linux/vs_pid.h 1970-01-01 01:00:00 +0100
15960 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_pid.h 2006-12-04 05:21:53 +0100
15965 +#include "vserver/base.h"
15966 +#include "vserver/context.h"
15967 +#include "vserver/debug.h"
15970 +/* pid faking stuff */
15973 +#define vx_info_map_pid(v,p) \
15974 + __vx_info_map_pid((v), (p), __FUNC__, __FILE__, __LINE__)
15975 +#define vx_info_map_tgid(v,p) vx_info_map_pid(v,p)
15976 +#define vx_map_pid(p) vx_info_map_pid(current->vx_info, p)
15977 +#define vx_map_tgid(p) vx_map_pid(p)
15979 +static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
15980 + const char *func, const char *file, int line)
15982 + if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
15983 + vxfprintk(VXD_CBIT(cvirt, 2),
15984 + "vx_map_tgid: %p/%llx: %d -> %d",
15985 + vxi, (long long)vxi->vx_flags, pid,
15986 + (pid && pid == vxi->vx_initpid)?1:pid,
15987 + func, file, line);
15990 + if (pid == vxi->vx_initpid)
15996 +#define vx_info_rmap_pid(v,p) \
15997 + __vx_info_rmap_pid((v), (p), __FUNC__, __FILE__, __LINE__)
15998 +#define vx_rmap_pid(p) vx_info_rmap_pid(current->vx_info, p)
15999 +#define vx_rmap_tgid(p) vx_rmap_pid(p)
16001 +static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
16002 + const char *func, const char *file, int line)
16004 + if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
16005 + vxfprintk(VXD_CBIT(cvirt, 2),
16006 + "vx_rmap_tgid: %p/%llx: %d -> %d",
16007 + vxi, (long long)vxi->vx_flags, pid,
16008 + (pid == 1)?vxi->vx_initpid:pid,
16009 + func, file, line);
16010 + if ((pid == 1) && vxi->vx_initpid)
16011 + return vxi->vx_initpid;
16012 + if (pid == vxi->vx_initpid)
16019 +#define VXF_FAKE_INIT (VXF_INFO_INIT|VXF_STATE_INIT)
16022 +int vx_proc_task_visible(struct task_struct *task)
16024 + if ((task->pid == 1) &&
16025 + !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
16026 + /* show a blend through init */
16028 + if (vx_check(vx_task_xid(task), VS_WATCH|VS_IDENT))
16036 +struct task_struct *vx_find_proc_task_by_pid(int pid)
16038 + struct task_struct *task = find_task_by_pid(pid);
16040 + if (task && !vx_proc_task_visible(task)) {
16041 + vxdprintk(VXD_CBIT(misc, 6),
16042 + "dropping task (find) %p[#%u,%u] for %p[#%u,%u]",
16043 + task, task->xid, task->pid,
16044 + current, current->xid, current->pid);
16051 +struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid)
16053 + struct task_struct *task = get_pid_task(pid, PIDTYPE_PID);
16055 + if (task && !vx_proc_task_visible(task)) {
16056 + vxdprintk(VXD_CBIT(misc, 6),
16057 + "dropping task (get) %p[#%u,%u] for %p[#%u,%u]",
16058 + task, task->xid, task->pid,
16059 + current, current->xid, current->pid);
16060 + put_task_struct(task);
16068 +#warning duplicate inclusion
16070 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_sched.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_sched.h
16071 --- linux-2.6.19.1/include/linux/vs_sched.h 1970-01-01 01:00:00 +0100
16072 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_sched.h 2006-11-30 18:53:18 +0100
16074 +#ifndef _VS_SCHED_H
16075 +#define _VS_SCHED_H
16077 +#include "vserver/base.h"
16078 +#include "vserver/context.h"
16079 +#include "vserver/sched.h"
16082 +#define VAVAVOOM_RATIO 50
16084 +#define MAX_PRIO_BIAS 20
16085 +#define MIN_PRIO_BIAS -20
16088 +#ifdef CONFIG_VSERVER_HARDCPU
16091 + * effective_prio - return the priority that is based on the static
16092 + * priority but is modified by bonuses/penalties.
16094 + * We scale the actual sleep average [0 .... MAX_SLEEP_AVG]
16095 + * into a -4 ... 0 ... +4 bonus/penalty range.
16097 + * Additionally, we scale another amount based on the number of
16098 + * CPU tokens currently held by the context, if the process is
16099 + * part of a context (and the appropriate SCHED flag is set).
16100 + * This ranges from -5 ... 0 ... +15, quadratically.
16102 + * So, the total bonus is -9 .. 0 .. +19
16103 + * We use ~50% of the full 0...39 priority range so that:
16105 + * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs.
16106 + * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks.
16107 + * unless that context is far exceeding its CPU allocation.
16109 + * Both properties are important to certain workloads.
16112 +int vx_effective_vavavoom(struct _vx_sched_pc *sched_pc, int max_prio)
16114 + int vavavoom, max;
16116 + /* lots of tokens = lots of vavavoom
16117 + * no tokens = no vavavoom */
16118 + if ((vavavoom = sched_pc->tokens) >= 0) {
16119 + max = sched_pc->tokens_max;
16120 + vavavoom = max - vavavoom;
16122 + vavavoom = max_prio * VAVAVOOM_RATIO / 100
16123 + * (vavavoom*vavavoom - (max >> 2)) / max;
16131 +int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
16133 + struct vx_info *vxi = p->vx_info;
16138 + if (vx_info_flags(vxi, VXF_SCHED_PRIO, 0)) {
16139 + struct _vx_sched_pc *sched_pc = &vx_cpu(vxi, sched_pc);
16140 + int vavavoom = vx_effective_vavavoom(sched_pc, max_user);
16142 + vxi->sched.vavavoom = vavavoom;
16143 + prio += vavavoom;
16145 + prio += vxi->sched.prio_bias;
16149 +#else /* !CONFIG_VSERVER_HARDCPU */
16152 +int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
16154 + struct vx_info *vxi = p->vx_info;
16157 + prio += vxi->sched.prio_bias;
16161 +#endif /* CONFIG_VSERVER_HARDCPU */
16164 +static inline void vx_account_user(struct vx_info *vxi,
16165 + cputime_t cputime, int nice)
16169 + vx_cpu(vxi, sched_pc).user_ticks += cputime;
16172 +static inline void vx_account_system(struct vx_info *vxi,
16173 + cputime_t cputime, int idle)
16177 + vx_cpu(vxi, sched_pc).sys_ticks += cputime;
16181 +#warning duplicate inclusion
16183 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_socket.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_socket.h
16184 --- linux-2.6.19.1/include/linux/vs_socket.h 1970-01-01 01:00:00 +0100
16185 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_socket.h 2006-11-30 19:13:42 +0100
16187 +#ifndef _VS_SOCKET_H
16188 +#define _VS_SOCKET_H
16190 +#include "vserver/debug.h"
16191 +#include "vserver/base.h"
16192 +#include "vserver/cacct.h"
16193 +#include "vserver/context.h"
16196 +/* socket accounting */
16198 +#include <linux/socket.h>
16200 +static inline int vx_sock_type(int family)
16202 + switch (family) {
16204 + return VXA_SOCK_UNSPEC;
16206 + return VXA_SOCK_UNIX;
16208 + return VXA_SOCK_INET;
16210 + return VXA_SOCK_INET6;
16212 + return VXA_SOCK_PACKET;
16214 + return VXA_SOCK_OTHER;
16218 +#define vx_acc_sock(v,f,p,s) \
16219 + __vx_acc_sock((v), (f), (p), (s), __FILE__, __LINE__)
16221 +static inline void __vx_acc_sock(struct vx_info *vxi,
16222 + int family, int pos, int size, char *file, int line)
16225 + int type = vx_sock_type(family);
16227 + atomic_inc(&vxi->cacct.sock[type][pos].count);
16228 + atomic_add(size, &vxi->cacct.sock[type][pos].total);
16232 +#define vx_sock_recv(sk,s) \
16233 + vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, (s))
16234 +#define vx_sock_send(sk,s) \
16235 + vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, (s))
16236 +#define vx_sock_fail(sk,s) \
16237 + vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, (s))
16240 +#define sock_vx_init(s) do { \
16241 + (s)->sk_xid = 0; \
16242 + (s)->sk_vx_info = NULL; \
16245 +#define sock_nx_init(s) do { \
16246 + (s)->sk_nid = 0; \
16247 + (s)->sk_nx_info = NULL; \
16252 +#warning duplicate inclusion
16254 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_tag.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_tag.h
16255 --- linux-2.6.19.1/include/linux/vs_tag.h 1970-01-01 01:00:00 +0100
16256 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_tag.h 2006-11-30 18:53:18 +0100
16261 +#include <linux/vserver/tag.h>
16263 +/* check conditions */
16265 +#define DX_ADMIN 0x0001
16266 +#define DX_WATCH 0x0002
16267 +#define DX_HOSTID 0x0008
16269 +#define DX_IDENT 0x0010
16271 +#define DX_ARG_MASK 0x0010
16274 +#define dx_task_tag(t) ((t)->xid)
16276 +#define dx_current_tag() dx_task_tag(current)
16278 +#define dx_check(c,m) __dx_check(dx_current_tag(),c,m)
16280 +#define dx_weak_check(c,m) ((m) ? dx_check(c,m) : 1)
16284 + * check current context for ADMIN/WATCH and
16285 + * optionally against supplied argument
16287 +static inline int __dx_check(tag_t cid, tag_t id, unsigned int mode)
16289 + if (mode & DX_ARG_MASK) {
16290 + if ((mode & DX_IDENT) &&
16294 + return (((mode & DX_ADMIN) && (cid == 0)) ||
16295 + ((mode & DX_WATCH) && (cid == 1)) ||
16296 + ((mode & DX_HOSTID) && (id == 0)));
16300 +#warning duplicate inclusion
16302 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_time.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_time.h
16303 --- linux-2.6.19.1/include/linux/vs_time.h 1970-01-01 01:00:00 +0100
16304 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_time.h 2006-11-30 18:53:18 +0100
16306 +#ifndef _VS_TIME_H
16307 +#define _VS_TIME_H
16310 +/* time faking stuff */
16312 +#ifdef CONFIG_VSERVER_VTIME
16314 +extern void vx_gettimeofday(struct timeval *tv);
16315 +extern int vx_settimeofday(struct timespec *ts);
16318 +#define vx_gettimeofday(t) do_gettimeofday(t)
16319 +#define vx_settimeofday(t) do_settimeofday(t)
16323 +#warning duplicate inclusion
16325 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/Kbuild linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/Kbuild
16326 --- linux-2.6.19.1/include/linux/vserver/Kbuild 1970-01-01 01:00:00 +0100
16327 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/Kbuild 2006-12-17 04:40:51 +0100
16330 +unifdef-y += context_cmd.h network_cmd.h space_cmd.h \
16331 + cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \
16332 + inode_cmd.h sched_cmd.h signal_cmd.h debug_cmd.h
16334 +unifdef-y += switch.h network.h monitor.h
16336 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/base.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/base.h
16337 --- linux-2.6.19.1/include/linux/vserver/base.h 1970-01-01 01:00:00 +0100
16338 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/base.h 2006-12-17 05:26:45 +0100
16340 +#ifndef _VX_BASE_H
16341 +#define _VX_BASE_H
16344 +/* context state changes */
16355 +#define MAX_S_CONTEXT 65535 /* Arbitrary limit */
16357 +/* check conditions */
16359 +#define VS_ADMIN 0x0001
16360 +#define VS_WATCH 0x0002
16361 +#define VS_HIDE 0x0004
16362 +#define VS_HOSTID 0x0008
16364 +#define VS_IDENT 0x0010
16365 +#define VS_EQUIV 0x0020
16366 +#define VS_PARENT 0x0040
16367 +#define VS_CHILD 0x0080
16369 +#define VS_ARG_MASK 0x00F0
16371 +#ifdef CONFIG_VSERVER_PRIVACY
16372 +#define VS_ADMIN_P (0)
16373 +#define VS_WATCH_P (0)
16375 +#define VS_ADMIN_P VS_ADMIN
16376 +#define VS_WATCH_P VS_WATCH
16379 +#define VS_HARDIRQ 0x1000
16380 +#define VS_SOFTIRQ 0x2000
16381 +#define VS_IRQ 0x4000
16383 +#define VS_IRQ_MASK 0xF000
16385 +#include <linux/hardirq.h>
16388 + * check current context for ADMIN/WATCH and
16389 + * optionally against supplied argument
16391 +static inline int __vs_check(int cid, int id, unsigned int mode)
16393 + if (mode & VS_ARG_MASK) {
16394 + if ((mode & VS_IDENT) &&
16398 + if (mode & VS_IRQ_MASK) {
16399 + if ((mode & VS_IRQ) && unlikely(in_interrupt()))
16401 + if ((mode & VS_HARDIRQ) && unlikely(in_irq()))
16403 + if ((mode & VS_SOFTIRQ) && unlikely(in_softirq()))
16406 + return (((mode & VS_ADMIN) && (cid == 0)) ||
16407 + ((mode & VS_WATCH) && (cid == 1)) ||
16408 + ((mode & VS_HOSTID) && (id == 0)));
16411 +#define vx_task_xid(t) ((t)->xid)
16413 +#define vx_current_xid() vx_task_xid(current)
16415 +#define current_vx_info() (current->vx_info)
16418 +#define vx_check(c,m) __vs_check(vx_current_xid(),c,(m)|VS_IRQ)
16420 +#define vx_weak_check(c,m) ((m) ? vx_check(c,m) : 1)
16423 +#define nx_task_nid(t) ((t)->nid)
16425 +#define nx_current_nid() nx_task_nid(current)
16427 +#define current_nx_info() (current->nx_info)
16430 +#define nx_check(c,m) __vs_check(nx_current_nid(),c,m)
16432 +#define nx_weak_check(c,m) ((m) ? nx_check(c,m) : 1)
16436 +/* generic flag merging */
16438 +#define vs_check_flags(v,m,f) (((v) & (m)) ^ (f))
16440 +#define vs_mask_flags(v,f,m) (((v) & ~(m)) | ((f) & (m)))
16442 +#define vs_mask_mask(v,f,m) (((v) & ~(m)) | ((v) & (f) & (m)))
16444 +#define vs_check_bit(v,n) ((v) & (1LL << (n)))
16447 +/* context flags */
16449 +#define __vx_flags(v) ((v) ? (v)->vx_flags : 0)
16451 +#define vx_current_flags() __vx_flags(current->vx_info)
16453 +#define vx_info_flags(v,m,f) \
16454 + vs_check_flags(__vx_flags(v),(m),(f))
16456 +#define task_vx_flags(t,m,f) \
16457 + ((t) && vx_info_flags((t)->vx_info, (m), (f)))
16459 +#define vx_flags(m,f) vx_info_flags(current->vx_info,(m),(f))
16462 +/* context caps */
16464 +#define __vx_ccaps(v) ((v) ? (v)->vx_ccaps : 0)
16466 +#define vx_current_ccaps() __vx_ccaps(current->vx_info)
16468 +#define vx_info_ccaps(v,c) (__vx_ccaps(v) & (c))
16470 +#define vx_ccaps(c) vx_info_ccaps(current->vx_info,(c))
16474 +/* network flags */
16476 +#define __nx_flags(v) ((v) ? (v)->nx_flags : 0)
16478 +#define nx_current_flags() __nx_flags(current->nx_info)
16480 +#define nx_info_flags(v,m,f) \
16481 + vs_check_flags(__nx_flags(v),(m),(f))
16483 +#define task_nx_flags(t,m,f) \
16484 + ((t) && nx_info_flags((t)->nx_info, (m), (f)))
16486 +#define nx_flags(m,f) nx_info_flags(current->nx_info,(m),(f))
16489 +/* network caps */
16491 +#define __nx_ncaps(v) ((v) ? (v)->nx_ncaps : 0)
16493 +#define nx_current_ncaps() __nx_ncaps(current->nx_info)
16495 +#define nx_info_ncaps(v,c) (__nx_ncaps(v) & (c))
16497 +#define nx_ncaps(c) nx_info_ncaps(current->nx_info,(c))
16500 +/* context mask capabilities */
16502 +#define __vx_mcaps(v) ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
16504 +#define vx_info_mcaps(v,c) (__vx_mcaps(v) & (c))
16506 +#define vx_mcaps(c) vx_info_mcaps(current->vx_info,(c))
16509 +/* context bcap mask */
16511 +#define __vx_bcaps(v) ((v) ? (v)->vx_bcaps : ~0 )
16513 +#define vx_current_bcaps() __vx_bcaps(current->vx_info)
16515 +#define vx_info_bcaps(v,c) (__vx_bcaps(v) & (c))
16517 +#define vx_bcaps(c) vx_info_bcaps(current->vx_info,(c))
16520 +#define vx_info_cap_bset(v) ((v) ? (v)->vx_cap_bset : cap_bset)
16522 +#define vx_current_cap_bset() vx_info_cap_bset(current->vx_info)
16525 +#define __vx_info_mbcap(v,b) \
16526 + (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \
16527 + vx_info_bcaps(v, b) : (b))
16529 +#define vx_info_mbcap(v,b) __vx_info_mbcap(v,cap_t(b))
16531 +#define task_vx_mbcap(t,b) \
16532 + vx_info_mbcap((t)->vx_info, (t)->b)
16534 +#define vx_mbcap(b) task_vx_mbcap(current,b)
16536 +#define vx_cap_raised(v,c,f) (vx_info_mbcap(v,c) & CAP_TO_MASK(f))
16538 +#define vx_capable(b,c) (capable(b) || \
16539 + (cap_raised(current->cap_effective,b) && vx_ccaps(c)))
16542 +#define vx_current_initpid(n) \
16543 + (current->vx_info && \
16544 + (current->vx_info->vx_initpid == (n)))
16547 +#define __vx_state(v) ((v) ? ((v)->vx_state) : 0)
16549 +#define vx_info_state(v,m) (__vx_state(v) & (m))
16552 +#define __nx_state(v) ((v) ? ((v)->nx_state) : 0)
16554 +#define nx_info_state(v,m) (__nx_state(v) & (m))
16557 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cacct.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct.h
16558 --- linux-2.6.19.1/include/linux/vserver/cacct.h 1970-01-01 01:00:00 +0100
16559 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct.h 2006-11-08 04:57:44 +0100
16561 +#ifndef _VX_CACCT_H
16562 +#define _VX_CACCT_H
16565 +enum sock_acc_field {
16566 + VXA_SOCK_UNSPEC = 0,
16572 + VXA_SOCK_SIZE /* array size */
16575 +#endif /* _VX_CACCT_H */
16576 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cacct_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_cmd.h
16577 --- linux-2.6.19.1/include/linux/vserver/cacct_cmd.h 1970-01-01 01:00:00 +0100
16578 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_cmd.h 2006-11-08 04:57:49 +0100
16580 +#ifndef _VX_CACCT_CMD_H
16581 +#define _VX_CACCT_CMD_H
16584 +/* virtual host info name commands */
16586 +#define VCMD_sock_stat VC_CMD(VSTAT, 5, 0)
16588 +struct vcmd_sock_stat_v0 {
16590 + uint32_t count[3];
16591 + uint64_t total[3];
16597 +#include <linux/compiler.h>
16599 +extern int vc_sock_stat(struct vx_info *, void __user *);
16601 +#endif /* __KERNEL__ */
16602 +#endif /* _VX_CACCT_CMD_H */
16603 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cacct_def.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_def.h
16604 --- linux-2.6.19.1/include/linux/vserver/cacct_def.h 1970-01-01 01:00:00 +0100
16605 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_def.h 2006-11-08 04:57:49 +0100
16607 +#ifndef _VX_CACCT_DEF_H
16608 +#define _VX_CACCT_DEF_H
16610 +#include <asm/atomic.h>
16611 +#include <linux/vserver/cacct.h>
16614 +struct _vx_sock_acc {
16619 +/* context sub struct */
16621 +struct _vx_cacct {
16622 + struct _vx_sock_acc sock[VXA_SOCK_SIZE][3];
16623 + atomic_t slab[8];
16624 + atomic_t page[6][8];
16627 +#ifdef CONFIG_VSERVER_DEBUG
16629 +static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
16633 + printk("\t_vx_cacct:");
16634 + for (i=0; i<6; i++) {
16635 + struct _vx_sock_acc *ptr = cacct->sock[i];
16637 + printk("\t [%d] =", i);
16638 + for (j=0; j<3; j++) {
16639 + printk(" [%d] = %8d, %8d", j,
16640 + atomic_read(&ptr[j].count),
16641 + atomic_read(&ptr[j].total));
16649 +#endif /* _VX_CACCT_DEF_H */
16650 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cacct_int.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_int.h
16651 --- linux-2.6.19.1/include/linux/vserver/cacct_int.h 1970-01-01 01:00:00 +0100
16652 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_int.h 2006-11-08 04:57:44 +0100
16654 +#ifndef _VX_CACCT_INT_H
16655 +#define _VX_CACCT_INT_H
16661 +unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos)
16663 + return atomic_read(&cacct->sock[type][pos].count);
16668 +unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos)
16670 + return atomic_read(&cacct->sock[type][pos].total);
16673 +#endif /* __KERNEL__ */
16674 +#endif /* _VX_CACCT_INT_H */
16675 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/context.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/context.h
16676 --- linux-2.6.19.1/include/linux/vserver/context.h 1970-01-01 01:00:00 +0100
16677 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/context.h 2006-12-17 05:24:26 +0100
16679 +#ifndef _VX_CONTEXT_H
16680 +#define _VX_CONTEXT_H
16682 +#include <linux/types.h>
16683 +#include <linux/capability.h>
16686 +/* context flags */
16688 +#define VXF_INFO_SCHED 0x00000002
16689 +#define VXF_INFO_NPROC 0x00000004
16690 +#define VXF_INFO_PRIVATE 0x00000008
16692 +#define VXF_INFO_INIT 0x00000010
16693 +#define VXF_INFO_HIDE 0x00000020
16694 +#define VXF_INFO_ULIMIT 0x00000040
16695 +#define VXF_INFO_NSPACE 0x00000080
16697 +#define VXF_SCHED_HARD 0x00000100
16698 +#define VXF_SCHED_PRIO 0x00000200
16699 +#define VXF_SCHED_PAUSE 0x00000400
16701 +#define VXF_VIRT_MEM 0x00010000
16702 +#define VXF_VIRT_UPTIME 0x00020000
16703 +#define VXF_VIRT_CPU 0x00040000
16704 +#define VXF_VIRT_LOAD 0x00080000
16705 +#define VXF_VIRT_TIME 0x00100000
16707 +#define VXF_HIDE_MOUNT 0x01000000
16708 +/* was VXF_HIDE_NETIF 0x02000000 */
16709 +#define VXF_HIDE_VINFO 0x04000000
16711 +#define VXF_STATE_SETUP (1ULL<<32)
16712 +#define VXF_STATE_INIT (1ULL<<33)
16713 +#define VXF_STATE_ADMIN (1ULL<<34)
16715 +#define VXF_SC_HELPER (1ULL<<36)
16716 +#define VXF_REBOOT_KILL (1ULL<<37)
16717 +#define VXF_PERSISTENT (1ULL<<38)
16719 +#define VXF_FORK_RSS (1ULL<<48)
16720 +#define VXF_PROLIFIC (1ULL<<49)
16722 +#define VXF_IGNEG_NICE (1ULL<<52)
16724 +#define VXF_ONE_TIME (0x0007ULL<<32)
16726 +#define VXF_INIT_SET (VXF_STATE_SETUP|VXF_STATE_INIT|VXF_STATE_ADMIN)
16729 +/* context migration */
16731 +#define VXM_SET_INIT 0x00000001
16732 +#define VXM_SET_REAPER 0x00000002
16734 +/* context caps */
16736 +#define VXC_CAP_MASK 0x00000000
16738 +#define VXC_SET_UTSNAME 0x00000001
16739 +#define VXC_SET_RLIMIT 0x00000002
16741 +#define VXC_RAW_ICMP 0x00000100
16742 +#define VXC_SYSLOG 0x00001000
16744 +#define VXC_SECURE_MOUNT 0x00010000
16745 +#define VXC_SECURE_REMOUNT 0x00020000
16746 +#define VXC_BINARY_MOUNT 0x00040000
16748 +#define VXC_QUOTA_CTL 0x00100000
16749 +#define VXC_ADMIN_MAPPER 0x00200000
16750 +#define VXC_ADMIN_CLOOP 0x00400000
16755 +#include <linux/list.h>
16756 +#include <linux/spinlock.h>
16757 +#include <linux/rcupdate.h>
16759 +#include "limit_def.h"
16760 +#include "sched_def.h"
16761 +#include "cvirt_def.h"
16762 +#include "cacct_def.h"
16764 +struct _vx_info_pc {
16765 + struct _vx_sched_pc sched_pc;
16766 + struct _vx_cvirt_pc cvirt_pc;
16770 + struct hlist_node vx_hlist; /* linked list of contexts */
16771 + xid_t vx_id; /* context id */
16772 + atomic_t vx_usecnt; /* usage count */
16773 + atomic_t vx_tasks; /* tasks count */
16774 + struct vx_info *vx_parent; /* parent context */
16775 + int vx_state; /* context state */
16777 + unsigned long vx_nsmask; /* assignment mask */
16778 + struct nsproxy *vx_nsproxy; /* private namespace */
16779 + struct fs_struct *vx_fs; /* private namespace fs */
16781 + uint64_t vx_flags; /* context flags */
16782 + uint64_t vx_bcaps; /* bounding caps (system) */
16783 + uint64_t vx_ccaps; /* context caps (vserver) */
16784 + kernel_cap_t vx_cap_bset; /* the guest's bset */
16786 + struct task_struct *vx_reaper; /* guest reaper process */
16787 + pid_t vx_initpid; /* PID of guest init */
16789 + struct _vx_limit limit; /* vserver limits */
16790 + struct _vx_sched sched; /* vserver scheduler */
16791 + struct _vx_cvirt cvirt; /* virtual/bias stuff */
16792 + struct _vx_cacct cacct; /* context accounting */
16794 +#ifndef CONFIG_SMP
16795 + struct _vx_info_pc info_pc; /* per cpu data */
16797 + struct _vx_info_pc *ptr_pc; /* per cpu array */
16800 + wait_queue_head_t vx_wait; /* context exit waitqueue */
16801 + int reboot_cmd; /* last sys_reboot() cmd */
16802 + int exit_code; /* last process exit code */
16804 + char vx_name[65]; /* vserver name */
16807 +#ifndef CONFIG_SMP
16808 +#define vx_ptr_pc(vxi) (&(vxi)->info_pc)
16809 +#define vx_per_cpu(vxi, v, id) vx_ptr_pc(vxi)->v
16811 +#define vx_ptr_pc(vxi) ((vxi)->ptr_pc)
16812 +#define vx_per_cpu(vxi, v, id) per_cpu_ptr(vx_ptr_pc(vxi), id)->v
16815 +#define vx_cpu(vxi, v) vx_per_cpu(vxi, v, smp_processor_id())
16818 +struct vx_info_save {
16819 + struct vx_info *vxi;
16824 +/* status flags */
16826 +#define VXS_HASHED 0x0001
16827 +#define VXS_PAUSED 0x0010
16828 +#define VXS_SHUTDOWN 0x0100
16829 +#define VXS_HELPER 0x1000
16830 +#define VXS_RELEASED 0x8000
16833 +extern void claim_vx_info(struct vx_info *, struct task_struct *);
16834 +extern void release_vx_info(struct vx_info *, struct task_struct *);
16836 +extern struct vx_info *lookup_vx_info(int);
16837 +extern struct vx_info *lookup_or_create_vx_info(int);
16839 +extern int get_xid_list(int, unsigned int *, int);
16840 +extern int xid_is_hashed(xid_t);
16842 +extern int vx_migrate_task(struct task_struct *, struct vx_info *, int);
16844 +extern long vs_state_change(struct vx_info *, unsigned int);
16847 +#endif /* __KERNEL__ */
16848 +#endif /* _VX_CONTEXT_H */
16849 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/context_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/context_cmd.h
16850 --- linux-2.6.19.1/include/linux/vserver/context_cmd.h 1970-01-01 01:00:00 +0100
16851 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/context_cmd.h 2006-11-08 04:57:49 +0100
16853 +#ifndef _VX_CONTEXT_CMD_H
16854 +#define _VX_CONTEXT_CMD_H
16857 +/* vinfo commands */
16859 +#define VCMD_task_xid VC_CMD(VINFO, 1, 0)
16862 +extern int vc_task_xid(uint32_t, void __user *);
16864 +#endif /* __KERNEL__ */
16866 +#define VCMD_vx_info VC_CMD(VINFO, 5, 0)
16868 +struct vcmd_vx_info_v0 {
16870 + uint32_t initpid;
16871 + /* more to come */
16875 +extern int vc_vx_info(struct vx_info *, void __user *);
16877 +#endif /* __KERNEL__ */
16879 +#define VCMD_ctx_stat VC_CMD(VSTAT, 0, 0)
16881 +struct vcmd_ctx_stat_v0 {
16884 + /* more to come */
16888 +extern int vc_ctx_stat(struct vx_info *, void __user *);
16890 +#endif /* __KERNEL__ */
16892 +/* context commands */
16894 +#define VCMD_ctx_create_v0 VC_CMD(VPROC, 1, 0)
16895 +#define VCMD_ctx_create VC_CMD(VPROC, 1, 1)
16897 +struct vcmd_ctx_create {
16898 + uint64_t flagword;
16901 +#define VCMD_ctx_migrate_v0 VC_CMD(PROCMIG, 1, 0)
16902 +#define VCMD_ctx_migrate VC_CMD(PROCMIG, 1, 1)
16904 +struct vcmd_ctx_migrate {
16905 + uint64_t flagword;
16909 +extern int vc_ctx_create(uint32_t, void __user *);
16910 +extern int vc_ctx_migrate(struct vx_info *, void __user *);
16912 +#endif /* __KERNEL__ */
16915 +/* flag commands */
16917 +#define VCMD_get_cflags VC_CMD(FLAGS, 1, 0)
16918 +#define VCMD_set_cflags VC_CMD(FLAGS, 2, 0)
16920 +struct vcmd_ctx_flags_v0 {
16921 + uint64_t flagword;
16926 +extern int vc_get_cflags(struct vx_info *, void __user *);
16927 +extern int vc_set_cflags(struct vx_info *, void __user *);
16929 +#endif /* __KERNEL__ */
16932 +/* context caps commands */
16934 +#define VCMD_get_ccaps_v0 VC_CMD(FLAGS, 3, 0)
16935 +#define VCMD_set_ccaps_v0 VC_CMD(FLAGS, 4, 0)
16937 +struct vcmd_ctx_caps_v0 {
16943 +#define VCMD_get_ccaps VC_CMD(FLAGS, 3, 1)
16944 +#define VCMD_set_ccaps VC_CMD(FLAGS, 4, 1)
16946 +struct vcmd_ctx_caps_v1 {
16952 +extern int vc_get_ccaps_v0(struct vx_info *, void __user *);
16953 +extern int vc_set_ccaps_v0(struct vx_info *, void __user *);
16954 +extern int vc_get_ccaps(struct vx_info *, void __user *);
16955 +extern int vc_set_ccaps(struct vx_info *, void __user *);
16957 +#endif /* __KERNEL__ */
16960 +/* bcaps commands */
16962 +#define VCMD_get_bcaps VC_CMD(FLAGS, 9, 0)
16963 +#define VCMD_set_bcaps VC_CMD(FLAGS,10, 0)
16965 +struct vcmd_bcaps {
16971 +extern int vc_get_bcaps(struct vx_info *, void __user *);
16972 +extern int vc_set_bcaps(struct vx_info *, void __user *);
16974 +#endif /* __KERNEL__ */
16975 +#endif /* _VX_CONTEXT_CMD_H */
16976 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cvirt.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt.h
16977 --- linux-2.6.19.1/include/linux/vserver/cvirt.h 1970-01-01 01:00:00 +0100
16978 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt.h 2006-11-14 02:23:11 +0100
16980 +#ifndef _VX_CVIRT_H
16981 +#define _VX_CVIRT_H
16988 +void vx_vsi_uptime(struct timespec *, struct timespec *);
16993 +void vx_update_load(struct vx_info *);
16996 +int vx_do_syslog(int, char __user *, int);
16998 +#endif /* __KERNEL__ */
16999 +#endif /* _VX_CVIRT_H */
17000 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cvirt_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt_cmd.h
17001 --- linux-2.6.19.1/include/linux/vserver/cvirt_cmd.h 1970-01-01 01:00:00 +0100
17002 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt_cmd.h 2006-11-08 04:57:49 +0100
17004 +#ifndef _VX_CVIRT_CMD_H
17005 +#define _VX_CVIRT_CMD_H
17008 +/* virtual host info name commands */
17010 +#define VCMD_set_vhi_name VC_CMD(VHOST, 1, 0)
17011 +#define VCMD_get_vhi_name VC_CMD(VHOST, 2, 0)
17013 +struct vcmd_vhi_name_v0 {
17019 +enum vhi_name_field {
17032 +#include <linux/compiler.h>
17034 +extern int vc_set_vhi_name(struct vx_info *, void __user *);
17035 +extern int vc_get_vhi_name(struct vx_info *, void __user *);
17037 +#endif /* __KERNEL__ */
17039 +#define VCMD_virt_stat VC_CMD(VSTAT, 3, 0)
17041 +struct vcmd_virt_stat_v0 {
17044 + uint32_t nr_threads;
17045 + uint32_t nr_running;
17046 + uint32_t nr_uninterruptible;
17047 + uint32_t nr_onhold;
17048 + uint32_t nr_forks;
17049 + uint32_t load[3];
17053 +extern int vc_virt_stat(struct vx_info *, void __user *);
17055 +#endif /* __KERNEL__ */
17056 +#endif /* _VX_CVIRT_CMD_H */
17057 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cvirt_def.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt_def.h
17058 --- linux-2.6.19.1/include/linux/vserver/cvirt_def.h 1970-01-01 01:00:00 +0100
17059 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt_def.h 2006-11-14 00:04:36 +0100
17061 +#ifndef _VX_CVIRT_DEF_H
17062 +#define _VX_CVIRT_DEF_H
17064 +#include <linux/jiffies.h>
17065 +#include <linux/spinlock.h>
17066 +#include <linux/wait.h>
17067 +#include <linux/time.h>
17068 +#include <linux/utsname.h>
17069 +#include <asm/atomic.h>
17072 +struct _vx_usage_stat {
17076 + uint64_t softirq;
17082 +struct _vx_syslog {
17083 + wait_queue_head_t log_wait;
17084 + spinlock_t logbuf_lock; /* lock for the log buffer */
17086 + unsigned long log_start; /* next char to be read by syslog() */
17087 + unsigned long con_start; /* next char to be sent to consoles */
17088 + unsigned long log_end; /* most-recently-written-char + 1 */
17089 + unsigned long logged_chars; /* #chars since last read+clear operation */
17091 + char log_buf[1024];
17095 +/* context sub struct */
17097 +struct _vx_cvirt {
17098 +// int max_threads; /* maximum allowed threads */
17099 + atomic_t nr_threads; /* number of current threads */
17100 + atomic_t nr_running; /* number of running threads */
17101 + atomic_t nr_uninterruptible; /* number of uninterruptible threads */
17103 + atomic_t nr_onhold; /* processes on hold */
17104 + uint32_t onhold_last; /* jiffies when put on hold */
17106 + struct timeval bias_tv; /* time offset to the host */
17107 + struct timespec bias_idle;
17108 + struct timespec bias_uptime; /* context creation point */
17109 + uint64_t bias_clock; /* offset in clock_t */
17111 + spinlock_t load_lock; /* lock for the load averages */
17112 + atomic_t load_updates; /* nr of load updates done so far */
17113 + uint32_t load_last; /* last time load was calculated */
17114 + uint32_t load[3]; /* load averages 1,5,15 */
17116 + atomic_t total_forks; /* number of forks so far */
17118 + struct _vx_syslog syslog;
17121 +struct _vx_cvirt_pc {
17122 + struct _vx_usage_stat cpustat;
17126 +#ifdef CONFIG_VSERVER_DEBUG
17128 +static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
17130 + printk("\t_vx_cvirt:\n");
17131 + printk("\t threads: %4d, %4d, %4d, %4d\n",
17132 + atomic_read(&cvirt->nr_threads),
17133 + atomic_read(&cvirt->nr_running),
17134 + atomic_read(&cvirt->nr_uninterruptible),
17135 + atomic_read(&cvirt->nr_onhold));
17136 + /* add rest here */
17137 + printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks));
17142 +#endif /* _VX_CVIRT_DEF_H */
17143 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/debug.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/debug.h
17144 --- linux-2.6.19.1/include/linux/vserver/debug.h 1970-01-01 01:00:00 +0100
17145 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/debug.h 2006-11-08 04:57:48 +0100
17147 +#ifndef _VX_DEBUG_H
17148 +#define _VX_DEBUG_H
17151 +#define VXD_CBIT(n,m) (vx_debug_ ## n & (1 << (m)))
17152 +#define VXD_CMIN(n,m) (vx_debug_ ## n > (m))
17153 +#define VXD_MASK(n,m) (vx_debug_ ## n & (m))
17155 +#define VXD_QPOS(v,p) (((uint32_t)(v) >> ((p)*8)) & 0xFF)
17156 +#define VXD_QUAD(v) VXD_QPOS(v,0), VXD_QPOS(v,1), \
17157 + VXD_QPOS(v,2), VXD_QPOS(v,3)
17158 +#define VXF_QUAD "%u.%u.%u.%u"
17160 +#define VXD_DEV(d) (d), (d)->bd_inode->i_ino, \
17161 + imajor((d)->bd_inode), iminor((d)->bd_inode)
17162 +#define VXF_DEV "%p[%lu,%d:%d]"
17165 +#define __FUNC__ __func__
17168 +#ifdef CONFIG_VSERVER_DEBUG
17170 +extern unsigned int vx_debug_switch;
17171 +extern unsigned int vx_debug_xid;
17172 +extern unsigned int vx_debug_nid;
17173 +extern unsigned int vx_debug_tag;
17174 +extern unsigned int vx_debug_net;
17175 +extern unsigned int vx_debug_limit;
17176 +extern unsigned int vx_debug_cres;
17177 +extern unsigned int vx_debug_dlim;
17178 +extern unsigned int vx_debug_quota;
17179 +extern unsigned int vx_debug_cvirt;
17180 +extern unsigned int vx_debug_misc;
17183 +#define VX_LOGLEVEL "vxD: "
17184 +#define VX_WARNLEVEL KERN_WARNING "vxW: "
17186 +#define vxdprintk(c,f,x...) \
17189 + printk(VX_LOGLEVEL f "\n" , ##x); \
17192 +#define vxlprintk(c,f,x...) \
17195 + printk(VX_LOGLEVEL f " @%s:%d\n", x); \
17198 +#define vxfprintk(c,f,x...) \
17201 + printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
17205 +#define vxwprintk(c,f,x...) \
17208 + printk(VX_WARNLEVEL f "\n" , ##x); \
17212 +#define vxd_path(d,m) \
17213 + ({ static char _buffer[PATH_MAX]; \
17214 + d_path((d), (m), _buffer, sizeof(_buffer)); })
17216 +#define vxd_cond_path(n) \
17217 + ((n) ? vxd_path((n)->dentry, (n)->mnt) : "<null>" )
17222 +void dump_vx_info(struct vx_info *, int);
17223 +void dump_vx_info_inactive(int);
17225 +#else /* CONFIG_VSERVER_DEBUG */
17227 +#define vx_debug_switch 0
17228 +#define vx_debug_xid 0
17229 +#define vx_debug_nid 0
17230 +#define vx_debug_tag 0
17231 +#define vx_debug_net 0
17232 +#define vx_debug_limit 0
17233 +#define vx_debug_cres 0
17234 +#define vx_debug_dlim 0
17235 +#define vx_debug_cvirt 0
17237 +#define vxdprintk(x...) do { } while (0)
17238 +#define vxlprintk(x...) do { } while (0)
17239 +#define vxfprintk(x...) do { } while (0)
17240 +#define vxwprintk(x...) do { } while (0)
17242 +#define vxd_path "<none>"
17243 +#define vxd_cond_path vxd_path
17245 +#endif /* CONFIG_VSERVER_DEBUG */
17248 +#ifdef CONFIG_VSERVER_DEBUG
17249 +#define vxd_assert_lock(l) assert_spin_locked(l)
17250 +#define vxd_assert(c,f,x...) vxlprintk(!(c), \
17251 + "assertion [" f "] failed.", ##x, __FILE__, __LINE__)
17253 +#define vxd_assert_lock(l) do { } while (0)
17254 +#define vxd_assert(c,f,x...) do { } while (0)
17258 +#endif /* _VX_DEBUG_H */
17259 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/debug_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/debug_cmd.h
17260 --- linux-2.6.19.1/include/linux/vserver/debug_cmd.h 1970-01-01 01:00:00 +0100
17261 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/debug_cmd.h 2006-11-08 04:57:49 +0100
17263 +#ifndef _VX_DEBUG_CMD_H
17264 +#define _VX_DEBUG_CMD_H
17267 +/* debug commands */
17269 +#define VCMD_dump_history VC_CMD(DEBUG, 1, 0)
17271 +#define VCMD_read_history VC_CMD(DEBUG, 5, 0)
17272 +#define VCMD_read_monitor VC_CMD(DEBUG, 6, 0)
17274 +struct vcmd_read_history_v0 {
17277 + char __user *data;
17280 +struct vcmd_read_monitor_v0 {
17283 + char __user *data;
17289 +#ifdef CONFIG_COMPAT
17291 +#include <asm/compat.h>
17293 +struct vcmd_read_history_v0_x32 {
17296 + compat_uptr_t data_ptr;
17299 +struct vcmd_read_monitor_v0_x32 {
17302 + compat_uptr_t data_ptr;
17305 +#endif /* CONFIG_COMPAT */
17307 +extern int vc_dump_history(uint32_t);
17309 +extern int vc_read_history(uint32_t, void __user *);
17310 +extern int vc_read_monitor(uint32_t, void __user *);
17312 +#ifdef CONFIG_COMPAT
17314 +extern int vc_read_history_x32(uint32_t, void __user *);
17315 +extern int vc_read_monitor_x32(uint32_t, void __user *);
17317 +#endif /* CONFIG_COMPAT */
17319 +#endif /* __KERNEL__ */
17320 +#endif /* _VX_DEBUG_CMD_H */
17321 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/device.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/device.h
17322 --- linux-2.6.19.1/include/linux/vserver/device.h 1970-01-01 01:00:00 +0100
17323 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/device.h 2006-12-09 03:45:16 +0100
17325 +#ifndef _VX_DEVICE_H
17326 +#define _VX_DEVICE_H
17329 +#define DATTR_CREATE 0x00000001
17330 +#define DATTR_OPEN 0x00000002
17332 +#define DATTR_REMAP 0x00000010
17335 +#else /* _VX_DEVICE_H */
17336 +#warning duplicate inclusion
17337 +#endif /* _VX_DEVICE_H */
17338 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/device_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/device_cmd.h
17339 --- linux-2.6.19.1/include/linux/vserver/device_cmd.h 1970-01-01 01:00:00 +0100
17340 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/device_cmd.h 2006-12-09 03:47:06 +0100
17342 +#ifndef _VX_DEVICE_CMD_H
17343 +#define _VX_DEVICE_CMD_H
17346 +/* device vserver commands */
17348 +#define VCMD_set_mapping VC_CMD(DEVICE, 1, 0)
17350 +struct vcmd_set_mapping_v0 {
17351 + const char __user *device;
17352 + const char __user *target;
17359 +#ifdef CONFIG_COMPAT
17361 +#include <asm/compat.h>
17363 +struct vcmd_set_mapping_v0_x32 {
17364 + compat_uptr_t device_ptr;
17365 + compat_uptr_t target_ptr;
17369 +#endif /* CONFIG_COMPAT */
17371 +#include <linux/compiler.h>
17373 +extern int vc_set_mapping(uint32_t, void __user *);
17375 +#ifdef CONFIG_COMPAT
17377 +extern int vc_set_mapping_x32(uint32_t, void __user *);
17379 +#endif /* CONFIG_COMPAT */
17381 +#endif /* __KERNEL__ */
17382 +#endif /* _VX_DEVICE_CMD_H */
17383 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/dlimit.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/dlimit.h
17384 --- linux-2.6.19.1/include/linux/vserver/dlimit.h 1970-01-01 01:00:00 +0100
17385 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/dlimit.h 2006-11-08 04:57:50 +0100
17387 +#ifndef _VX_DLIMIT_H
17388 +#define _VX_DLIMIT_H
17390 +#include "switch.h"
17395 +/* keep in sync with CDLIM_INFINITY */
17397 +#define DLIM_INFINITY (~0ULL)
17399 +#include <linux/spinlock.h>
17401 +struct super_block;
17404 + struct hlist_node dl_hlist; /* linked list of contexts */
17405 + struct rcu_head dl_rcu; /* the rcu head */
17406 + tag_t dl_tag; /* context tag */
17407 + atomic_t dl_usecnt; /* usage count */
17408 + atomic_t dl_refcnt; /* reference count */
17410 + struct super_block *dl_sb; /* associated superblock */
17412 + spinlock_t dl_lock; /* protect the values */
17414 + unsigned long long dl_space_used; /* used space in bytes */
17415 + unsigned long long dl_space_total; /* maximum space in bytes */
17416 + unsigned long dl_inodes_used; /* used inodes */
17417 + unsigned long dl_inodes_total; /* maximum inodes */
17419 + unsigned int dl_nrlmult; /* non root limit mult */
17424 +extern void rcu_free_dl_info(struct rcu_head *);
17425 +extern void unhash_dl_info(struct dl_info *);
17427 +extern struct dl_info *locate_dl_info(struct super_block *, tag_t);
17432 +extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
17434 +typedef uint64_t dlsize_t;
17436 +#endif /* __KERNEL__ */
17437 +#else /* _VX_DLIMIT_H */
17438 +#warning duplicate inclusion
17439 +#endif /* _VX_DLIMIT_H */
17440 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/dlimit_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/dlimit_cmd.h
17441 --- linux-2.6.19.1/include/linux/vserver/dlimit_cmd.h 1970-01-01 01:00:00 +0100
17442 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/dlimit_cmd.h 2006-11-08 04:57:49 +0100
17444 +#ifndef _VX_DLIMIT_CMD_H
17445 +#define _VX_DLIMIT_CMD_H
17448 +/* dlimit vserver commands */
17450 +#define VCMD_add_dlimit VC_CMD(DLIMIT, 1, 0)
17451 +#define VCMD_rem_dlimit VC_CMD(DLIMIT, 2, 0)
17453 +#define VCMD_set_dlimit VC_CMD(DLIMIT, 5, 0)
17454 +#define VCMD_get_dlimit VC_CMD(DLIMIT, 6, 0)
17456 +struct vcmd_ctx_dlimit_base_v0 {
17457 + const char __user *name;
17461 +struct vcmd_ctx_dlimit_v0 {
17462 + const char __user *name;
17463 + uint32_t space_used; /* used space in kbytes */
17464 + uint32_t space_total; /* maximum space in kbytes */
17465 + uint32_t inodes_used; /* used inodes */
17466 + uint32_t inodes_total; /* maximum inodes */
17467 + uint32_t reserved; /* reserved for root in % */
17471 +#define CDLIM_UNSET ((uint32_t)0UL)
17472 +#define CDLIM_INFINITY ((uint32_t)~0UL)
17473 +#define CDLIM_KEEP ((uint32_t)~1UL)
17477 +#ifdef CONFIG_COMPAT
17479 +#include <asm/compat.h>
17481 +struct vcmd_ctx_dlimit_base_v0_x32 {
17482 + compat_uptr_t name_ptr;
17486 +struct vcmd_ctx_dlimit_v0_x32 {
17487 + compat_uptr_t name_ptr;
17488 + uint32_t space_used; /* used space in kbytes */
17489 + uint32_t space_total; /* maximum space in kbytes */
17490 + uint32_t inodes_used; /* used inodes */
17491 + uint32_t inodes_total; /* maximum inodes */
17492 + uint32_t reserved; /* reserved for root in % */
17496 +#endif /* CONFIG_COMPAT */
17498 +#include <linux/compiler.h>
17500 +extern int vc_add_dlimit(uint32_t, void __user *);
17501 +extern int vc_rem_dlimit(uint32_t, void __user *);
17503 +extern int vc_set_dlimit(uint32_t, void __user *);
17504 +extern int vc_get_dlimit(uint32_t, void __user *);
17506 +#ifdef CONFIG_COMPAT
17508 +extern int vc_add_dlimit_x32(uint32_t, void __user *);
17509 +extern int vc_rem_dlimit_x32(uint32_t, void __user *);
17511 +extern int vc_set_dlimit_x32(uint32_t, void __user *);
17512 +extern int vc_get_dlimit_x32(uint32_t, void __user *);
17514 +#endif /* CONFIG_COMPAT */
17516 +#endif /* __KERNEL__ */
17517 +#endif /* _VX_DLIMIT_CMD_H */
17518 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/global.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/global.h
17519 --- linux-2.6.19.1/include/linux/vserver/global.h 1970-01-01 01:00:00 +0100
17520 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/global.h 2006-12-06 21:16:15 +0100
17522 +#ifndef _VX_GLOBAL_H
17523 +#define _VX_GLOBAL_H
17526 +extern atomic_t vx_global_ctotal;
17527 +extern atomic_t vx_global_cactive;
17529 +extern atomic_t nx_global_ctotal;
17530 +extern atomic_t nx_global_cactive;
17532 +#endif /* _VX_GLOBAL_H */
17533 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/history.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/history.h
17534 --- linux-2.6.19.1/include/linux/vserver/history.h 1970-01-01 01:00:00 +0100
17535 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/history.h 2006-11-30 19:59:44 +0100
17537 +#ifndef _VX_HISTORY_H
17538 +#define _VX_HISTORY_H
17543 + VXH_THROW_OOPS=1,
17547 + VXH_INIT_VX_INFO,
17550 + VXH_CLAIM_VX_INFO,
17551 + VXH_RELEASE_VX_INFO,
17552 + VXH_ALLOC_VX_INFO,
17553 + VXH_DEALLOC_VX_INFO,
17554 + VXH_HASH_VX_INFO,
17555 + VXH_UNHASH_VX_INFO,
17557 + VXH_LOOKUP_VX_INFO,
17558 + VXH_CREATE_VX_INFO,
17561 +struct _vxhe_vxi {
17562 + struct vx_info *ptr;
17568 +struct _vxhe_set_clr {
17572 +struct _vxhe_loc_lookup {
17576 +struct _vx_hist_entry {
17578 + unsigned short seq;
17579 + unsigned short type;
17580 + struct _vxhe_vxi vxi;
17582 + struct _vxhe_set_clr sc;
17583 + struct _vxhe_loc_lookup ll;
17587 +#ifdef CONFIG_VSERVER_HISTORY
17589 +extern unsigned volatile int vxh_active;
17591 +struct _vx_hist_entry *vxh_advance(void *loc);
17595 +void __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
17597 + entry->vxi.ptr = vxi;
17599 + entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
17600 + entry->vxi.tasks = atomic_read(&vxi->vx_tasks);
17601 + entry->vxi.xid = vxi->vx_id;
17606 +#define __HERE__ current_text_addr()
17608 +#define __VXH_BODY(__type, __data, __here) \
17609 + struct _vx_hist_entry *entry; \
17611 + preempt_disable(); \
17612 + entry = vxh_advance(__here); \
17614 + entry->type = __type; \
17615 + preempt_enable();
17618 + /* pass vxi only */
17620 +#define __VXH_SMPL \
17621 + __vxh_copy_vxi(entry, vxi)
17624 +void __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
17626 + __VXH_BODY(__type, __VXH_SMPL, __here)
17629 + /* pass vxi and data (void *) */
17631 +#define __VXH_DATA \
17632 + __vxh_copy_vxi(entry, vxi); \
17633 + entry->sc.data = data
17636 +void __vxh_data(struct vx_info *vxi, void *data,
17637 + int __type, void *__here)
17639 + __VXH_BODY(__type, __VXH_DATA, __here)
17642 + /* pass vxi and arg (long) */
17644 +#define __VXH_LONG \
17645 + __vxh_copy_vxi(entry, vxi); \
17646 + entry->ll.arg = arg
17649 +void __vxh_long(struct vx_info *vxi, long arg,
17650 + int __type, void *__here)
17652 + __VXH_BODY(__type, __VXH_LONG, __here)
17657 +void __vxh_throw_oops(void *__here)
17659 + __VXH_BODY(VXH_THROW_OOPS, {}, __here);
17660 + /* prevent further acquisition */
17665 +#define vxh_throw_oops() __vxh_throw_oops(__HERE__);
17667 +#define __vxh_get_vx_info(v,h) __vxh_smpl(v, VXH_GET_VX_INFO, h);
17668 +#define __vxh_put_vx_info(v,h) __vxh_smpl(v, VXH_PUT_VX_INFO, h);
17670 +#define __vxh_init_vx_info(v,d,h) \
17671 + __vxh_data(v,d, VXH_INIT_VX_INFO, h);
17672 +#define __vxh_set_vx_info(v,d,h) \
17673 + __vxh_data(v,d, VXH_SET_VX_INFO, h);
17674 +#define __vxh_clr_vx_info(v,d,h) \
17675 + __vxh_data(v,d, VXH_CLR_VX_INFO, h);
17677 +#define __vxh_claim_vx_info(v,d,h) \
17678 + __vxh_data(v,d, VXH_CLAIM_VX_INFO, h);
17679 +#define __vxh_release_vx_info(v,d,h) \
17680 + __vxh_data(v,d, VXH_RELEASE_VX_INFO, h);
17682 +#define vxh_alloc_vx_info(v) \
17683 + __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__);
17684 +#define vxh_dealloc_vx_info(v) \
17685 + __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__);
17687 +#define vxh_hash_vx_info(v) \
17688 + __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__);
17689 +#define vxh_unhash_vx_info(v) \
17690 + __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__);
17692 +#define vxh_loc_vx_info(v,l) \
17693 + __vxh_long(v,l, VXH_LOC_VX_INFO, __HERE__);
17694 +#define vxh_lookup_vx_info(v,l) \
17695 + __vxh_long(v,l, VXH_LOOKUP_VX_INFO, __HERE__);
17696 +#define vxh_create_vx_info(v,l) \
17697 + __vxh_long(v,l, VXH_CREATE_VX_INFO, __HERE__);
17699 +extern void vxh_dump_history(void);
17702 +#else /* CONFIG_VSERVER_HISTORY */
17704 +#define __HERE__ 0
17706 +#define vxh_throw_oops() do { } while (0)
17708 +#define __vxh_get_vx_info(v,h) do { } while (0)
17709 +#define __vxh_put_vx_info(v,h) do { } while (0)
17711 +#define __vxh_init_vx_info(v,d,h) do { } while (0)
17712 +#define __vxh_set_vx_info(v,d,h) do { } while (0)
17713 +#define __vxh_clr_vx_info(v,d,h) do { } while (0)
17715 +#define __vxh_claim_vx_info(v,d,h) do { } while (0)
17716 +#define __vxh_release_vx_info(v,d,h) do { } while (0)
17718 +#define vxh_alloc_vx_info(v) do { } while (0)
17719 +#define vxh_dealloc_vx_info(v) do { } while (0)
17721 +#define vxh_hash_vx_info(v) do { } while (0)
17722 +#define vxh_unhash_vx_info(v) do { } while (0)
17724 +#define vxh_loc_vx_info(a,v) do { } while (0)
17725 +#define vxh_lookup_vx_info(a,v) do { } while (0)
17726 +#define vxh_create_vx_info(a,v) do { } while (0)
17728 +#define vxh_dump_history() do { } while (0)
17731 +#endif /* CONFIG_VSERVER_HISTORY */
17733 +#endif /* _VX_HISTORY_H */
17734 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/inode.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/inode.h
17735 --- linux-2.6.19.1/include/linux/vserver/inode.h 1970-01-01 01:00:00 +0100
17736 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/inode.h 2006-11-08 04:57:45 +0100
17738 +#ifndef _VX_INODE_H
17739 +#define _VX_INODE_H
17742 +#define IATTR_TAG 0x01000000
17744 +#define IATTR_ADMIN 0x00000001
17745 +#define IATTR_WATCH 0x00000002
17746 +#define IATTR_HIDE 0x00000004
17747 +#define IATTR_FLAGS 0x00000007
17749 +#define IATTR_BARRIER 0x00010000
17750 +#define IATTR_IUNLINK 0x00020000
17751 +#define IATTR_IMMUTABLE 0x00040000
17756 +#ifdef CONFIG_VSERVER_PROC_SECURE
17757 +#define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE )
17758 +#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
17760 +#define IATTR_PROC_DEFAULT ( IATTR_ADMIN )
17761 +#define IATTR_PROC_SYMLINK ( IATTR_ADMIN )
17764 +#define vx_hide_check(c,m) (((m) & IATTR_HIDE) ? vx_check(c,m) : 1)
17766 +#endif /* __KERNEL__ */
17768 +/* inode ioctls */
17770 +#define FIOC_GETXFLG _IOR('x', 5, long)
17771 +#define FIOC_SETXFLG _IOW('x', 6, long)
17773 +#else /* _VX_INODE_H */
17774 +#warning duplicate inclusion
17775 +#endif /* _VX_INODE_H */
17776 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/inode_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/inode_cmd.h
17777 --- linux-2.6.19.1/include/linux/vserver/inode_cmd.h 1970-01-01 01:00:00 +0100
17778 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/inode_cmd.h 2006-11-08 04:57:49 +0100
17780 +#ifndef _VX_INODE_CMD_H
17781 +#define _VX_INODE_CMD_H
17784 +/* inode vserver commands */
17786 +#define VCMD_get_iattr_v0 VC_CMD(INODE, 1, 0)
17787 +#define VCMD_set_iattr_v0 VC_CMD(INODE, 2, 0)
17789 +#define VCMD_get_iattr VC_CMD(INODE, 1, 1)
17790 +#define VCMD_set_iattr VC_CMD(INODE, 2, 1)
17792 +struct vcmd_ctx_iattr_v0 {
17793 + /* device handle in id */
17800 +struct vcmd_ctx_iattr_v1 {
17801 + const char __user *name;
17811 +#ifdef CONFIG_COMPAT
17813 +#include <asm/compat.h>
17815 +struct vcmd_ctx_iattr_v1_x32 {
17816 + compat_uptr_t name_ptr;
17822 +#endif /* CONFIG_COMPAT */
17824 +#include <linux/compiler.h>
17826 +extern int vc_get_iattr_v0(uint32_t, void __user *);
17827 +extern int vc_set_iattr_v0(uint32_t, void __user *);
17829 +extern int vc_get_iattr(uint32_t, void __user *);
17830 +extern int vc_set_iattr(uint32_t, void __user *);
17832 +#ifdef CONFIG_COMPAT
17834 +extern int vc_get_iattr_x32(uint32_t, void __user *);
17835 +extern int vc_set_iattr_x32(uint32_t, void __user *);
17837 +#endif /* CONFIG_COMPAT */
17839 +#endif /* __KERNEL__ */
17840 +#endif /* _VX_INODE_CMD_H */
17841 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/limit.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit.h
17842 --- linux-2.6.19.1/include/linux/vserver/limit.h 1970-01-01 01:00:00 +0100
17843 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit.h 2006-11-30 19:31:41 +0100
17845 +#ifndef _VX_LIMIT_H
17846 +#define _VX_LIMIT_H
17849 +#define VLIMIT_NSOCK 16
17850 +#define VLIMIT_OPENFD 17
17851 +#define VLIMIT_ANON 18
17852 +#define VLIMIT_SHMEM 19
17853 +#define VLIMIT_SEMARY 20
17854 +#define VLIMIT_NSEMS 21
17855 +#define VLIMIT_DENTRY 22
17856 +#define VLIMIT_MAPPED 23
17861 +#define VLIM_NOCHECK ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS))
17863 +/* keep in sync with CRLIM_INFINITY */
17865 +#define VLIM_INFINITY (~0ULL)
17867 +#ifndef RLIM_INFINITY
17868 +#warning RLIM_INFINITY is undefined
17871 +#define __rlim_val(l,r,v) ((l)->res[(r)].v)
17873 +#define __rlim_soft(l,r) __rlim_val(l,r,soft)
17874 +#define __rlim_hard(l,r) __rlim_val(l,r,hard)
17876 +#define __rlim_rcur(l,r) __rlim_val(l,r,rcur)
17877 +#define __rlim_rmin(l,r) __rlim_val(l,r,rmin)
17878 +#define __rlim_rmax(l,r) __rlim_val(l,r,rmax)
17880 +#define __rlim_lhit(l,r) __rlim_val(l,r,lhit)
17881 +#define __rlim_hit(l,r) atomic_inc(&__rlim_lhit(l,r))
17883 +typedef atomic_long_t rlim_atomic_t;
17884 +typedef unsigned long rlim_t;
17886 +#define __rlim_get(l,r) atomic_long_read(&__rlim_rcur(l,r))
17887 +#define __rlim_set(l,r,v) atomic_long_set(&__rlim_rcur(l,r), v)
17888 +#define __rlim_inc(l,r) atomic_long_inc(&__rlim_rcur(l,r))
17889 +#define __rlim_dec(l,r) atomic_long_dec(&__rlim_rcur(l,r))
17890 +#define __rlim_add(l,r,v) atomic_long_add(v, &__rlim_rcur(l,r))
17891 +#define __rlim_sub(l,r,v) atomic_long_sub(v, &__rlim_rcur(l,r))
17894 +#if (RLIM_INFINITY == VLIM_INFINITY)
17895 +#define VX_VLIM(r) ((long long)(long)(r))
17896 +#define VX_RLIM(v) ((rlim_t)(v))
17898 +#define VX_VLIM(r) (((r) == RLIM_INFINITY) \
17899 + ? VLIM_INFINITY : (long long)(r))
17900 +#define VX_RLIM(v) (((v) == VLIM_INFINITY) \
17901 + ? RLIM_INFINITY : (rlim_t)(v))
17906 +void vx_vsi_meminfo(struct sysinfo *);
17907 +void vx_vsi_swapinfo(struct sysinfo *);
17909 +#define NUM_LIMITS 24
17911 +#endif /* __KERNEL__ */
17912 +#endif /* _VX_LIMIT_H */
17913 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/limit_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_cmd.h
17914 --- linux-2.6.19.1/include/linux/vserver/limit_cmd.h 1970-01-01 01:00:00 +0100
17915 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_cmd.h 2006-11-08 04:57:49 +0100
17917 +#ifndef _VX_LIMIT_CMD_H
17918 +#define _VX_LIMIT_CMD_H
17921 +/* rlimit vserver commands */
17923 +#define VCMD_get_rlimit VC_CMD(RLIMIT, 1, 0)
17924 +#define VCMD_set_rlimit VC_CMD(RLIMIT, 2, 0)
17925 +#define VCMD_get_rlimit_mask VC_CMD(RLIMIT, 3, 0)
17926 +#define VCMD_reset_minmax VC_CMD(RLIMIT, 9, 0)
17928 +struct vcmd_ctx_rlimit_v0 {
17930 + uint64_t minimum;
17931 + uint64_t softlimit;
17932 + uint64_t maximum;
17935 +struct vcmd_ctx_rlimit_mask_v0 {
17936 + uint32_t minimum;
17937 + uint32_t softlimit;
17938 + uint32_t maximum;
17941 +#define VCMD_rlimit_stat VC_CMD(VSTAT, 1, 0)
17943 +struct vcmd_rlimit_stat_v0 {
17947 + uint64_t minimum;
17948 + uint64_t maximum;
17951 +#define CRLIM_UNSET (0ULL)
17952 +#define CRLIM_INFINITY (~0ULL)
17953 +#define CRLIM_KEEP (~1ULL)
17957 +#ifdef CONFIG_IA32_EMULATION
17959 +struct vcmd_ctx_rlimit_v0_x32 {
17961 + uint64_t minimum;
17962 + uint64_t softlimit;
17963 + uint64_t maximum;
17964 +} __attribute__ ((aligned (4)));
17966 +#endif /* CONFIG_IA32_EMULATION */
17968 +#include <linux/compiler.h>
17970 +extern int vc_get_rlimit_mask(uint32_t, void __user *);
17971 +extern int vc_get_rlimit(struct vx_info *, void __user *);
17972 +extern int vc_set_rlimit(struct vx_info *, void __user *);
17973 +extern int vc_reset_minmax(struct vx_info *, void __user *);
17975 +extern int vc_rlimit_stat(struct vx_info *, void __user *);
17977 +#ifdef CONFIG_IA32_EMULATION
17979 +extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
17980 +extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
17982 +#endif /* CONFIG_IA32_EMULATION */
17984 +#endif /* __KERNEL__ */
17985 +#endif /* _VX_LIMIT_CMD_H */
17986 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/limit_def.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_def.h
17987 --- linux-2.6.19.1/include/linux/vserver/limit_def.h 1970-01-01 01:00:00 +0100
17988 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_def.h 2006-11-08 04:57:49 +0100
17990 +#ifndef _VX_LIMIT_DEF_H
17991 +#define _VX_LIMIT_DEF_H
17993 +#include <asm/atomic.h>
17994 +#include <asm/resource.h>
17996 +#include "limit.h"
17999 +struct _vx_res_limit {
18000 + rlim_t soft; /* Context soft limit */
18001 + rlim_t hard; /* Context hard limit */
18003 + rlim_atomic_t rcur; /* Current value */
18004 + rlim_t rmin; /* Context minimum */
18005 + rlim_t rmax; /* Context maximum */
18007 + atomic_t lhit; /* Limit hits */
18010 +/* context sub struct */
18012 +struct _vx_limit {
18013 + struct _vx_res_limit res[NUM_LIMITS];
18016 +#ifdef CONFIG_VSERVER_DEBUG
18018 +static inline void __dump_vx_limit(struct _vx_limit *limit)
18022 + printk("\t_vx_limit:");
18023 + for (i=0; i<NUM_LIMITS; i++) {
18024 + printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
18025 + i, (unsigned long)__rlim_get(limit, i),
18026 + (unsigned long)__rlim_rmin(limit, i),
18027 + (unsigned long)__rlim_rmax(limit, i),
18028 + (long)__rlim_soft(limit, i),
18029 + (long)__rlim_hard(limit, i),
18030 + atomic_read(&__rlim_lhit(limit, i)));
18036 +#endif /* _VX_LIMIT_DEF_H */
18037 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/limit_int.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_int.h
18038 --- linux-2.6.19.1/include/linux/vserver/limit_int.h 1970-01-01 01:00:00 +0100
18039 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_int.h 2006-12-04 05:22:12 +0100
18041 +#ifndef _VX_LIMIT_INT_H
18042 +#define _VX_LIMIT_INT_H
18044 +#include "context.h"
18048 +#define VXD_RCRES_COND(r) VXD_CBIT(cres, (r))
18049 +#define VXD_RLIMIT_COND(r) VXD_CBIT(limit, (r))
18051 +extern const char *vlimit_name[NUM_LIMITS];
18053 +static inline void __vx_acc_cres(struct vx_info *vxi,
18054 + int res, int dir, void *_data, char *_file, int _line)
18056 + if (VXD_RCRES_COND(res))
18057 + vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
18058 + (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
18059 + (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
18060 + (dir > 0) ? "++" : "--", _data, _file, _line);
18065 + __rlim_inc(&vxi->limit, res);
18067 + __rlim_dec(&vxi->limit, res);
18070 +static inline void __vx_add_cres(struct vx_info *vxi,
18071 + int res, int amount, void *_data, char *_file, int _line)
18073 + if (VXD_RCRES_COND(res))
18074 + vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
18075 + (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
18076 + (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
18077 + amount, _data, _file, _line);
18082 + __rlim_add(&vxi->limit, res, amount);
18086 +int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
18088 + int cond = (value > __rlim_rmax(limit, res));
18091 + __rlim_rmax(limit, res) = value;
18096 +int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
18098 + int cond = (value < __rlim_rmin(limit, res));
18101 + __rlim_rmin(limit, res) = value;
18106 +void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
18108 + if (!__vx_cres_adjust_max(limit, res, value))
18109 + __vx_cres_adjust_min(limit, res, value);
18114 + +1 ... no limit hit
18115 + -1 ... over soft limit
18116 + 0 ... over hard limit */
18118 +static inline int __vx_cres_avail(struct vx_info *vxi,
18119 + int res, int num, char *_file, int _line)
18121 + struct _vx_limit *limit;
18124 + if (VXD_RLIMIT_COND(res))
18125 + vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
18126 + (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
18127 + (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
18128 + (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
18129 + (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
18130 + num, _file, _line);
18134 + limit = &vxi->limit;
18135 + value = __rlim_get(limit, res);
18137 + if (!__vx_cres_adjust_max(limit, res, value))
18138 + __vx_cres_adjust_min(limit, res, value);
18143 + if (__rlim_soft(limit, res) == RLIM_INFINITY)
18145 + if (value + num <= __rlim_soft(limit, res))
18148 + if (__rlim_hard(limit, res) == RLIM_INFINITY)
18150 + if (value + num <= __rlim_hard(limit, res))
18153 + __rlim_hit(limit, res);
18158 +static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
18161 +rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
18163 + rlim_t value, sum = 0;
18166 + while ((res = *array++)) {
18167 + value = __rlim_get(limit, res);
18168 + __vx_cres_fixup(limit, res, value);
18175 +rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
18177 + rlim_t value = __vx_cres_array_sum(limit, array + 1);
18178 + int res = *array;
18180 + if (value == __rlim_get(limit, res))
18183 + __rlim_set(limit, res, value);
18184 + /* now adjust min/max */
18185 + if (!__vx_cres_adjust_max(limit, res, value))
18186 + __vx_cres_adjust_min(limit, res, value);
18191 +static inline int __vx_cres_array_avail(struct vx_info *vxi,
18192 + const int *array, int num, char *_file, int _line)
18194 + struct _vx_limit *limit;
18195 + rlim_t value = 0;
18203 + limit = &vxi->limit;
18205 + value = __vx_cres_array_sum(limit, array+1);
18207 + __rlim_set(limit, res, value);
18208 + __vx_cres_fixup(limit, res, value);
18210 + return __vx_cres_avail(vxi, res, num, _file, _line);
18214 +#endif /* __KERNEL__ */
18215 +#endif /* _VX_LIMIT_INT_H */
18216 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/monitor.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/monitor.h
18217 --- linux-2.6.19.1/include/linux/vserver/monitor.h 1970-01-01 01:00:00 +0100
18218 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/monitor.h 2006-11-08 04:57:48 +0100
18220 +#ifndef _VX_MONITOR_H
18221 +#define _VX_MONITOR_H
18229 + VXM_UPDATE = 0x20,
18233 + VXM_RQINFO_1 = 0x24,
18236 + VXM_ACTIVATE = 0x40,
18243 + VXM_MIGRATE = 0x48,
18246 + /* all other bits are flags */
18247 + VXM_SCHED = 0x80,
18250 +struct _vxm_update_1 {
18251 + uint32_t tokens_max;
18252 + uint32_t fill_rate;
18253 + uint32_t interval;
18256 +struct _vxm_update_2 {
18257 + uint32_t tokens_min;
18258 + uint32_t fill_rate;
18259 + uint32_t interval;
18262 +struct _vxm_rqinfo_1 {
18263 + uint16_t running;
18267 + uint32_t idle_tokens;
18270 +struct _vxm_rqinfo_2 {
18271 + uint32_t norm_time;
18272 + uint32_t idle_time;
18273 + uint32_t idle_skip;
18276 +struct _vxm_sched {
18278 + uint32_t norm_time;
18279 + uint32_t idle_time;
18282 +struct _vxm_task {
18287 +struct _vxm_event {
18296 + struct _vxm_task tsk;
18300 +struct _vx_mon_entry {
18304 + struct _vxm_event ev;
18305 + struct _vxm_sched sd;
18306 + struct _vxm_update_1 u1;
18307 + struct _vxm_update_2 u2;
18308 + struct _vxm_rqinfo_1 q1;
18309 + struct _vxm_rqinfo_2 q2;
18314 +#endif /* _VX_MONITOR_H */
18315 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/network.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/network.h
18316 --- linux-2.6.19.1/include/linux/vserver/network.h 1970-01-01 01:00:00 +0100
18317 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/network.h 2006-12-17 05:24:42 +0100
18319 +#ifndef _VX_NETWORK_H
18320 +#define _VX_NETWORK_H
18322 +#include <linux/types.h>
18325 +#define MAX_N_CONTEXT 65535 /* Arbitrary limit */
18327 +#define NB_IPV4ROOT 16
18330 +/* network flags */
18332 +#define NXF_INFO_PRIVATE 0x00000008
18334 +#define NXF_SINGLE_IP 0x00000100
18336 +#define NXF_HIDE_NETIF 0x02000000
18338 +#define NXF_STATE_SETUP (1ULL<<32)
18339 +#define NXF_STATE_ADMIN (1ULL<<34)
18341 +#define NXF_SC_HELPER (1ULL<<36)
18342 +#define NXF_PERSISTENT (1ULL<<38)
18344 +#define NXF_ONE_TIME (0x0005ULL<<32)
18346 +#define NXF_INIT_SET (NXF_STATE_ADMIN)
18349 +/* address types */
18351 +#define NXA_TYPE_IPV4 0x0001
18352 +#define NXA_TYPE_IPV6 0x0002
18354 +#define NXA_MOD_BCAST 0x0100
18355 +#define NXA_MOD_LBACK 0x0200
18357 +#define NXA_TYPE_ANY ((uint16_t)-1)
18359 +#define NXA_TYPE_ADDR 0x0003
18360 +#define NXA_TYPE_MASK 0x0013
18361 +#define NXA_TYPE_RANGE 0x0023
18366 +#include <linux/list.h>
18367 +#include <linux/spinlock.h>
18368 +#include <linux/rcupdate.h>
18369 +#include <asm/atomic.h>
18373 + struct hlist_node nx_hlist; /* linked list of nxinfos */
18374 + nid_t nx_id; /* vnet id */
18375 + atomic_t nx_usecnt; /* usage count */
18376 + atomic_t nx_tasks; /* tasks count */
18377 + int nx_state; /* context state */
18379 + uint64_t nx_flags; /* network flag word */
18380 + uint64_t nx_ncaps; /* network capabilities */
18383 + __be32 ipv4[NB_IPV4ROOT]; /* Process can only bind to these IPs */
18384 + /* The first one is used to connect */
18385 + /* and for bind any service */
18386 + /* The other must be used explicity */
18387 + __be32 mask[NB_IPV4ROOT]; /* Netmask for each ipv4 */
18388 + /* Used to select the proper source */
18389 + /* address for sockets */
18390 + __be32 v4_bcast; /* Broadcast address to receive UDP */
18391 + __be32 v4_lback; /* Loopback address */
18393 + char nx_name[65]; /* network context name */
18397 +/* status flags */
18399 +#define NXS_HASHED 0x0001
18400 +#define NXS_SHUTDOWN 0x0100
18401 +#define NXS_RELEASED 0x8000
18403 +extern struct nx_info *lookup_nx_info(int);
18405 +extern int get_nid_list(int, unsigned int *, int);
18406 +extern int nid_is_hashed(nid_t);
18408 +extern int nx_migrate_task(struct task_struct *, struct nx_info *);
18410 +extern long vs_net_change(struct nx_info *, unsigned int);
18414 +#endif /* __KERNEL__ */
18415 +#else /* _VX_NETWORK_H */
18416 +#warning duplicate inclusion
18417 +#endif /* _VX_NETWORK_H */
18418 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/network_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/network_cmd.h
18419 --- linux-2.6.19.1/include/linux/vserver/network_cmd.h 1970-01-01 01:00:00 +0100
18420 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/network_cmd.h 2006-12-18 05:02:31 +0100
18422 +#ifndef _VX_NETWORK_CMD_H
18423 +#define _VX_NETWORK_CMD_H
18426 +/* vinfo commands */
18428 +#define VCMD_task_nid VC_CMD(VINFO, 2, 0)
18431 +extern int vc_task_nid(uint32_t, void __user *);
18433 +#endif /* __KERNEL__ */
18435 +#define VCMD_nx_info VC_CMD(VINFO, 6, 0)
18437 +struct vcmd_nx_info_v0 {
18439 + /* more to come */
18443 +extern int vc_nx_info(struct nx_info *, void __user *);
18445 +#endif /* __KERNEL__ */
18447 +#include <linux/in.h>
18448 +#include <linux/in6.h>
18450 +#define VCMD_net_create_v0 VC_CMD(VNET, 1, 0)
18451 +#define VCMD_net_create VC_CMD(VNET, 1, 1)
18453 +struct vcmd_net_create {
18454 + uint64_t flagword;
18457 +#define VCMD_net_migrate VC_CMD(NETMIG, 1, 0)
18459 +#define VCMD_net_add VC_CMD(NETALT, 1, 0)
18460 +#define VCMD_net_remove VC_CMD(NETALT, 2, 0)
18462 +struct vcmd_net_addr_v0 {
18465 + struct in_addr ip[4];
18466 + struct in_addr mask[4];
18467 + /* more to come */
18470 +#define VCMD_add_match_ipv4 VC_CMD(NETALT, 4, 0)
18471 +#define VCMD_get_match_ipv4 VC_CMD(NETALT, 5, 0)
18473 +struct vcmd_match_ipv4_v0 {
18478 + struct in_addr ip;
18479 + struct in_addr ip2;
18480 + struct in_addr mask;
18483 +#define VCMD_add_match_ipv6 VC_CMD(NETALT, 6, 0)
18484 +#define VCMD_get_match_ipv6 VC_CMD(NETALT, 7, 0)
18486 +struct vcmd_match_ipv6_v0 {
18491 + struct in6_addr ip;
18492 + struct in6_addr ip2;
18493 + struct in6_addr mask;
18498 +extern int vc_net_create(uint32_t, void __user *);
18499 +extern int vc_net_migrate(struct nx_info *, void __user *);
18501 +extern int vc_net_add(struct nx_info *, void __user *);
18502 +extern int vc_net_remove(struct nx_info *, void __user *);
18504 +extern int vc_add_match_ipv4(struct nx_info *, void __user *);
18505 +extern int vc_get_match_ipv4(struct nx_info *, void __user *);
18507 +extern int vc_add_match_ipv6(struct nx_info *, void __user *);
18508 +extern int vc_get_match_ipv6(struct nx_info *, void __user *);
18510 +#endif /* __KERNEL__ */
18513 +/* flag commands */
18515 +#define VCMD_get_nflags VC_CMD(FLAGS, 5, 0)
18516 +#define VCMD_set_nflags VC_CMD(FLAGS, 6, 0)
18518 +struct vcmd_net_flags_v0 {
18519 + uint64_t flagword;
18524 +extern int vc_get_nflags(struct nx_info *, void __user *);
18525 +extern int vc_set_nflags(struct nx_info *, void __user *);
18527 +#endif /* __KERNEL__ */
18530 +/* network caps commands */
18532 +#define VCMD_get_ncaps VC_CMD(FLAGS, 7, 0)
18533 +#define VCMD_set_ncaps VC_CMD(FLAGS, 8, 0)
18535 +struct vcmd_net_caps_v0 {
18541 +extern int vc_get_ncaps(struct nx_info *, void __user *);
18542 +extern int vc_set_ncaps(struct nx_info *, void __user *);
18544 +#endif /* __KERNEL__ */
18545 +#endif /* _VX_CONTEXT_CMD_H */
18546 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/sched.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched.h
18547 --- linux-2.6.19.1/include/linux/vserver/sched.h 1970-01-01 01:00:00 +0100
18548 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched.h 2006-11-08 04:57:45 +0100
18550 +#ifndef _VX_SCHED_H
18551 +#define _VX_SCHED_H
18558 +void vx_vsi_uptime(struct timespec *, struct timespec *);
18563 +void vx_update_load(struct vx_info *);
18566 +int vx_tokens_recalc(struct _vx_sched_pc *,
18567 + unsigned long *, unsigned long *, int [2]);
18569 +void vx_update_sched_param(struct _vx_sched *sched,
18570 + struct _vx_sched_pc *sched_pc);
18572 +#endif /* __KERNEL__ */
18573 +#else /* _VX_SCHED_H */
18574 +#warning duplicate inclusion
18575 +#endif /* _VX_SCHED_H */
18576 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/sched_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched_cmd.h
18577 --- linux-2.6.19.1/include/linux/vserver/sched_cmd.h 1970-01-01 01:00:00 +0100
18578 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched_cmd.h 2006-11-08 04:57:49 +0100
18580 +#ifndef _VX_SCHED_CMD_H
18581 +#define _VX_SCHED_CMD_H
18584 +/* sched vserver commands */
18586 +#define VCMD_set_sched_v2 VC_CMD(SCHED, 1, 2)
18587 +#define VCMD_set_sched_v3 VC_CMD(SCHED, 1, 3)
18588 +#define VCMD_set_sched VC_CMD(SCHED, 1, 4)
18590 +struct vcmd_set_sched_v2 {
18591 + int32_t fill_rate;
18592 + int32_t interval;
18594 + int32_t tokens_min;
18595 + int32_t tokens_max;
18596 + uint64_t cpu_mask;
18599 +struct vcmd_set_sched_v3 {
18600 + uint32_t set_mask;
18601 + int32_t fill_rate;
18602 + int32_t interval;
18604 + int32_t tokens_min;
18605 + int32_t tokens_max;
18606 + int32_t priority_bias;
18609 +struct vcmd_set_sched_v4 {
18610 + uint32_t set_mask;
18611 + int32_t fill_rate;
18612 + int32_t interval;
18614 + int32_t tokens_min;
18615 + int32_t tokens_max;
18616 + int32_t prio_bias;
18618 + int32_t bucket_id;
18622 +#define VXSM_FILL_RATE 0x0001
18623 +#define VXSM_INTERVAL 0x0002
18624 +#define VXSM_FILL_RATE2 0x0004
18625 +#define VXSM_INTERVAL2 0x0008
18626 +#define VXSM_TOKENS 0x0010
18627 +#define VXSM_TOKENS_MIN 0x0020
18628 +#define VXSM_TOKENS_MAX 0x0040
18629 +#define VXSM_PRIO_BIAS 0x0100
18631 +#define VXSM_IDLE_TIME 0x0200
18632 +#define VXSM_FORCE 0x0400
18634 +#define VXSM_V3_MASK 0x0173
18635 +#define VXSM_SET_MASK 0x01FF
18637 +#define VXSM_CPU_ID 0x1000
18638 +#define VXSM_BUCKET_ID 0x2000
18640 +#define SCHED_KEEP (-2) /* only for v2 */
18644 +#include <linux/compiler.h>
18646 +extern int vc_set_sched_v2(struct vx_info *, void __user *);
18647 +extern int vc_set_sched_v3(struct vx_info *, void __user *);
18648 +extern int vc_set_sched(struct vx_info *, void __user *);
18650 +#endif /* __KERNEL__ */
18651 +#endif /* _VX_SCHED_CMD_H */
18652 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/sched_def.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched_def.h
18653 --- linux-2.6.19.1/include/linux/vserver/sched_def.h 1970-01-01 01:00:00 +0100
18654 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched_def.h 2006-11-08 04:57:49 +0100
18656 +#ifndef _VX_SCHED_DEF_H
18657 +#define _VX_SCHED_DEF_H
18659 +#include <linux/spinlock.h>
18660 +#include <linux/jiffies.h>
18661 +#include <linux/cpumask.h>
18662 +#include <asm/atomic.h>
18663 +#include <asm/param.h>
18666 +/* context sub struct */
18668 +struct _vx_sched {
18669 + spinlock_t tokens_lock; /* lock for token bucket */
18671 + int tokens; /* number of CPU tokens */
18672 + int fill_rate[2]; /* Fill rate: add X tokens... */
18673 + int interval[2]; /* Divisor: per Y jiffies */
18674 + int tokens_min; /* Limit: minimum for unhold */
18675 + int tokens_max; /* Limit: no more than N tokens */
18677 + unsigned update_mask; /* which features should be updated */
18678 + cpumask_t update; /* CPUs which should update */
18680 + int prio_bias; /* bias offset for priority */
18681 + int vavavoom; /* last calculated vavavoom */
18684 +struct _vx_sched_pc {
18685 + int tokens; /* number of CPU tokens */
18686 + int flags; /* bucket flags */
18688 + int fill_rate[2]; /* Fill rate: add X tokens... */
18689 + int interval[2]; /* Divisor: per Y jiffies */
18690 + int tokens_min; /* Limit: minimum for unhold */
18691 + int tokens_max; /* Limit: no more than N tokens */
18693 + unsigned long norm_time; /* last time accounted */
18694 + unsigned long idle_time; /* non linear time for fair sched */
18695 + unsigned long token_time; /* token time for accounting */
18696 + unsigned long onhold; /* jiffies when put on hold */
18698 + uint64_t user_ticks; /* token tick events */
18699 + uint64_t sys_ticks; /* token tick events */
18700 + uint64_t hold_ticks; /* token ticks paused */
18704 +#define VXSF_ONHOLD 0x0001
18705 +#define VXSF_IDLE_TIME 0x0100
18707 +#ifdef CONFIG_VSERVER_DEBUG
18709 +static inline void __dump_vx_sched(struct _vx_sched *sched)
18711 + printk("\t_vx_sched:\n");
18712 + printk("\t tokens: %4d/%4d, %4d/%4d, %4d, %4d\n",
18713 + sched->fill_rate[0], sched->interval[0],
18714 + sched->fill_rate[1], sched->interval[1],
18715 + sched->tokens_min, sched->tokens_max);
18716 + printk("\t priority = %4d, %4d\n",
18717 + sched->prio_bias, sched->vavavoom);
18722 +#endif /* _VX_SCHED_DEF_H */
18723 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/signal.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/signal.h
18724 --- linux-2.6.19.1/include/linux/vserver/signal.h 1970-01-01 01:00:00 +0100
18725 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/signal.h 2006-11-08 04:57:45 +0100
18727 +#ifndef _VX_SIGNAL_H
18728 +#define _VX_SIGNAL_H
18735 +int vx_info_kill(struct vx_info *, int, int);
18737 +#endif /* __KERNEL__ */
18738 +#else /* _VX_SIGNAL_H */
18739 +#warning duplicate inclusion
18740 +#endif /* _VX_SIGNAL_H */
18741 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/signal_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/signal_cmd.h
18742 --- linux-2.6.19.1/include/linux/vserver/signal_cmd.h 1970-01-01 01:00:00 +0100
18743 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/signal_cmd.h 2006-12-05 17:36:09 +0100
18745 +#ifndef _VX_SIGNAL_CMD_H
18746 +#define _VX_SIGNAL_CMD_H
18749 +/* signalling vserver commands */
18751 +#define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0)
18752 +#define VCMD_wait_exit VC_CMD(EVENT, 99, 0)
18754 +struct vcmd_ctx_kill_v0 {
18759 +struct vcmd_wait_exit_v0 {
18760 + int32_t reboot_cmd;
18761 + int32_t exit_code;
18766 +extern int vc_ctx_kill(struct vx_info *, void __user *);
18767 +extern int vc_wait_exit(struct vx_info *, void __user *);
18769 +#endif /* __KERNEL__ */
18771 +/* process alteration commands */
18773 +#define VCMD_get_pflags VC_CMD(PROCALT, 5, 0)
18774 +#define VCMD_set_pflags VC_CMD(PROCALT, 6, 0)
18776 +struct vcmd_pflags_v0 {
18777 + uint32_t flagword;
18783 +extern int vc_get_pflags(uint32_t pid, void __user *);
18784 +extern int vc_set_pflags(uint32_t pid, void __user *);
18786 +#endif /* __KERNEL__ */
18787 +#endif /* _VX_SIGNAL_CMD_H */
18788 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/space.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/space.h
18789 --- linux-2.6.19.1/include/linux/vserver/space.h 1970-01-01 01:00:00 +0100
18790 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/space.h 2006-12-05 18:57:02 +0100
18792 +#ifndef _VX_SPACE_H
18793 +#define _VX_SPACE_H
18796 +#include <linux/types.h>
18800 +int vx_set_space(struct vx_info *vxi, unsigned long mask);
18802 +#else /* _VX_SPACE_H */
18803 +#warning duplicate inclusion
18804 +#endif /* _VX_SPACE_H */
18805 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/space_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/space_cmd.h
18806 --- linux-2.6.19.1/include/linux/vserver/space_cmd.h 1970-01-01 01:00:00 +0100
18807 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/space_cmd.h 2006-12-05 18:14:49 +0100
18809 +#ifndef _VX_SPACE_CMD_H
18810 +#define _VX_SPACE_CMD_H
18813 +#define VCMD_enter_space_v0 VC_CMD(PROCALT, 1, 0)
18814 +#define VCMD_enter_space VC_CMD(PROCALT, 1, 1)
18816 +#define VCMD_set_space_v0 VC_CMD(PROCALT, 3, 0)
18817 +#define VCMD_set_space VC_CMD(PROCALT, 3, 1)
18819 +#define VCMD_get_space_mask VC_CMD(PROCALT, 4, 0)
18822 +struct vcmd_space_mask {
18829 +extern int vc_enter_space(struct vx_info *, void __user *);
18830 +extern int vc_set_space(struct vx_info *, void __user *);
18831 +extern int vc_get_space_mask(struct vx_info *, void __user *);
18833 +#endif /* __KERNEL__ */
18834 +#endif /* _VX_SPACE_CMD_H */
18835 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/switch.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/switch.h
18836 --- linux-2.6.19.1/include/linux/vserver/switch.h 1970-01-01 01:00:00 +0100
18837 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/switch.h 2006-12-09 03:45:16 +0100
18839 +#ifndef _VX_SWITCH_H
18840 +#define _VX_SWITCH_H
18842 +#include <linux/types.h>
18845 +#define VC_CATEGORY(c) (((c) >> 24) & 0x3F)
18846 +#define VC_COMMAND(c) (((c) >> 16) & 0xFF)
18847 +#define VC_VERSION(c) ((c) & 0xFFF)
18849 +#define VC_CMD(c,i,v) ((((VC_CAT_ ## c) & 0x3F) << 24) \
18850 + | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
18854 + Syscall Matrix V2.8
18856 + |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
18857 + |STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | |
18858 + |INFO |SETUP | |MOVE | | | | | |
18859 + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18860 + SYSTEM |VERSION|VSETUP |VHOST | | | | |DEVICE | |
18861 + HOST | 00| 01| 02| 03| 04| 05| | 06| 07|
18862 + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18863 + CPU | |VPROC |PROCALT|PROCMIG|PROCTRL| | |SCHED. | |
18864 + PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15|
18865 + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18866 + MEMORY | | | | | | | |SWAP | |
18867 + | 16| 17| 18| 19| 20| 21| | 22| 23|
18868 + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18869 + NETWORK| |VNET |NETALT |NETMIG |NETCTL | | |SERIAL | |
18870 + | 24| 25| 26| 27| 28| 29| | 30| 31|
18871 + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18872 + DISK | | | | |DLIMIT | | |INODE | |
18873 + VFS | 32| 33| 34| 35| 36| 37| | 38| 39|
18874 + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18875 + OTHER |VSTAT | | | | | | |VINFO | |
18876 + | 40| 41| 42| 43| 44| 45| | 46| 47|
18877 + =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
18878 + SPECIAL|EVENT | | | |FLAGS | | | | |
18879 + | 48| 49| 50| 51| 52| 53| | 54| 55|
18880 + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18881 + SPECIAL|DEBUG | | | |RLIMIT |SYSCALL| | |COMPAT |
18882 + | 56| 57| 58| 59| 60|TEST 61| | 62| 63|
18883 + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18887 +#define VC_CAT_VERSION 0
18889 +#define VC_CAT_VSETUP 1
18890 +#define VC_CAT_VHOST 2
18892 +#define VC_CAT_DEVICE 6
18894 +#define VC_CAT_VPROC 9
18895 +#define VC_CAT_PROCALT 10
18896 +#define VC_CAT_PROCMIG 11
18897 +#define VC_CAT_PROCTRL 12
18899 +#define VC_CAT_SCHED 14
18901 +#define VC_CAT_VNET 25
18902 +#define VC_CAT_NETALT 26
18903 +#define VC_CAT_NETMIG 27
18904 +#define VC_CAT_NETCTRL 28
18906 +#define VC_CAT_DLIMIT 36
18907 +#define VC_CAT_INODE 38
18909 +#define VC_CAT_VSTAT 40
18910 +#define VC_CAT_VINFO 46
18911 +#define VC_CAT_EVENT 48
18913 +#define VC_CAT_FLAGS 52
18914 +#define VC_CAT_DEBUG 56
18915 +#define VC_CAT_RLIMIT 60
18917 +#define VC_CAT_SYSTEST 61
18918 +#define VC_CAT_COMPAT 63
18920 +/* interface version */
18922 +#define VCI_VERSION 0x00020102
18923 +#define VCI_LEGACY_VERSION 0x000100FF
18925 +/* query version */
18927 +#define VCMD_get_version VC_CMD(VERSION, 0, 0)
18928 +#define VCMD_get_vci VC_CMD(VERSION, 1, 0)
18933 +#include <linux/errno.h>
18936 +#else /* __KERNEL__ */
18938 +#endif /* __KERNEL__ */
18940 +#endif /* _VX_SWITCH_H */
18941 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/tag.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/tag.h
18942 --- linux-2.6.19.1/include/linux/vserver/tag.h 1970-01-01 01:00:00 +0100
18943 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/tag.h 2006-12-17 04:19:20 +0100
18949 +#define DX_TAG(in) (IS_TAGGED(in))
18952 +#ifdef CONFIG_DX_TAG_NFSD
18953 +#define DX_TAG_NFSD 1
18955 +#define DX_TAG_NFSD 0
18959 +#ifdef CONFIG_TAGGING_NONE
18961 +#define MAX_UID 0xFFFFFFFF
18962 +#define MAX_GID 0xFFFFFFFF
18964 +#define INOTAG_TAG(cond, uid, gid, tag) (0)
18966 +#define TAGINO_UID(cond, uid, tag) (uid)
18967 +#define TAGINO_GID(cond, gid, tag) (gid)
18972 +#ifdef CONFIG_TAGGING_GID16
18974 +#define MAX_UID 0xFFFFFFFF
18975 +#define MAX_GID 0x0000FFFF
18977 +#define INOTAG_TAG(cond, uid, gid, tag) \
18978 + ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
18980 +#define TAGINO_UID(cond, uid, tag) (uid)
18981 +#define TAGINO_GID(cond, gid, tag) \
18982 + ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
18987 +#ifdef CONFIG_TAGGING_ID24
18989 +#define MAX_UID 0x00FFFFFF
18990 +#define MAX_GID 0x00FFFFFF
18992 +#define INOTAG_TAG(cond, uid, gid, tag) \
18993 + ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
18995 +#define TAGINO_UID(cond, uid, tag) \
18996 + ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
18997 +#define TAGINO_GID(cond, gid, tag) \
18998 + ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
19003 +#ifdef CONFIG_TAGGING_UID16
19005 +#define MAX_UID 0x0000FFFF
19006 +#define MAX_GID 0xFFFFFFFF
19008 +#define INOTAG_TAG(cond, uid, gid, tag) \
19009 + ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
19011 +#define TAGINO_UID(cond, uid, tag) \
19012 + ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
19013 +#define TAGINO_GID(cond, gid, tag) (gid)
19018 +#ifdef CONFIG_TAGGING_INTERN
19020 +#define MAX_UID 0xFFFFFFFF
19021 +#define MAX_GID 0xFFFFFFFF
19023 +#define INOTAG_TAG(cond, uid, gid, tag) \
19024 + ((cond) ? (tag) : 0)
19026 +#define TAGINO_UID(cond, uid, tag) (uid)
19027 +#define TAGINO_GID(cond, gid, tag) (gid)
19032 +#ifdef CONFIG_TAGGING_RUNTIME
19034 +#define MAX_UID 0xFFFFFFFF
19035 +#define MAX_GID 0xFFFFFFFF
19037 +#define INOTAG_TAG(cond, uid, gid, tag) (0)
19039 +#define TAGINO_UID(cond, uid, tag) (uid)
19040 +#define TAGINO_GID(cond, gid, tag) (gid)
19045 +#ifndef CONFIG_TAGGING_NONE
19046 +#define dx_current_fstag(sb) \
19047 + ((sb)->s_flags & MS_TAGGED ? dx_current_tag(): 0)
19049 +#define dx_current_fstag(sb) (0)
19052 +#ifndef CONFIG_TAGGING_INTERN
19053 +#define TAGINO_TAG(cond, tag) (0)
19055 +#define TAGINO_TAG(cond, tag) ((cond) ? (tag) : 0)
19058 +#define INOTAG_UID(cond, uid, gid) \
19059 + ((cond) ? ((uid) & MAX_UID) : (uid))
19060 +#define INOTAG_GID(cond, uid, gid) \
19061 + ((cond) ? ((gid) & MAX_GID) : (gid))
19064 +static inline uid_t dx_map_uid(uid_t uid)
19066 + if ((uid > MAX_UID) && (uid != -1))
19068 + return (uid & MAX_UID);
19071 +static inline gid_t dx_map_gid(gid_t gid)
19073 + if ((gid > MAX_GID) && (gid != -1))
19075 + return (gid & MAX_GID);
19079 +#ifdef CONFIG_PROPAGATE
19081 +int dx_parse_tag(char *string, tag_t *tag, int remove);
19083 +void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
19085 +#define dx_propagate_tag(n,i) __dx_propagate_tag(n,i)
19088 +#define dx_propagate_tag(n,i) do { } while (0)
19091 +#endif /* _DX_TAG_H */
19092 diff -NurpP --minimal linux-2.6.19.1/include/net/af_unix.h linux-2.6.19.1-vs2.3.0.6/include/net/af_unix.h
19093 --- linux-2.6.19.1/include/net/af_unix.h 2006-09-20 16:58:44 +0200
19094 +++ linux-2.6.19.1-vs2.3.0.6/include/net/af_unix.h 2006-12-04 05:06:17 +0100
19096 #include <linux/socket.h>
19097 #include <linux/un.h>
19098 #include <linux/mutex.h>
19099 +#include <linux/vs_base.h>
19100 #include <net/sock.h>
19102 extern void unix_inflight(struct file *fp);
19103 @@ -17,9 +18,9 @@ extern spinlock_t unix_table_lock;
19105 extern atomic_t unix_tot_inflight;
19107 -static inline struct sock *first_unix_socket(int *i)
19108 +static inline struct sock *next_unix_socket_table(int *i)
19110 - for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
19111 + for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
19112 if (!hlist_empty(&unix_socket_table[*i]))
19113 return __sk_head(&unix_socket_table[*i]);
19115 @@ -28,16 +29,19 @@ static inline struct sock *first_unix_so
19117 static inline struct sock *next_unix_socket(int *i, struct sock *s)
19119 - struct sock *next = sk_next(s);
19120 - /* More in this chain? */
19123 - /* Look for next non-empty chain. */
19124 - for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
19125 - if (!hlist_empty(&unix_socket_table[*i]))
19126 - return __sk_head(&unix_socket_table[*i]);
19133 + s = next_unix_socket_table(i);
19134 + } while (s && !nx_check(s->sk_nid, VS_WATCH_P|VS_IDENT));
19138 +static inline struct sock *first_unix_socket(int *i)
19141 + return next_unix_socket(i, NULL);
19144 #define forall_unix_sockets(i, s) \
19145 diff -NurpP --minimal linux-2.6.19.1/include/net/inet_hashtables.h linux-2.6.19.1-vs2.3.0.6/include/net/inet_hashtables.h
19146 --- linux-2.6.19.1/include/net/inet_hashtables.h 2006-11-30 21:19:40 +0100
19147 +++ linux-2.6.19.1-vs2.3.0.6/include/net/inet_hashtables.h 2006-11-08 04:57:42 +0100
19148 @@ -271,6 +271,26 @@ static inline int inet_iif(const struct
19149 return ((struct rtable *)skb->dst)->rt_iif;
19153 + * Check if a given address matches for an inet socket
19155 + * nxi: the socket's nx_info if any
19156 + * addr: to be verified address
19157 + * saddr: socket addresses
19159 +static inline int inet_addr_match (
19160 + struct nx_info *nxi,
19164 + if (addr && (saddr == addr))
19167 + return addr_in_nx_info(nxi, addr);
19172 extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
19173 const __be32 daddr,
19174 const unsigned short hnum,
19175 diff -NurpP --minimal linux-2.6.19.1/include/net/inet_sock.h linux-2.6.19.1-vs2.3.0.6/include/net/inet_sock.h
19176 --- linux-2.6.19.1/include/net/inet_sock.h 2006-11-30 21:19:40 +0100
19177 +++ linux-2.6.19.1-vs2.3.0.6/include/net/inet_sock.h 2006-11-08 04:57:42 +0100
19178 @@ -112,6 +112,7 @@ struct inet_sock {
19179 /* Socket demultiplex comparisons on incoming packets. */
19182 + __be32 rcv_saddr2; /* Second bound ipv4 addr, for ipv4root */
19186 diff -NurpP --minimal linux-2.6.19.1/include/net/inet_timewait_sock.h linux-2.6.19.1-vs2.3.0.6/include/net/inet_timewait_sock.h
19187 --- linux-2.6.19.1/include/net/inet_timewait_sock.h 2006-11-30 21:19:40 +0100
19188 +++ linux-2.6.19.1-vs2.3.0.6/include/net/inet_timewait_sock.h 2006-11-08 04:57:42 +0100
19189 @@ -115,6 +115,10 @@ struct inet_timewait_sock {
19190 #define tw_refcnt __tw_common.skc_refcnt
19191 #define tw_hash __tw_common.skc_hash
19192 #define tw_prot __tw_common.skc_prot
19193 +#define tw_xid __tw_common.skc_xid
19194 +#define tw_vx_info __tw_common.skc_vx_info
19195 +#define tw_nid __tw_common.skc_nid
19196 +#define tw_nx_info __tw_common.skc_nx_info
19197 volatile unsigned char tw_substate;
19198 /* 3 bits hole, try to pack */
19199 unsigned char tw_rcv_wscale;
19200 diff -NurpP --minimal linux-2.6.19.1/include/net/route.h linux-2.6.19.1-vs2.3.0.6/include/net/route.h
19201 --- linux-2.6.19.1/include/net/route.h 2006-11-30 21:19:40 +0100
19202 +++ linux-2.6.19.1-vs2.3.0.6/include/net/route.h 2006-12-17 03:25:02 +0100
19203 @@ -27,12 +27,16 @@
19204 #include <net/dst.h>
19205 #include <net/inetpeer.h>
19206 #include <net/flow.h>
19207 +#include <net/inet_sock.h>
19208 #include <linux/in_route.h>
19209 #include <linux/rtnetlink.h>
19210 #include <linux/route.h>
19211 #include <linux/ip.h>
19212 #include <linux/cache.h>
19213 #include <linux/security.h>
19214 +#include <linux/vs_base.h>
19215 +#include <linux/vs_inet.h>
19216 +#include <linux/in.h>
19219 #warning This file is not supposed to be used outside of kernel.
19220 @@ -144,6 +148,8 @@ static inline char rt_tos2priority(u8 to
19221 return ip_tos2prio[IPTOS_TOS(tos)>>1];
19224 +#include "route_vs.h"
19226 static inline int ip_route_connect(struct rtable **rp, __be32 dst,
19227 __be32 src, u32 tos, int oif, u8 protocol,
19228 __be16 sport, __be16 dport, struct sock *sk)
19229 @@ -158,7 +164,21 @@ static inline int ip_route_connect(struc
19230 .dport = dport } } };
19233 - if (!dst || !src) {
19234 + struct nx_info *nx_info = current->nx_info;
19237 + nx_info = sk->sk_nx_info;
19239 + vxdprintk(VXD_CBIT(net, 4),
19240 + "ip_route_connect(%p) %p,%p;%lx",
19241 + sk, nx_info, sk->sk_socket,
19242 + (sk->sk_socket?sk->sk_socket->flags:0));
19244 + err = ip_find_src(nx_info, rp, &fl);
19248 + if (!fl.fl4_dst || !fl.fl4_src) {
19249 err = __ip_route_output_key(rp, &fl);
19252 diff -NurpP --minimal linux-2.6.19.1/include/net/route_vs.h linux-2.6.19.1-vs2.3.0.6/include/net/route_vs.h
19253 --- linux-2.6.19.1/include/net/route_vs.h 1970-01-01 01:00:00 +0100
19254 +++ linux-2.6.19.1-vs2.3.0.6/include/net/route_vs.h 2006-12-17 03:47:12 +0100
19257 +static inline int ip_find_src(struct nx_info *nxi, struct rtable **rp, struct flowi *fl)
19261 + uint32_t ipv4root;
19266 + ipv4root = nxi->ipv4[0];
19267 + if (ipv4root == 0)
19271 + if (fl->fl4_src == 0) {
19275 + err = __ip_route_output_key(rp, fl);
19277 + fl->fl4_src = ipv4root;
19278 + err = __ip_route_output_key(rp, fl);
19283 + foundsrc = (*rp)->rt_src;
19286 + for (i=0; i<n; i++){
19287 + u32 mask = nxi->mask[i];
19288 + u32 ipv4 = nxi->ipv4[i];
19289 + u32 net4 = ipv4 & mask;
19291 + if (foundsrc == ipv4) {
19292 + fl->fl4_src = ipv4;
19295 + if (!fl->fl4_src && (foundsrc & mask) == net4)
19296 + fl->fl4_src = ipv4;
19299 + if (fl->fl4_src == 0)
19300 + fl->fl4_src = (fl->fl4_dst == IPI_LOOPBACK)
19301 + ? IPI_LOOPBACK : ipv4root;
19303 + for (i=0; i<n; i++) {
19304 + if (nxi->ipv4[i] == fl->fl4_src)
19311 + if (fl->fl4_dst == IPI_LOOPBACK && !nx_check(0, VS_ADMIN))
19312 + fl->fl4_dst = nxi->ipv4[0];
19313 +#ifdef CONFIG_VSERVER_REMAP_SADDR
19314 + if (fl->fl4_src == IPI_LOOPBACK && !nx_check(0, VS_ADMIN))
19315 + fl->fl4_src = nxi->ipv4[0];
19320 diff -NurpP --minimal linux-2.6.19.1/include/net/sock.h linux-2.6.19.1-vs2.3.0.6/include/net/sock.h
19321 --- linux-2.6.19.1/include/net/sock.h 2006-11-30 21:19:41 +0100
19322 +++ linux-2.6.19.1-vs2.3.0.6/include/net/sock.h 2006-11-30 20:55:45 +0100
19323 @@ -118,6 +118,10 @@ struct sock_common {
19324 atomic_t skc_refcnt;
19325 unsigned int skc_hash;
19326 struct proto *skc_prot;
19328 + struct vx_info *skc_vx_info;
19330 + struct nx_info *skc_nx_info;
19334 @@ -194,6 +198,10 @@ struct sock {
19335 #define sk_refcnt __sk_common.skc_refcnt
19336 #define sk_hash __sk_common.skc_hash
19337 #define sk_prot __sk_common.skc_prot
19338 +#define sk_xid __sk_common.skc_xid
19339 +#define sk_vx_info __sk_common.skc_vx_info
19340 +#define sk_nid __sk_common.skc_nid
19341 +#define sk_nx_info __sk_common.skc_nx_info
19342 unsigned char sk_shutdown : 2,
19345 diff -NurpP --minimal linux-2.6.19.1/init/Makefile linux-2.6.19.1-vs2.3.0.6/init/Makefile
19346 --- linux-2.6.19.1/init/Makefile 2006-09-20 16:58:44 +0200
19347 +++ linux-2.6.19.1-vs2.3.0.6/init/Makefile 2006-12-06 21:16:15 +0100
19348 @@ -15,6 +15,7 @@ clean-files := ../include/linux/compile.
19350 # dependencies on generated files need to be listed explicitly
19352 +$(obj)/main.o: include/linux/compile.h
19353 $(obj)/version.o: include/linux/compile.h
19355 # compile.h changes depending on hostname, generation number, etc,
19356 diff -NurpP --minimal linux-2.6.19.1/init/main.c linux-2.6.19.1-vs2.3.0.6/init/main.c
19357 --- linux-2.6.19.1/init/main.c 2006-11-30 21:19:43 +0100
19358 +++ linux-2.6.19.1-vs2.3.0.6/init/main.c 2006-12-06 08:48:35 +0100
19360 #include <linux/buffer_head.h>
19361 #include <linux/debug_locks.h>
19362 #include <linux/lockdep.h>
19363 +#include <linux/utsrelease.h>
19364 +#include <linux/compile.h>
19366 #include <asm/io.h>
19367 #include <asm/bugs.h>
19368 @@ -501,7 +503,7 @@ asmlinkage void __init start_kernel(void
19370 page_address_init();
19371 printk(KERN_NOTICE);
19372 - printk(linux_banner);
19373 + printk(linux_banner, UTS_RELEASE, UTS_VERSION);
19374 setup_arch(&command_line);
19376 setup_per_cpu_areas();
19377 diff -NurpP --minimal linux-2.6.19.1/init/version.c linux-2.6.19.1-vs2.3.0.6/init/version.c
19378 --- linux-2.6.19.1/init/version.c 2006-11-30 21:19:43 +0100
19379 +++ linux-2.6.19.1-vs2.3.0.6/init/version.c 2006-12-06 08:48:35 +0100
19380 @@ -35,5 +35,6 @@ struct uts_namespace init_uts_ns = {
19381 EXPORT_SYMBOL_GPL(init_uts_ns);
19383 const char linux_banner[] =
19384 - "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
19385 - LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
19386 + "Linux version %s (" LINUX_COMPILE_BY "@"
19387 + LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") %s\n";
19389 diff -NurpP --minimal linux-2.6.19.1/ipc/mqueue.c linux-2.6.19.1-vs2.3.0.6/ipc/mqueue.c
19390 --- linux-2.6.19.1/ipc/mqueue.c 2006-11-30 21:19:43 +0100
19391 +++ linux-2.6.19.1-vs2.3.0.6/ipc/mqueue.c 2006-11-08 04:57:52 +0100
19393 #include <linux/audit.h>
19394 #include <linux/signal.h>
19395 #include <linux/mutex.h>
19396 +#include <linux/vs_context.h>
19397 +#include <linux/vs_limit.h>
19399 #include <net/sock.h>
19401 @@ -151,17 +153,20 @@ static struct inode *mqueue_get_inode(st
19402 spin_lock(&mq_lock);
19403 if (u->mq_bytes + mq_bytes < u->mq_bytes ||
19404 u->mq_bytes + mq_bytes >
19405 - p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
19406 + p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur ||
19407 + !vx_ipcmsg_avail(p->vx_info, mq_bytes)) {
19408 spin_unlock(&mq_lock);
19411 u->mq_bytes += mq_bytes;
19412 + vx_ipcmsg_add(p->vx_info, u, mq_bytes);
19413 spin_unlock(&mq_lock);
19415 info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
19416 if (!info->messages) {
19417 spin_lock(&mq_lock);
19418 u->mq_bytes -= mq_bytes;
19419 + vx_ipcmsg_sub(p->vx_info, u, mq_bytes);
19420 spin_unlock(&mq_lock);
19423 @@ -259,10 +264,14 @@ static void mqueue_delete_inode(struct i
19424 (info->attr.mq_maxmsg * info->attr.mq_msgsize));
19427 + struct vx_info *vxi = lookup_vx_info(user->xid);
19429 spin_lock(&mq_lock);
19430 user->mq_bytes -= mq_bytes;
19431 + vx_ipcmsg_sub(vxi, user, mq_bytes);
19433 spin_unlock(&mq_lock);
19434 + put_vx_info(vxi);
19438 @@ -747,7 +756,7 @@ asmlinkage long sys_mq_unlink(const char
19440 atomic_inc(&inode->i_count);
19442 - err = vfs_unlink(dentry->d_parent->d_inode, dentry);
19443 + err = vfs_unlink(dentry->d_parent->d_inode, dentry, NULL);
19447 diff -NurpP --minimal linux-2.6.19.1/ipc/msg.c linux-2.6.19.1-vs2.3.0.6/ipc/msg.c
19448 --- linux-2.6.19.1/ipc/msg.c 2006-11-30 21:19:43 +0100
19449 +++ linux-2.6.19.1-vs2.3.0.6/ipc/msg.c 2006-11-30 18:53:18 +0100
19451 #include <linux/seq_file.h>
19452 #include <linux/mutex.h>
19453 #include <linux/nsproxy.h>
19454 +#include <linux/vs_base.h>
19456 #include <asm/current.h>
19457 #include <asm/uaccess.h>
19458 @@ -149,6 +150,7 @@ static int newque (struct ipc_namespace
19460 msq->q_perm.mode = msgflg & S_IRWXUGO;
19461 msq->q_perm.key = key;
19462 + msq->q_perm.xid = vx_current_xid();
19464 msq->q_perm.security = NULL;
19465 retval = security_msg_queue_alloc(msq);
19466 @@ -903,6 +905,9 @@ static int sysvipc_msg_proc_show(struct
19468 struct msg_queue *msq = it;
19470 + if (!vx_check(msq->q_perm.xid, VS_WATCH_P|VS_IDENT))
19473 return seq_printf(s,
19474 "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
19476 diff -NurpP --minimal linux-2.6.19.1/ipc/sem.c linux-2.6.19.1-vs2.3.0.6/ipc/sem.c
19477 --- linux-2.6.19.1/ipc/sem.c 2006-11-30 21:19:43 +0100
19478 +++ linux-2.6.19.1-vs2.3.0.6/ipc/sem.c 2006-11-30 18:53:18 +0100
19480 #include <linux/seq_file.h>
19481 #include <linux/mutex.h>
19482 #include <linux/nsproxy.h>
19483 +#include <linux/vs_base.h>
19484 +#include <linux/vs_limit.h>
19486 #include <asm/uaccess.h>
19488 @@ -230,6 +232,7 @@ static int newary (struct ipc_namespace
19490 sma->sem_perm.mode = (semflg & S_IRWXUGO);
19491 sma->sem_perm.key = key;
19492 + sma->sem_perm.xid = vx_current_xid();
19494 sma->sem_perm.security = NULL;
19495 retval = security_sem_alloc(sma);
19496 @@ -245,6 +248,9 @@ static int newary (struct ipc_namespace
19499 ns->used_sems += nsems;
19500 + /* FIXME: obsoleted? */
19501 + vx_semary_inc(sma);
19502 + vx_nsems_add(sma, nsems);
19504 sma->sem_id = sem_buildid(ns, id, sma->sem_perm.seq);
19505 sma->sem_base = (struct sem *) &sma[1];
19506 @@ -526,6 +532,9 @@ static void freeary (struct ipc_namespac
19509 ns->used_sems -= sma->sem_nsems;
19510 + /* FIXME: obsoleted? */
19511 + vx_nsems_sub(sma, sma->sem_nsems);
19512 + vx_semary_dec(sma);
19513 size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
19514 security_sem_free(sma);
19515 ipc_rcu_putref(sma);
19516 @@ -1403,6 +1412,9 @@ static int sysvipc_sem_proc_show(struct
19518 struct sem_array *sma = it;
19520 + if (!vx_check(sma->sem_perm.xid, VS_WATCH_P|VS_IDENT))
19523 return seq_printf(s,
19524 "%10d %10d %4o %10lu %5u %5u %5u %5u %10lu %10lu\n",
19526 diff -NurpP --minimal linux-2.6.19.1/ipc/shm.c linux-2.6.19.1-vs2.3.0.6/ipc/shm.c
19527 --- linux-2.6.19.1/ipc/shm.c 2006-11-30 21:19:43 +0100
19528 +++ linux-2.6.19.1-vs2.3.0.6/ipc/shm.c 2006-11-30 18:53:18 +0100
19530 #include <linux/seq_file.h>
19531 #include <linux/mutex.h>
19532 #include <linux/nsproxy.h>
19533 +#include <linux/vs_context.h>
19534 +#include <linux/vs_limit.h>
19536 #include <asm/uaccess.h>
19538 @@ -181,7 +183,12 @@ static void shm_open(struct vm_area_stru
19540 static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
19542 - ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
19543 + struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
19544 + int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
19546 + vx_ipcshm_sub(vxi, shp, numpages);
19547 + ns->shm_tot -= numpages;
19549 shm_rmid(ns, shp->id);
19551 if (!is_file_hugepages(shp->shm_file))
19552 @@ -191,6 +198,7 @@ static void shm_destroy(struct ipc_names
19554 fput (shp->shm_file);
19555 security_shm_free(shp);
19556 + put_vx_info(vxi);
19557 ipc_rcu_putref(shp);
19560 @@ -282,11 +290,15 @@ static int newseg (struct ipc_namespace
19561 if (ns->shm_tot + numpages >= ns->shm_ctlall)
19564 + if (!vx_ipcshm_avail(current->vx_info, numpages))
19567 shp = ipc_rcu_alloc(sizeof(*shp));
19571 shp->shm_perm.key = key;
19572 + shp->shm_perm.xid = vx_current_xid();
19573 shp->shm_perm.mode = (shmflg & S_IRWXUGO);
19574 shp->mlock_user = NULL;
19576 @@ -339,6 +351,7 @@ static int newseg (struct ipc_namespace
19577 file->f_op = &shm_file_operations;
19579 ns->shm_tot += numpages;
19580 + vx_ipcshm_add(current->vx_info, key, numpages);
19584 @@ -993,6 +1006,9 @@ static int sysvipc_shm_proc_show(struct
19585 #define SMALL_STRING "%10d %10d %4o %10u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
19586 #define BIG_STRING "%10d %10d %4o %21u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
19588 + if (!vx_check(shp->shm_perm.xid, VS_WATCH_P|VS_IDENT))
19591 if (sizeof(size_t) <= sizeof(int))
19592 format = SMALL_STRING;
19594 diff -NurpP --minimal linux-2.6.19.1/ipc/util.c linux-2.6.19.1-vs2.3.0.6/ipc/util.c
19595 --- linux-2.6.19.1/ipc/util.c 2006-11-30 21:19:43 +0100
19596 +++ linux-2.6.19.1-vs2.3.0.6/ipc/util.c 2006-11-30 18:53:18 +0100
19598 #include <linux/proc_fs.h>
19599 #include <linux/audit.h>
19600 #include <linux/nsproxy.h>
19601 +#include <linux/vs_base.h>
19603 #include <asm/unistd.h>
19605 @@ -261,7 +262,9 @@ int ipc_findkey(struct ipc_ids* ids, key
19607 for (id = 0; id <= max_id; id++) {
19608 p = ids->entries->p[id];
19612 + if (!vx_check(p->xid, VS_WATCH_P|VS_IDENT))
19616 @@ -574,6 +577,9 @@ int ipcperms (struct kern_ipc_perm *ipcp
19618 if (unlikely((err = audit_ipc_obj(ipcp))))
19621 + if (!vx_check(ipcp->xid, VS_WATCH_P|VS_IDENT)) /* maybe just VS_IDENT? */
19623 requested_mode = (flag >> 6) | (flag >> 3) | flag;
19624 granted_mode = ipcp->mode;
19625 if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
19626 diff -NurpP --minimal linux-2.6.19.1/kernel/Makefile linux-2.6.19.1-vs2.3.0.6/kernel/Makefile
19627 --- linux-2.6.19.1/kernel/Makefile 2006-11-30 21:19:43 +0100
19628 +++ linux-2.6.19.1-vs2.3.0.6/kernel/Makefile 2006-11-08 23:23:13 +0100
19629 @@ -10,6 +10,8 @@ obj-y = sched.o fork.o exec_domain.o
19630 kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
19631 hrtimer.o rwsem.o latency.o nsproxy.o srcu.o
19635 obj-$(CONFIG_STACKTRACE) += stacktrace.o
19637 obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
19638 diff -NurpP --minimal linux-2.6.19.1/kernel/capability.c linux-2.6.19.1-vs2.3.0.6/kernel/capability.c
19639 --- linux-2.6.19.1/kernel/capability.c 2006-11-30 21:19:43 +0100
19640 +++ linux-2.6.19.1-vs2.3.0.6/kernel/capability.c 2006-11-30 19:37:57 +0100
19642 #include <linux/module.h>
19643 #include <linux/security.h>
19644 #include <linux/syscalls.h>
19645 +#include <linux/vs_context.h>
19646 #include <asm/uaccess.h>
19648 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
19649 @@ -244,8 +245,12 @@ int __capable(struct task_struct *t, int
19651 EXPORT_SYMBOL(__capable);
19653 +#include <linux/vserver/base.h>
19654 int capable(int cap)
19656 + /* here for now so we don't require task locking */
19657 + if (vs_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap))
19659 return __capable(current, cap);
19661 EXPORT_SYMBOL(capable);
19662 diff -NurpP --minimal linux-2.6.19.1/kernel/compat.c linux-2.6.19.1-vs2.3.0.6/kernel/compat.c
19663 --- linux-2.6.19.1/kernel/compat.c 2006-11-30 21:19:43 +0100
19664 +++ linux-2.6.19.1-vs2.3.0.6/kernel/compat.c 2006-11-08 21:52:09 +0100
19665 @@ -846,7 +846,7 @@ asmlinkage long compat_sys_time(compat_t
19669 - do_gettimeofday(&tv);
19670 + vx_gettimeofday(&tv);
19674 @@ -870,7 +870,7 @@ asmlinkage long compat_sys_stime(compat_
19678 - do_settimeofday(&tv);
19679 + vx_settimeofday(&tv);
19683 diff -NurpP --minimal linux-2.6.19.1/kernel/exit.c linux-2.6.19.1-vs2.3.0.6/kernel/exit.c
19684 --- linux-2.6.19.1/kernel/exit.c 2006-11-30 21:19:43 +0100
19685 +++ linux-2.6.19.1-vs2.3.0.6/kernel/exit.c 2006-11-08 04:57:53 +0100
19687 #include <linux/audit.h> /* for audit_free() */
19688 #include <linux/resource.h>
19689 #include <linux/blkdev.h>
19690 +#include <linux/vs_limit.h>
19691 +#include <linux/vs_context.h>
19692 +#include <linux/vs_network.h>
19694 #include <asm/uaccess.h>
19695 #include <asm/unistd.h>
19696 @@ -437,9 +440,11 @@ static void close_files(struct files_str
19697 struct file * file = xchg(&fdt->fd[i], NULL);
19699 filp_close(file, files);
19700 + vx_openfd_dec(i);
19708 @@ -592,6 +597,11 @@ static void exit_mm(struct task_struct *
19710 choose_new_parent(struct task_struct *p, struct task_struct *reaper)
19712 + /* check for reaper context */
19713 + vxwprintk((p->xid != reaper->xid) && (reaper != child_reaper),
19714 + "rogue reaper: %p[%d,#%u] <> %p[%d,#%u]",
19715 + p, p->pid, p->xid, reaper, reaper->pid, reaper->xid);
19718 * Make sure we're not reparenting to ourselves and that
19719 * the parent is not a zombie.
19720 @@ -674,7 +684,7 @@ forget_original_parent(struct task_struc
19722 reaper = next_thread(reaper);
19723 if (reaper == father) {
19724 - reaper = child_reaper;
19725 + reaper = vx_child_reaper(father);
19728 } while (reaper->exit_state);
19729 @@ -698,7 +708,7 @@ forget_original_parent(struct task_struc
19731 if (father == p->real_parent) {
19732 /* reparent with a reaper, real father it's us */
19733 - choose_new_parent(p, reaper);
19734 + choose_new_parent(p, vx_child_reaper(p));
19735 reparent_thread(p, father, 0);
19737 /* reparent ptraced task to its real parent */
19738 @@ -934,6 +944,8 @@ fastcall NORET_TYPE void do_exit(long co
19740 tsk->exit_code = code;
19741 proc_exit_connector(tsk);
19742 + /* needs to stay before exit_notify() */
19743 + exit_vx_info_early(tsk, code);
19745 exit_task_namespaces(tsk);
19747 @@ -959,6 +971,10 @@ fastcall NORET_TYPE void do_exit(long co
19748 if (tsk->splice_pipe)
19749 __free_pipe_info(tsk->splice_pipe);
19751 + /* needs to stay after exit_notify() */
19752 + exit_vx_info(tsk, code);
19753 + exit_nx_info(tsk);
19756 /* causes final put_task_struct in finish_task_switch(). */
19757 tsk->state = TASK_DEAD;
19758 diff -NurpP --minimal linux-2.6.19.1/kernel/fork.c linux-2.6.19.1-vs2.3.0.6/kernel/fork.c
19759 --- linux-2.6.19.1/kernel/fork.c 2006-11-30 21:19:43 +0100
19760 +++ linux-2.6.19.1-vs2.3.0.6/kernel/fork.c 2006-11-30 20:55:45 +0100
19762 #include <linux/delayacct.h>
19763 #include <linux/taskstats_kern.h>
19764 #include <linux/random.h>
19765 +#include <linux/vs_context.h>
19766 +#include <linux/vs_network.h>
19767 +#include <linux/vs_limit.h>
19768 +#include <linux/vs_memory.h>
19770 #include <asm/pgtable.h>
19771 #include <asm/pgalloc.h>
19772 @@ -107,6 +111,8 @@ void free_task(struct task_struct *tsk)
19774 free_thread_info(tsk->thread_info);
19775 rt_mutex_debug_task_free(tsk);
19776 + clr_vx_info(&tsk->vx_info);
19777 + clr_nx_info(&tsk->nx_info);
19778 free_task_struct(tsk);
19780 EXPORT_SYMBOL(free_task);
19781 @@ -214,6 +220,8 @@ static inline int dup_mmap(struct mm_str
19782 mm->free_area_cache = oldmm->mmap_base;
19783 mm->cached_hole_size = ~0UL;
19785 + __set_mm_counter(mm, file_rss, 0);
19786 + __set_mm_counter(mm, anon_rss, 0);
19787 cpus_clear(mm->cpu_vm_mask);
19788 mm->mm_rb = RB_ROOT;
19789 rb_link = &mm->mm_rb.rb_node;
19790 @@ -225,7 +233,7 @@ static inline int dup_mmap(struct mm_str
19792 if (mpnt->vm_flags & VM_DONTCOPY) {
19793 long pages = vma_pages(mpnt);
19794 - mm->total_vm -= pages;
19795 + vx_vmpages_sub(mm, pages);
19796 vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
19799 @@ -332,8 +340,6 @@ static struct mm_struct * mm_init(struct
19800 INIT_LIST_HEAD(&mm->mmlist);
19801 mm->core_waiters = 0;
19803 - set_mm_counter(mm, file_rss, 0);
19804 - set_mm_counter(mm, anon_rss, 0);
19805 spin_lock_init(&mm->page_table_lock);
19806 rwlock_init(&mm->ioctx_list_lock);
19807 mm->ioctx_list = NULL;
19808 @@ -342,6 +348,7 @@ static struct mm_struct * mm_init(struct
19810 if (likely(!mm_alloc_pgd(mm))) {
19812 + set_vx_info(&mm->mm_vx_info, current->vx_info);
19816 @@ -373,6 +380,7 @@ void fastcall __mmdrop(struct mm_struct
19817 BUG_ON(mm == &init_mm);
19819 destroy_context(mm);
19820 + clr_vx_info(&mm->mm_vx_info);
19824 @@ -478,6 +486,7 @@ static struct mm_struct *dup_mm(struct t
19827 memcpy(mm, oldmm, sizeof(*mm));
19828 + mm->mm_vx_info = NULL;
19832 @@ -505,6 +514,7 @@ fail_nocontext:
19833 * If init_new_context() failed, we cannot use mmput() to free the mm
19834 * because it calls destroy_context()
19836 + clr_vx_info(&mm->mm_vx_info);
19840 @@ -700,6 +710,8 @@ static struct files_struct *dup_fd(struc
19841 struct file *f = *old_fds++;
19844 + /* FIXME: sum it first for check and performance */
19845 + vx_openfd_inc(open_files - i);
19848 * The fd may be claimed in the fd bitmap but not yet
19849 @@ -955,6 +967,8 @@ static struct task_struct *copy_process(
19852 struct task_struct *p = NULL;
19853 + struct vx_info *vxi;
19854 + struct nx_info *nxi;
19856 if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
19857 return ERR_PTR(-EINVAL);
19858 @@ -989,12 +1003,30 @@ static struct task_struct *copy_process(
19859 DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
19860 DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
19862 + init_vx_info(&p->vx_info, current->vx_info);
19863 + init_nx_info(&p->nx_info, current->nx_info);
19865 + /* check vserver memory */
19866 + if (p->mm && !(clone_flags & CLONE_VM)) {
19867 + if (vx_vmpages_avail(p->mm, p->mm->total_vm))
19868 + vx_pages_add(p->vx_info, RLIMIT_AS, p->mm->total_vm);
19870 + goto bad_fork_free;
19872 + if (p->mm && vx_flags(VXF_FORK_RSS, 0)) {
19873 + if (!vx_rss_avail(p->mm, get_mm_counter(p->mm, file_rss)))
19874 + goto bad_fork_cleanup_vm;
19878 + if (!vx_nproc_avail(1))
19879 + goto bad_fork_cleanup_vm;
19881 if (atomic_read(&p->user->processes) >=
19882 p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
19883 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
19884 p->user != &root_user)
19885 - goto bad_fork_free;
19886 + goto bad_fork_cleanup_vm;
19889 atomic_inc(&p->user->__count);
19890 @@ -1256,6 +1288,18 @@ static struct task_struct *copy_process(
19893 spin_unlock(¤t->sighand->siglock);
19895 + /* p is copy of current */
19896 + vxi = p->vx_info;
19898 + claim_vx_info(vxi, p);
19899 + atomic_inc(&vxi->cvirt.nr_threads);
19900 + atomic_inc(&vxi->cvirt.total_forks);
19903 + nxi = p->nx_info;
19905 + claim_nx_info(nxi, p);
19906 write_unlock_irq(&tasklist_lock);
19907 proc_fork_connector(p);
19909 @@ -1297,6 +1341,9 @@ bad_fork_cleanup_count:
19910 put_group_info(p->group_info);
19911 atomic_dec(&p->user->processes);
19913 +bad_fork_cleanup_vm:
19914 + if (p->mm && !(clone_flags & CLONE_VM))
19915 + vx_pages_sub(p->vx_info, RLIMIT_AS, p->mm->total_vm);
19919 @@ -1357,6 +1404,19 @@ long do_fork(unsigned long clone_flags,
19924 + /* kernel threads are host only */
19925 + if ((clone_flags & CLONE_KTHREAD) && !vx_check(0, VS_ADMIN)) {
19926 + vxwprintk(1, "xid=%d tried to spawn a kernel thread.",
19927 + vx_current_xid());
19932 + /* fake ipc/uts on namespace */
19933 + if (clone_flags & CLONE_NEWNS)
19934 + clone_flags |= CLONE_NEWUTS|CLONE_NEWIPC;
19937 if (unlikely(current->ptrace)) {
19938 trace = fork_traceflag (clone_flags);
19939 diff -NurpP --minimal linux-2.6.19.1/kernel/kthread.c linux-2.6.19.1-vs2.3.0.6/kernel/kthread.c
19940 --- linux-2.6.19.1/kernel/kthread.c 2006-09-20 16:58:44 +0200
19941 +++ linux-2.6.19.1-vs2.3.0.6/kernel/kthread.c 2006-11-08 04:57:52 +0100
19942 @@ -123,7 +123,7 @@ static void keventd_create_kthread(void
19944 wait_for_completion(&create->started);
19945 read_lock(&tasklist_lock);
19946 - create->result = find_task_by_pid(pid);
19947 + create->result = find_task_by_real_pid(pid);
19948 read_unlock(&tasklist_lock);
19950 complete(&create->done);
19951 diff -NurpP --minimal linux-2.6.19.1/kernel/nsproxy.c linux-2.6.19.1-vs2.3.0.6/kernel/nsproxy.c
19952 --- linux-2.6.19.1/kernel/nsproxy.c 2006-11-30 21:19:43 +0100
19953 +++ linux-2.6.19.1-vs2.3.0.6/kernel/nsproxy.c 2006-11-14 02:14:48 +0100
19956 struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
19958 -static inline void get_nsproxy(struct nsproxy *ns)
19960 - atomic_inc(&ns->count);
19963 void get_task_namespaces(struct task_struct *tsk)
19965 struct nsproxy *ns = tsk->nsproxy;
19966 diff -NurpP --minimal linux-2.6.19.1/kernel/pid.c linux-2.6.19.1-vs2.3.0.6/kernel/pid.c
19967 --- linux-2.6.19.1/kernel/pid.c 2006-11-30 21:19:43 +0100
19968 +++ linux-2.6.19.1-vs2.3.0.6/kernel/pid.c 2006-12-04 01:47:02 +0100
19970 #include <linux/bootmem.h>
19971 #include <linux/hash.h>
19972 #include <linux/pspace.h>
19973 +#include <linux/vs_pid.h>
19975 #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
19976 static struct hlist_head *pid_hash;
19977 @@ -299,6 +300,10 @@ struct task_struct * fastcall pid_task(s
19979 struct task_struct *find_task_by_pid_type(int type, int nr)
19981 + if (type == PIDTYPE_PID)
19982 + nr = vx_rmap_pid(nr);
19983 + else if (type == PIDTYPE_REALPID)
19984 + type = PIDTYPE_PID;
19985 return pid_task(find_pid(nr), type);
19988 diff -NurpP --minimal linux-2.6.19.1/kernel/posix-timers.c linux-2.6.19.1-vs2.3.0.6/kernel/posix-timers.c
19989 --- linux-2.6.19.1/kernel/posix-timers.c 2006-11-30 21:19:43 +0100
19990 +++ linux-2.6.19.1-vs2.3.0.6/kernel/posix-timers.c 2006-11-08 04:57:52 +0100
19992 #include <linux/wait.h>
19993 #include <linux/workqueue.h>
19994 #include <linux/module.h>
19995 +#include <linux/vs_context.h>
19998 * Management arrays for POSIX timers. Timers are kept in slab memory
19999 @@ -298,6 +299,10 @@ void do_schedule_next_timer(struct sigin
20001 int posix_timer_event(struct k_itimer *timr,int si_private)
20003 + struct vx_info_save vxis;
20006 + enter_vx_info(task_get_vx_info(timr->it_process), &vxis);
20007 memset(&timr->sigq->info, 0, sizeof(siginfo_t));
20008 timr->sigq->info.si_sys_private = si_private;
20009 /* Send signal to the process that owns this timer.*/
20010 @@ -310,11 +315,11 @@ int posix_timer_event(struct k_itimer *t
20012 if (timr->it_sigev_notify & SIGEV_THREAD_ID) {
20013 struct task_struct *leader;
20014 - int ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
20015 - timr->it_process);
20017 + ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
20018 + timr->it_process);
20019 if (likely(ret >= 0))
20023 timr->it_sigev_notify = SIGEV_SIGNAL;
20024 leader = timr->it_process->group_leader;
20025 @@ -322,8 +327,12 @@ int posix_timer_event(struct k_itimer *t
20026 timr->it_process = leader;
20029 - return send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
20030 - timr->it_process);
20031 + ret = send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
20032 + timr->it_process);
20034 + leave_vx_info(&vxis);
20035 + put_vx_info(vxis.vxi);
20038 EXPORT_SYMBOL_GPL(posix_timer_event);
20040 @@ -372,7 +381,7 @@ static struct task_struct * good_sigeven
20041 struct task_struct *rtn = current->group_leader;
20043 if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
20044 - (!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
20045 + (!(rtn = find_task_by_real_pid(event->sigev_notify_thread_id)) ||
20046 rtn->tgid != current->tgid ||
20047 (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
20049 diff -NurpP --minimal linux-2.6.19.1/kernel/printk.c linux-2.6.19.1-vs2.3.0.6/kernel/printk.c
20050 --- linux-2.6.19.1/kernel/printk.c 2006-11-30 21:19:44 +0100
20051 +++ linux-2.6.19.1-vs2.3.0.6/kernel/printk.c 2006-11-30 19:14:49 +0100
20053 #include <linux/bootmem.h>
20054 #include <linux/syscalls.h>
20055 #include <linux/jiffies.h>
20056 +#include <linux/vs_cvirt.h>
20058 #include <asm/uaccess.h>
20060 @@ -185,18 +186,13 @@ int do_syslog(int type, char __user *buf
20061 unsigned long i, j, limit, count;
20067 error = security_syslog(type);
20072 - case 0: /* Close log */
20074 - case 1: /* Open log */
20076 - case 2: /* Read from log */
20077 + if ((type >= 2) && (type <= 4)) {
20079 if (!buf || len < 0)
20081 @@ -207,6 +203,16 @@ int do_syslog(int type, char __user *buf
20086 + if (!vx_check(0, VS_ADMIN|VS_WATCH))
20087 + return vx_do_syslog(type, buf, len);
20090 + case 0: /* Close log */
20092 + case 1: /* Open log */
20094 + case 2: /* Read from log */
20095 error = wait_event_interruptible(log_wait,
20096 (log_start - log_end));
20098 @@ -231,16 +237,6 @@ int do_syslog(int type, char __user *buf
20101 case 3: /* Read last kernel messages */
20103 - if (!buf || len < 0)
20108 - if (!access_ok(VERIFY_WRITE, buf, len)) {
20113 if (count > log_buf_len)
20114 count = log_buf_len;
20115 diff -NurpP --minimal linux-2.6.19.1/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/kernel/ptrace.c
20116 --- linux-2.6.19.1/kernel/ptrace.c 2006-11-30 21:19:44 +0100
20117 +++ linux-2.6.19.1-vs2.3.0.6/kernel/ptrace.c 2006-11-30 19:38:18 +0100
20119 #include <linux/ptrace.h>
20120 #include <linux/security.h>
20121 #include <linux/signal.h>
20122 +#include <linux/vs_context.h>
20124 #include <asm/pgtable.h>
20125 #include <asm/uaccess.h>
20126 @@ -144,6 +145,11 @@ static int may_attach(struct task_struct
20127 dumpable = task->mm->dumpable;
20128 if (!dumpable && !capable(CAP_SYS_PTRACE))
20130 + if (!vx_check(task->xid, VS_ADMIN_P|VS_IDENT))
20132 + if (!vx_check(task->xid, VS_IDENT) &&
20133 + !task_vx_flags(task, VXF_STATE_ADMIN, 0))
20136 return security_ptrace(current, task);
20138 @@ -468,6 +474,10 @@ asmlinkage long sys_ptrace(long request,
20143 + if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT))
20144 + goto out_put_task_struct;
20146 if (request == PTRACE_ATTACH) {
20147 ret = ptrace_attach(child);
20148 goto out_put_task_struct;
20149 diff -NurpP --minimal linux-2.6.19.1/kernel/sched.c linux-2.6.19.1-vs2.3.0.6/kernel/sched.c
20150 --- linux-2.6.19.1/kernel/sched.c 2006-11-30 21:19:44 +0100
20151 +++ linux-2.6.19.1-vs2.3.0.6/kernel/sched.c 2006-11-30 18:53:18 +0100
20153 #include <asm/tlb.h>
20155 #include <asm/unistd.h>
20156 +#include <linux/vs_sched.h>
20157 +#include <linux/vs_cvirt.h>
20160 * Convert user-nice values [ -20 ... 0 ... 19 ]
20161 @@ -243,6 +245,16 @@ struct rq {
20162 struct task_struct *migration_thread;
20163 struct list_head migration_queue;
20165 + unsigned long norm_time;
20166 + unsigned long idle_time;
20167 +#ifdef CONFIG_VSERVER_IDLETIME
20170 +#ifdef CONFIG_VSERVER_HARDCPU
20171 + struct list_head hold_queue;
20172 + unsigned long nr_onhold;
20176 #ifdef CONFIG_SCHEDSTATS
20177 /* latency stats */
20178 @@ -672,6 +684,7 @@ sched_info_switch(struct task_struct *pr
20180 static void dequeue_task(struct task_struct *p, struct prio_array *array)
20182 + BUG_ON(p->state & TASK_ONHOLD);
20183 array->nr_active--;
20184 list_del(&p->run_list);
20185 if (list_empty(array->queue + p->prio))
20186 @@ -680,6 +693,7 @@ static void dequeue_task(struct task_str
20188 static void enqueue_task(struct task_struct *p, struct prio_array *array)
20190 + BUG_ON(p->state & TASK_ONHOLD);
20191 sched_info_queued(p);
20192 list_add_tail(&p->run_list, array->queue + p->prio);
20193 __set_bit(p->prio, array->bitmap);
20194 @@ -693,12 +707,14 @@ static void enqueue_task(struct task_str
20196 static void requeue_task(struct task_struct *p, struct prio_array *array)
20198 + BUG_ON(p->state & TASK_ONHOLD);
20199 list_move_tail(&p->run_list, array->queue + p->prio);
20203 enqueue_task_head(struct task_struct *p, struct prio_array *array)
20205 + BUG_ON(p->state & TASK_ONHOLD);
20206 list_add(&p->run_list, array->queue + p->prio);
20207 __set_bit(p->prio, array->bitmap);
20208 array->nr_active++;
20209 @@ -727,6 +743,10 @@ static inline int __normal_prio(struct t
20210 bonus = CURRENT_BONUS(p) - MAX_BONUS / 2;
20212 prio = p->static_prio - bonus;
20214 + /* adjust effective priority */
20215 + prio = vx_adjust_prio(p, prio, MAX_USER_PRIO);
20217 if (prio < MAX_RT_PRIO)
20218 prio = MAX_RT_PRIO;
20219 if (prio > MAX_PRIO-1)
20220 @@ -836,6 +856,9 @@ static int effective_prio(struct task_st
20224 +#include "sched_mon.h"
20228 * __activate_task - move a task to the runqueue.
20230 @@ -845,6 +868,7 @@ static void __activate_task(struct task_
20233 target = rq->expired;
20234 + vxm_activate_task(p, rq);
20235 enqueue_task(p, target);
20236 inc_nr_running(p, rq);
20238 @@ -854,6 +878,7 @@ static void __activate_task(struct task_
20240 static inline void __activate_idle_task(struct task_struct *p, struct rq *rq)
20242 + vxm_activate_idle(p, rq);
20243 enqueue_task_head(p, rq->active);
20244 inc_nr_running(p, rq);
20246 @@ -975,19 +1000,30 @@ static void activate_task(struct task_st
20248 p->timestamp = now;
20250 + vx_activate_task(p);
20251 __activate_task(p, rq);
20255 * deactivate_task - remove a task from the runqueue.
20257 -static void deactivate_task(struct task_struct *p, struct rq *rq)
20258 +static void __deactivate_task(struct task_struct *p, struct rq *rq)
20260 dec_nr_running(p, rq);
20261 dequeue_task(p, p->array);
20262 + vxm_deactivate_task(p, rq);
20267 +void deactivate_task(struct task_struct *p, struct rq *rq)
20269 + vx_deactivate_task(p);
20270 + __deactivate_task(p, rq);
20273 +#include "sched_hard.h"
20276 * resched_task - mark a task 'to be rescheduled now'.
20278 @@ -1063,6 +1099,7 @@ migrate_task(struct task_struct *p, int
20280 struct rq *rq = task_rq(p);
20282 + vxm_migrate_task(p, rq, dest_cpu);
20284 * If the task is not on a runqueue (and not running), then
20285 * it is sufficient to simply update the task's cpu field.
20286 @@ -1391,6 +1428,12 @@ static int try_to_wake_up(struct task_st
20288 rq = task_rq_lock(p, &flags);
20289 old_state = p->state;
20291 + /* we need to unhold suspended tasks */
20292 + if (old_state & TASK_ONHOLD) {
20293 + vx_unhold_task(p, rq);
20294 + old_state = p->state;
20296 if (!(old_state & state))
20299 @@ -1496,6 +1539,7 @@ out_activate:
20300 #endif /* CONFIG_SMP */
20301 if (old_state == TASK_UNINTERRUPTIBLE) {
20302 rq->nr_uninterruptible--;
20303 + vx_uninterruptible_dec(p);
20305 * Tasks on involuntary sleep don't earn
20306 * sleep_avg beyond just interactive state.
20307 @@ -1642,6 +1686,7 @@ void fastcall wake_up_new_task(struct ta
20309 p->prio = effective_prio(p);
20311 + vx_activate_task(p);
20312 if (likely(cpu == this_cpu)) {
20313 if (!(clone_flags & CLONE_VM)) {
20315 @@ -1653,6 +1698,7 @@ void fastcall wake_up_new_task(struct ta
20316 __activate_task(p, rq);
20318 p->prio = current->prio;
20319 + BUG_ON(p->state & TASK_ONHOLD);
20320 p->normal_prio = current->normal_prio;
20321 list_add_tail(&p->run_list, ¤t->run_list);
20322 p->array = current->array;
20323 @@ -2973,13 +3019,16 @@ static inline int expired_starving(struc
20324 void account_user_time(struct task_struct *p, cputime_t cputime)
20326 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
20327 + struct vx_info *vxi = p->vx_info; /* p is _always_ current */
20329 + int nice = (TASK_NICE(p) > 0);
20331 p->utime = cputime_add(p->utime, cputime);
20332 + vx_account_user(vxi, cputime, nice);
20334 /* Add user time to cpustat. */
20335 tmp = cputime_to_cputime64(cputime);
20336 - if (TASK_NICE(p) > 0)
20338 cpustat->nice = cputime64_add(cpustat->nice, tmp);
20340 cpustat->user = cputime64_add(cpustat->user, tmp);
20341 @@ -2995,10 +3044,12 @@ void account_system_time(struct task_str
20344 struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
20345 + struct vx_info *vxi = p->vx_info; /* p is _always_ current */
20346 struct rq *rq = this_rq();
20349 p->stime = cputime_add(p->stime, cputime);
20350 + vx_account_system(vxi, cputime, (p == rq->idle));
20352 /* Add system time to cpustat. */
20353 tmp = cputime_to_cputime64(cputime);
20354 @@ -3052,12 +3103,14 @@ void scheduler_tick(void)
20355 struct rq *rq = cpu_rq(cpu);
20357 update_cpu_clock(p, rq, now);
20358 + vxm_sync(now, cpu);
20360 rq->timestamp_last_tick = now;
20362 if (p == rq->idle) {
20363 if (wake_priority_sleeper(rq))
20365 + vx_idle_resched(rq);
20366 rebalance_tick(cpu, rq, SCHED_IDLE);
20369 @@ -3090,7 +3143,7 @@ void scheduler_tick(void)
20373 - if (!--p->time_slice) {
20374 + if (vx_need_resched(p, --p->time_slice, cpu)) {
20375 dequeue_task(p, rq->active);
20376 set_tsk_need_resched(p);
20377 p->prio = effective_prio(p);
20378 @@ -3377,14 +3430,25 @@ need_resched_nonpreemptible:
20379 unlikely(signal_pending(prev))))
20380 prev->state = TASK_RUNNING;
20382 - if (prev->state == TASK_UNINTERRUPTIBLE)
20383 + if (prev->state == TASK_UNINTERRUPTIBLE) {
20384 rq->nr_uninterruptible++;
20385 + vx_uninterruptible_inc(prev);
20387 deactivate_task(prev, rq);
20391 cpu = smp_processor_id();
20392 + vx_set_rq_time(rq, jiffies);
20394 + vx_try_unhold(rq, cpu);
20397 if (unlikely(!rq->nr_running)) {
20398 + /* can we skip idle time? */
20399 + if (vx_try_skip(rq, cpu))
20402 idle_balance(cpu, rq);
20403 if (!rq->nr_running) {
20405 @@ -3411,6 +3475,10 @@ need_resched_nonpreemptible:
20406 queue = array->queue + idx;
20407 next = list_entry(queue->next, struct task_struct, run_list);
20409 + /* check before we schedule this context */
20410 + if (!vx_schedule(next, rq, cpu))
20413 if (!rt_task(next) && interactive_sleep(next->sleep_type)) {
20414 unsigned long long delta = now - next->timestamp;
20415 if (unlikely((long long)(now - next->timestamp) < 0))
20416 @@ -4013,7 +4081,7 @@ asmlinkage long sys_nice(int increment)
20419 if (increment < 0 && !can_nice(current, nice))
20421 + return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
20423 retval = security_task_setnice(current, nice);
20425 @@ -4186,6 +4254,7 @@ recheck:
20427 __setscheduler(p, policy, param->sched_priority);
20429 + vx_activate_task(p);
20430 __activate_task(p, rq);
20432 * Reschedule if we are currently running on this runqueue and
20433 @@ -4976,6 +5045,7 @@ static int __migrate_task(struct task_st
20434 p->timestamp = p->timestamp - rq_src->timestamp_last_tick
20435 + rq_dest->timestamp_last_tick;
20436 deactivate_task(p, rq_src);
20437 + vx_activate_task(p);
20438 __activate_task(p, rq_dest);
20439 if (TASK_PREEMPTS_CURR(p, rq_dest))
20440 resched_task(rq_dest->curr);
20441 @@ -6819,7 +6889,10 @@ void __init sched_init(void)
20442 INIT_LIST_HEAD(&rq->migration_queue);
20444 atomic_set(&rq->nr_iowait, 0);
20446 +#ifdef CONFIG_VSERVER_HARDCPU
20447 + INIT_LIST_HEAD(&rq->hold_queue);
20448 + rq->nr_onhold = 0;
20450 for (j = 0; j < 2; j++) {
20451 array = rq->arrays + j;
20452 for (k = 0; k < MAX_PRIO; k++) {
20453 @@ -6895,6 +6968,7 @@ void normalize_rt_tasks(void)
20454 deactivate_task(p, task_rq(p));
20455 __setscheduler(p, SCHED_NORMAL, 0);
20457 + vx_activate_task(p);
20458 __activate_task(p, task_rq(p));
20459 resched_task(rq->curr);
20461 diff -NurpP --minimal linux-2.6.19.1/kernel/sched_hard.h linux-2.6.19.1-vs2.3.0.6/kernel/sched_hard.h
20462 --- linux-2.6.19.1/kernel/sched_hard.h 1970-01-01 01:00:00 +0100
20463 +++ linux-2.6.19.1-vs2.3.0.6/kernel/sched_hard.h 2006-11-30 18:53:18 +0100
20466 +#ifdef CONFIG_VSERVER_IDLELIMIT
20469 + * vx_idle_resched - reschedule after maxidle
20472 +void vx_idle_resched(struct rq *rq)
20474 + /* maybe have a better criterion for paused */
20475 + if (!--rq->idle_tokens && !list_empty(&rq->hold_queue))
20476 + set_need_resched();
20479 +#else /* !CONFIG_VSERVER_IDLELIMIT */
20481 +#define vx_idle_resched(rq)
20483 +#endif /* CONFIG_VSERVER_IDLELIMIT */
20487 +#ifdef CONFIG_VSERVER_IDLETIME
20489 +#define vx_set_rq_min_skip(rq, min) \
20490 + (rq)->idle_skip = (min)
20492 +#define vx_save_min_skip(ret, min, val) \
20493 + __vx_save_min_skip(ret, min, val)
20496 +void __vx_save_min_skip(int ret, int *min, int val)
20500 + if ((*min > val) || !*min)
20505 +int vx_try_skip(struct rq *rq, int cpu)
20507 + /* artificially advance time */
20508 + if (rq->idle_skip > 0) {
20509 + vxdprintk(list_empty(&rq->hold_queue),
20510 + "hold queue empty on cpu %d", cpu);
20511 + rq->idle_time += rq->idle_skip;
20512 + vxm_idle_skip(rq, cpu);
20518 +#else /* !CONFIG_VSERVER_IDLETIME */
20520 +#define vx_set_rq_min_skip(rq, min) \
20521 + ({ int dummy = (min); dummy; })
20523 +#define vx_save_min_skip(ret, min, val)
20526 +int vx_try_skip(struct rq *rq, int cpu)
20531 +#endif /* CONFIG_VSERVER_IDLETIME */
20535 +#ifdef CONFIG_VSERVER_HARDCPU
20537 +#define vx_set_rq_max_idle(rq, max) \
20538 + (rq)->idle_tokens = (max)
20540 +#define vx_save_max_idle(ret, min, val) \
20541 + __vx_save_max_idle(ret, min, val)
20544 +void __vx_save_max_idle(int ret, int *min, int val)
20552 + * vx_hold_task - put a task on the hold queue
20555 +void vx_hold_task(struct task_struct *p, struct rq *rq)
20557 + __deactivate_task(p, rq);
20558 + p->state |= TASK_ONHOLD;
20559 + /* a new one on hold */
20561 + vxm_hold_task(p, rq);
20562 + list_add_tail(&p->run_list, &rq->hold_queue);
20566 + * vx_unhold_task - put a task back to the runqueue
20569 +void vx_unhold_task(struct task_struct *p, struct rq *rq)
20571 + list_del(&p->run_list);
20572 + /* one less waiting */
20574 + p->state &= ~TASK_ONHOLD;
20575 + enqueue_task(p, rq->expired);
20576 + inc_nr_running(p, rq);
20577 + vxm_unhold_task(p, rq);
20579 + if (p->static_prio < rq->best_expired_prio)
20580 + rq->best_expired_prio = p->static_prio;
20583 +unsigned long nr_onhold(void)
20585 + unsigned long i, sum = 0;
20587 + for_each_online_cpu(i)
20588 + sum += cpu_rq(i)->nr_onhold;
20596 +int __vx_tokens_avail(struct _vx_sched_pc *sched_pc)
20598 + return sched_pc->tokens;
20602 +void __vx_consume_token(struct _vx_sched_pc *sched_pc)
20604 + sched_pc->tokens--;
20608 +int vx_need_resched(struct task_struct *p, int slice, int cpu)
20610 + struct vx_info *vxi = p->vx_info;
20612 + if (vx_info_flags(vxi, VXF_SCHED_HARD|VXF_SCHED_PRIO, 0)) {
20613 + struct _vx_sched_pc *sched_pc =
20614 + &vx_per_cpu(vxi, sched_pc, cpu);
20617 + /* maybe we can simplify that to decrement
20618 + the token counter unconditional? */
20620 + if ((tokens = __vx_tokens_avail(sched_pc)) > 0)
20621 + __vx_consume_token(sched_pc);
20623 + /* for tokens > 0, one token was consumed */
20627 + vxm_need_resched(p, slice, cpu);
20628 + return (slice == 0);
20632 +#define vx_set_rq_time(rq, time) do { \
20633 + rq->norm_time = time; \
20638 +void vx_try_unhold(struct rq *rq, int cpu)
20640 + struct vx_info *vxi = NULL;
20641 + struct list_head *l, *n;
20642 + int maxidle = HZ;
20645 + /* nothing to do? what about pause? */
20646 + if (list_empty(&rq->hold_queue))
20649 + list_for_each_safe(l, n, &rq->hold_queue) {
20650 + int ret, delta_min[2];
20651 + struct _vx_sched_pc *sched_pc;
20652 + struct task_struct *p;
20654 + p = list_entry(l, struct task_struct, run_list);
20655 + /* don't bother with same context */
20656 + if (vxi == p->vx_info)
20659 + vxi = p->vx_info;
20660 + /* ignore paused contexts */
20661 + if (vx_info_flags(vxi, VXF_SCHED_PAUSE, 0))
20664 + sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
20666 + /* recalc tokens */
20667 + vxm_sched_info(sched_pc, vxi, cpu);
20668 + ret = vx_tokens_recalc(sched_pc,
20669 + &rq->norm_time, &rq->idle_time, delta_min);
20670 + vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
20673 + /* we found a runable context */
20674 + vx_unhold_task(p, rq);
20677 + vx_save_max_idle(ret, &maxidle, delta_min[0]);
20678 + vx_save_min_skip(ret, &minskip, delta_min[1]);
20680 + vx_set_rq_max_idle(rq, maxidle);
20681 + vx_set_rq_min_skip(rq, minskip);
20682 + vxm_rq_max_min(rq, cpu);
20687 +int vx_schedule(struct task_struct *next, struct rq *rq, int cpu)
20689 + struct vx_info *vxi = next->vx_info;
20690 + struct _vx_sched_pc *sched_pc;
20691 + int delta_min[2];
20697 + flags = vxi->vx_flags;
20699 + if (unlikely(vs_check_flags(flags , VXF_SCHED_PAUSE, 0)))
20700 + goto put_on_hold;
20701 + if (!vs_check_flags(flags , VXF_SCHED_HARD|VXF_SCHED_PRIO, 0))
20704 + sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
20706 + /* update scheduler params */
20707 + if (cpu_isset(cpu, vxi->sched.update)) {
20708 + vx_update_sched_param(&vxi->sched, sched_pc);
20709 + vxm_update_sched(sched_pc, vxi, cpu);
20710 + cpu_clear(cpu, vxi->sched.update);
20713 + vxm_sched_info(sched_pc, vxi, cpu);
20714 + ret = vx_tokens_recalc(sched_pc,
20715 + &rq->norm_time, &rq->idle_time, delta_min);
20716 + vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
20718 + if (!vs_check_flags(flags , VXF_SCHED_HARD, 0))
20721 + if (unlikely(ret < 0)) {
20722 + vx_save_max_idle(ret, &rq->idle_tokens, delta_min[0]);
20723 + vx_save_min_skip(ret, &rq->idle_skip, delta_min[1]);
20724 + vxm_rq_max_min(rq, cpu);
20726 + vx_hold_task(next, rq);
20733 +#else /* CONFIG_VSERVER_HARDCPU */
20736 +void vx_hold_task(struct task_struct *p, struct rq *rq)
20742 +void vx_unhold_task(struct task_struct *p, struct rq *rq)
20747 +unsigned long nr_onhold(void)
20754 +int vx_need_resched(struct task_struct *p, int slice, int cpu)
20756 + return (slice == 0);
20760 +#define vx_set_rq_time(rq, time)
20763 +void vx_try_unhold(struct rq *rq, int cpu)
20769 +int vx_schedule(struct task_struct *next, struct rq *rq, int cpu)
20771 + struct vx_info *vxi = next->vx_info;
20772 + struct _vx_sched_pc *sched_pc;
20773 + int delta_min[2];
20776 + if (!vx_info_flags(vxi, VXF_SCHED_PRIO, 0))
20779 + sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
20780 + vxm_sched_info(sched_pc, vxi, cpu);
20781 + ret = vx_tokens_recalc(sched_pc,
20782 + &rq->norm_time, &rq->idle_time, delta_min);
20783 + vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
20787 +#endif /* CONFIG_VSERVER_HARDCPU */
20789 diff -NurpP --minimal linux-2.6.19.1/kernel/sched_mon.h linux-2.6.19.1-vs2.3.0.6/kernel/sched_mon.h
20790 --- linux-2.6.19.1/kernel/sched_mon.h 1970-01-01 01:00:00 +0100
20791 +++ linux-2.6.19.1-vs2.3.0.6/kernel/sched_mon.h 2006-11-08 04:57:48 +0100
20794 +#include <linux/vserver/monitor.h>
20796 +#ifdef CONFIG_VSERVER_MONITOR
20798 +#ifdef CONFIG_VSERVER_HARDCPU
20799 +#define HARDCPU(x) (x)
20801 +#define HARDCPU(x) (0)
20804 +#ifdef CONFIG_VSERVER_IDLETIME
20805 +#define IDLETIME(x) (x)
20807 +#define IDLETIME(x) (0)
20810 +struct _vx_mon_entry *vxm_advance(int cpu);
20814 +void __vxm_basic(struct _vx_mon_entry *entry, xid_t xid, int type)
20816 + entry->type = type;
20817 + entry->xid = xid;
20821 +void __vxm_sync(int cpu)
20823 + struct _vx_mon_entry *entry = vxm_advance(cpu);
20825 + __vxm_basic(entry, 0, VXM_SYNC);
20826 + entry->ev.sec = xtime.tv_sec;
20827 + entry->ev.nsec = xtime.tv_nsec;
20831 +void __vxm_task(struct task_struct *p, int type)
20833 + struct _vx_mon_entry *entry = vxm_advance(task_cpu(p));
20835 + __vxm_basic(entry, p->xid, type);
20836 + entry->ev.tsk.pid = p->pid;
20837 + entry->ev.tsk.state = p->state;
20841 +void __vxm_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20843 + struct _vx_mon_entry *entry = vxm_advance(cpu);
20845 + __vxm_basic(entry, vxi->vx_id, (VXM_SCHED | s->flags));
20846 + entry->sd.tokens = s->tokens;
20847 + entry->sd.norm_time = s->norm_time;
20848 + entry->sd.idle_time = s->idle_time;
20852 +void __vxm_rqinfo1(struct rq *q, int cpu)
20854 + struct _vx_mon_entry *entry = vxm_advance(cpu);
20856 + entry->type = VXM_RQINFO_1;
20857 + entry->xid = ((unsigned long)q >> 16) & 0xffff;
20858 + entry->q1.running = q->nr_running;
20859 + entry->q1.onhold = HARDCPU(q->nr_onhold);
20860 + entry->q1.iowait = atomic_read(&q->nr_iowait);
20861 + entry->q1.uintr = q->nr_uninterruptible;
20862 + entry->q1.idle_tokens = IDLETIME(q->idle_tokens);
20866 +void __vxm_rqinfo2(struct rq *q, int cpu)
20868 + struct _vx_mon_entry *entry = vxm_advance(cpu);
20870 + entry->type = VXM_RQINFO_2;
20871 + entry->xid = (unsigned long)q & 0xffff;
20872 + entry->q2.norm_time = q->norm_time;
20873 + entry->q2.idle_time = q->idle_time;
20874 + entry->q2.idle_skip = IDLETIME(q->idle_skip);
20878 +void __vxm_update(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20880 + struct _vx_mon_entry *entry = vxm_advance(cpu);
20882 + __vxm_basic(entry, vxi->vx_id, VXM_UPDATE);
20883 + entry->ev.tokens = s->tokens;
20887 +void __vxm_update1(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20889 + struct _vx_mon_entry *entry = vxm_advance(cpu);
20891 + __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_1);
20892 + entry->u1.tokens_max = s->tokens_max;
20893 + entry->u1.fill_rate = s->fill_rate[0];
20894 + entry->u1.interval = s->interval[0];
20898 +void __vxm_update2(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20900 + struct _vx_mon_entry *entry = vxm_advance(cpu);
20902 + __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_2);
20903 + entry->u2.tokens_min = s->tokens_min;
20904 + entry->u2.fill_rate = s->fill_rate[1];
20905 + entry->u2.interval = s->interval[1];
20909 +#define vxm_activate_task(p,q) __vxm_task(p, VXM_ACTIVATE)
20910 +#define vxm_activate_idle(p,q) __vxm_task(p, VXM_IDLE)
20911 +#define vxm_deactivate_task(p,q) __vxm_task(p, VXM_DEACTIVATE)
20912 +#define vxm_hold_task(p,q) __vxm_task(p, VXM_HOLD)
20913 +#define vxm_unhold_task(p,q) __vxm_task(p, VXM_UNHOLD)
20916 +void vxm_migrate_task(struct task_struct *p, struct rq *rq, int dest)
20918 + __vxm_task(p, VXM_MIGRATE);
20919 + __vxm_rqinfo1(rq, task_cpu(p));
20920 + __vxm_rqinfo2(rq, task_cpu(p));
20924 +void vxm_idle_skip(struct rq *rq, int cpu)
20926 + __vxm_rqinfo1(rq, cpu);
20927 + __vxm_rqinfo2(rq, cpu);
20931 +void vxm_need_resched(struct task_struct *p, int slice, int cpu)
20936 + __vxm_task(p, VXM_RESCHED);
20940 +void vxm_sync(unsigned long now, int cpu)
20942 + if (!CONFIG_VSERVER_MONITOR_SYNC ||
20943 + (now % CONFIG_VSERVER_MONITOR_SYNC))
20949 +#define vxm_sched_info(s,v,c) __vxm_sched(s,v,c)
20952 +void vxm_tokens_recalc(struct _vx_sched_pc *s, struct rq *rq,
20953 + struct vx_info *vxi, int cpu)
20955 + __vxm_sched(s, vxi, cpu);
20956 + __vxm_rqinfo2(rq, cpu);
20960 +void vxm_update_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20962 + __vxm_sched(s, vxi, cpu);
20963 + __vxm_update(s, vxi, cpu);
20964 + __vxm_update1(s, vxi, cpu);
20965 + __vxm_update2(s, vxi, cpu);
20969 +void vxm_rq_max_min(struct rq *rq, int cpu)
20971 + __vxm_rqinfo1(rq, cpu);
20972 + __vxm_rqinfo2(rq, cpu);
20975 +#else /* CONFIG_VSERVER_MONITOR */
20977 +#define vxm_activate_task(t,q) do { } while (0)
20978 +#define vxm_activate_idle(t,q) do { } while (0)
20979 +#define vxm_deactivate_task(t,q) do { } while (0)
20980 +#define vxm_hold_task(t,q) do { } while (0)
20981 +#define vxm_unhold_task(t,q) do { } while (0)
20982 +#define vxm_migrate_task(t,q,d) do { } while (0)
20983 +#define vxm_idle_skip(q,c) do { } while (0)
20984 +#define vxm_need_resched(t,s,c) do { } while (0)
20985 +#define vxm_sync(s,c) do { } while (0)
20986 +#define vxm_sched_info(s,v,c) do { } while (0)
20987 +#define vxm_tokens_recalc(s,q,v,c) do { } while (0)
20988 +#define vxm_update_sched(s,v,c) do { } while (0)
20989 +#define vxm_rq_max_min(q,c) do { } while (0)
20991 +#endif /* CONFIG_VSERVER_MONITOR */
20993 diff -NurpP --minimal linux-2.6.19.1/kernel/signal.c linux-2.6.19.1-vs2.3.0.6/kernel/signal.c
20994 --- linux-2.6.19.1/kernel/signal.c 2006-11-30 21:19:44 +0100
20995 +++ linux-2.6.19.1-vs2.3.0.6/kernel/signal.c 2006-11-30 19:43:08 +0100
20997 #include <linux/ptrace.h>
20998 #include <linux/signal.h>
20999 #include <linux/capability.h>
21000 +#include <linux/vs_context.h>
21001 #include <asm/param.h>
21002 #include <asm/uaccess.h>
21003 #include <asm/unistd.h>
21004 @@ -577,17 +578,30 @@ static int check_kill_permission(int sig
21005 struct task_struct *t)
21007 int error = -EINVAL;
21009 if (!valid_signal(sig))
21012 + if ((info != SEND_SIG_NOINFO) &&
21013 + (is_si_special(info) || !SI_FROMUSER(info)))
21017 - if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
21018 - && ((sig != SIGCONT) ||
21019 + if (((sig != SIGCONT) ||
21020 (current->signal->session != t->signal->session))
21021 && (current->euid ^ t->suid) && (current->euid ^ t->uid)
21022 && (current->uid ^ t->suid) && (current->uid ^ t->uid)
21023 && !capable(CAP_KILL))
21027 + if (!vx_check(vx_task_xid(t), VS_WATCH_P|VS_IDENT)) {
21028 + vxwprintk(current->xid,
21029 + "signal xid mismatch %p[#%u,%u] xid=#%u\n",
21030 + t, vx_task_xid(t), t->pid, current->xid);
21034 error = security_task_kill(t, info, sig, 0);
21036 audit_signal_info(sig, t); /* Let audit system see the signal */
21037 @@ -1125,7 +1139,7 @@ int kill_pid_info(int sig, struct siginf
21039 p = pid_task(pid, PIDTYPE_PID);
21042 + if (p && vx_check(vx_task_xid(p), VS_IDENT))
21043 error = group_send_sig_info(sig, info, p);
21044 if (unlikely(acquired_tasklist_lock))
21045 read_unlock(&tasklist_lock);
21046 @@ -1197,7 +1211,8 @@ static int kill_something_info(int sig,
21048 read_lock(&tasklist_lock);
21049 for_each_process(p) {
21050 - if (p->pid > 1 && p->tgid != current->tgid) {
21051 + if (vx_check(vx_task_xid(p), VS_ADMIN_P|VS_IDENT) &&
21052 + p->pid > 1 && p->tgid != current->tgid) {
21053 int err = group_send_sig_info(sig, info, p);
21056 @@ -1881,6 +1896,11 @@ relock:
21057 if (current == child_reaper)
21060 + /* virtual init is protected against user signals */
21061 + if ((info->si_code == SI_USER) &&
21062 + vx_current_initpid(current->pid))
21065 if (sig_kernel_stop(signr)) {
21067 * The default action is to stop all threads in
21068 diff -NurpP --minimal linux-2.6.19.1/kernel/softirq.c linux-2.6.19.1-vs2.3.0.6/kernel/softirq.c
21069 --- linux-2.6.19.1/kernel/softirq.c 2006-12-13 07:46:36 +0100
21070 +++ linux-2.6.19.1-vs2.3.0.6/kernel/softirq.c 2006-12-13 09:16:31 +0100
21072 #include <linux/kthread.h>
21073 #include <linux/rcupdate.h>
21074 #include <linux/smp.h>
21075 +#include <linux/vs_context.h>
21077 #include <asm/irq.h>
21079 diff -NurpP --minimal linux-2.6.19.1/kernel/sys.c linux-2.6.19.1-vs2.3.0.6/kernel/sys.c
21080 --- linux-2.6.19.1/kernel/sys.c 2006-11-30 21:19:44 +0100
21081 +++ linux-2.6.19.1-vs2.3.0.6/kernel/sys.c 2006-12-02 01:37:05 +0100
21083 #include <linux/mman.h>
21084 #include <linux/smp_lock.h>
21085 #include <linux/notifier.h>
21086 +#include <linux/kmod.h>
21087 #include <linux/reboot.h>
21088 #include <linux/prctl.h>
21089 #include <linux/highuid.h>
21091 #include <linux/compat.h>
21092 #include <linux/syscalls.h>
21093 #include <linux/kprobes.h>
21094 +#include <linux/vs_pid.h>
21096 #include <asm/uaccess.h>
21097 #include <asm/io.h>
21098 @@ -569,7 +571,10 @@ static int set_one_prio(struct task_stru
21101 if (niceval < task_nice(p) && !can_nice(p, niceval)) {
21103 + if (vx_flags(VXF_IGNEG_NICE, 0))
21109 no_nice = security_task_setnice(p, niceval);
21110 @@ -621,7 +626,8 @@ asmlinkage long sys_setpriority(int whic
21112 who = current->uid;
21114 - if ((who != current->uid) && !(user = find_user(who)))
21115 + if ((who != current->uid) &&
21116 + !(user = find_user(vx_current_xid(), who)))
21117 goto out_unlock; /* No processes for this user */
21119 do_each_thread(g, p)
21120 @@ -679,7 +685,8 @@ asmlinkage long sys_getpriority(int whic
21122 who = current->uid;
21124 - if ((who != current->uid) && !(user = find_user(who)))
21125 + if ((who != current->uid) &&
21126 + !(user = find_user(vx_current_xid(), who)))
21127 goto out_unlock; /* No processes for this user */
21129 do_each_thread(g, p)
21130 @@ -792,6 +799,9 @@ void kernel_power_off(void)
21131 machine_power_off();
21133 EXPORT_SYMBOL_GPL(kernel_power_off);
21135 +long vs_reboot(unsigned int, void __user *);
21138 * Reboot system call: for obvious reasons only root may call it,
21139 * and even root needs to set up some magic numbers in the registers
21140 @@ -822,6 +832,9 @@ asmlinkage long sys_reboot(int magic1, i
21141 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
21142 cmd = LINUX_REBOOT_CMD_HALT;
21144 + if (!vx_check(0, VS_ADMIN|VS_WATCH))
21145 + return vs_reboot(cmd, arg);
21149 case LINUX_REBOOT_CMD_RESTART:
21150 @@ -1001,7 +1014,7 @@ static int set_user(uid_t new_ruid, int
21152 struct user_struct *new_user;
21154 - new_user = alloc_uid(new_ruid);
21155 + new_user = alloc_uid(vx_current_xid(), new_ruid);
21159 @@ -1356,15 +1369,18 @@ asmlinkage long sys_setpgid(pid_t pid, p
21161 struct task_struct *p;
21162 struct task_struct *group_leader = current->group_leader;
21167 - pid = group_leader->pid;
21168 + pid = vx_map_pid(group_leader->pid);
21174 + rpgid = vx_rmap_pid(pgid);
21176 /* From this point forward we keep holding onto the tasklist lock
21177 * so that our parent does not change from under us. -DaveM
21179 @@ -1399,22 +1415,22 @@ asmlinkage long sys_setpgid(pid_t pid, p
21181 struct task_struct *p;
21183 - do_each_task_pid(pgid, PIDTYPE_PGID, p) {
21184 + do_each_task_pid(rpgid, PIDTYPE_PGID, p) {
21185 if (p->signal->session == group_leader->signal->session)
21187 - } while_each_task_pid(pgid, PIDTYPE_PGID, p);
21188 + } while_each_task_pid(rpgid, PIDTYPE_PGID, p);
21193 - err = security_task_setpgid(p, pgid);
21194 + err = security_task_setpgid(p, rpgid);
21198 - if (process_group(p) != pgid) {
21199 + if (process_group(p) != rpgid) {
21200 detach_pid(p, PIDTYPE_PGID);
21201 - p->signal->pgrp = pgid;
21202 - attach_pid(p, PIDTYPE_PGID, pgid);
21203 + p->signal->pgrp = rpgid;
21204 + attach_pid(p, PIDTYPE_PGID, rpgid);
21208 @@ -1427,7 +1443,7 @@ out:
21209 asmlinkage long sys_getpgid(pid_t pid)
21212 - return process_group(current);
21213 + return vx_rmap_pid(process_group(current));
21216 struct task_struct *p;
21217 @@ -1439,7 +1455,7 @@ asmlinkage long sys_getpgid(pid_t pid)
21219 retval = security_task_getpgid(p);
21221 - retval = process_group(p);
21222 + retval = vx_rmap_pid(process_group(p));
21224 read_unlock(&tasklist_lock);
21226 @@ -1789,7 +1805,7 @@ asmlinkage long sys_sethostname(char __u
21228 char tmp[__NEW_UTS_LEN];
21230 - if (!capable(CAP_SYS_ADMIN))
21231 + if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME))
21233 if (len < 0 || len > __NEW_UTS_LEN)
21235 @@ -1834,7 +1850,7 @@ asmlinkage long sys_setdomainname(char _
21237 char tmp[__NEW_UTS_LEN];
21239 - if (!capable(CAP_SYS_ADMIN))
21240 + if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME))
21242 if (len < 0 || len > __NEW_UTS_LEN)
21244 @@ -1901,7 +1917,7 @@ asmlinkage long sys_setrlimit(unsigned i
21246 old_rlim = current->signal->rlim + resource;
21247 if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
21248 - !capable(CAP_SYS_RESOURCE))
21249 + !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
21251 if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN)
21253 diff -NurpP --minimal linux-2.6.19.1/kernel/sysctl.c linux-2.6.19.1-vs2.3.0.6/kernel/sysctl.c
21254 --- linux-2.6.19.1/kernel/sysctl.c 2006-11-30 21:19:44 +0100
21255 +++ linux-2.6.19.1-vs2.3.0.6/kernel/sysctl.c 2006-12-02 01:37:05 +0100
21256 @@ -87,6 +87,7 @@ static int ngroups_max = NGROUPS_MAX;
21258 extern char modprobe_path[];
21260 +extern char vshelper_path[];
21261 #ifdef CONFIG_CHR_DEV_SG
21262 extern int sg_big_buff;
21264 @@ -456,6 +457,15 @@ static ctl_table kern_table[] = {
21265 .strategy = &sysctl_string,
21269 + .ctl_name = KERN_VSHELPER,
21270 + .procname = "vshelper",
21271 + .data = &vshelper_path,
21274 + .proc_handler = &proc_dostring,
21275 + .strategy = &sysctl_string,
21277 #ifdef CONFIG_CHR_DEV_SG
21279 .ctl_name = KERN_SG_BIG_BUFF,
21280 diff -NurpP --minimal linux-2.6.19.1/kernel/time.c linux-2.6.19.1-vs2.3.0.6/kernel/time.c
21281 --- linux-2.6.19.1/kernel/time.c 2006-11-30 21:19:44 +0100
21282 +++ linux-2.6.19.1-vs2.3.0.6/kernel/time.c 2006-11-08 04:57:44 +0100
21283 @@ -61,7 +61,7 @@ asmlinkage long sys_time(time_t __user *
21287 - do_gettimeofday(&tv);
21288 + vx_gettimeofday(&tv);
21292 @@ -92,7 +92,7 @@ asmlinkage long sys_stime(time_t __user
21296 - do_settimeofday(&tv);
21297 + vx_settimeofday(&tv);
21301 @@ -102,7 +102,7 @@ asmlinkage long sys_gettimeofday(struct
21303 if (likely(tv != NULL)) {
21304 struct timeval ktv;
21305 - do_gettimeofday(&ktv);
21306 + vx_gettimeofday(&ktv);
21307 if (copy_to_user(tv, &ktv, sizeof(ktv)))
21310 @@ -176,7 +176,7 @@ int do_sys_settimeofday(struct timespec
21311 /* SMP safe, again the code in arch/foo/time.c should
21312 * globally block out interrupts when it runs.
21314 - return do_settimeofday(tv);
21315 + return vx_settimeofday(tv);
21319 @@ -359,7 +359,7 @@ void getnstimeofday(struct timespec *tv)
21323 - do_gettimeofday(&x);
21324 + vx_gettimeofday(&x);
21325 tv->tv_sec = x.tv_sec;
21326 tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
21328 diff -NurpP --minimal linux-2.6.19.1/kernel/timer.c linux-2.6.19.1-vs2.3.0.6/kernel/timer.c
21329 --- linux-2.6.19.1/kernel/timer.c 2006-11-30 21:19:44 +0100
21330 +++ linux-2.6.19.1-vs2.3.0.6/kernel/timer.c 2006-11-08 06:18:54 +0100
21332 #include <linux/cpu.h>
21333 #include <linux/syscalls.h>
21334 #include <linux/delay.h>
21335 +#include <linux/vs_base.h>
21336 +#include <linux/vs_cvirt.h>
21337 +#include <linux/vs_pid.h>
21338 +#include <linux/vserver/sched.h>
21340 #include <asm/uaccess.h>
21341 #include <asm/unistd.h>
21342 @@ -1082,12 +1086,6 @@ asmlinkage unsigned long sys_alarm(unsig
21349 - * The Alpha uses getxpid, getxuid, and getxgid instead. Maybe this
21350 - * should be moved into arch/i386 instead?
21354 * sys_getpid - return the thread group id of the current process
21355 @@ -1100,7 +1098,7 @@ asmlinkage unsigned long sys_alarm(unsig
21357 asmlinkage long sys_getpid(void)
21359 - return current->tgid;
21360 + return vx_map_tgid(current->tgid);
21364 @@ -1116,10 +1114,23 @@ asmlinkage long sys_getppid(void)
21366 pid = rcu_dereference(current->real_parent)->tgid;
21368 + return vx_map_pid(pid);
21375 + * The Alpha uses getxpid, getxuid, and getxgid instead.
21378 +asmlinkage long do_getxpid(long *ppid)
21380 + *ppid = sys_getppid();
21381 + return sys_getpid();
21384 +#else /* _alpha_ */
21386 asmlinkage long sys_getuid(void)
21388 /* Only we change this so SMP safe */
21389 @@ -1281,6 +1292,8 @@ asmlinkage long sys_sysinfo(struct sysin
21390 tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC;
21393 + if (vx_flags(VXF_VIRT_UPTIME, 0))
21394 + vx_vsi_uptime(&tp, NULL);
21395 val.uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0);
21397 val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
21398 diff -NurpP --minimal linux-2.6.19.1/kernel/user.c linux-2.6.19.1-vs2.3.0.6/kernel/user.c
21399 --- linux-2.6.19.1/kernel/user.c 2006-11-30 21:19:44 +0100
21400 +++ linux-2.6.19.1-vs2.3.0.6/kernel/user.c 2006-11-08 21:52:09 +0100
21402 #define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 8)
21403 #define UIDHASH_SZ (1 << UIDHASH_BITS)
21404 #define UIDHASH_MASK (UIDHASH_SZ - 1)
21405 -#define __uidhashfn(uid) (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK)
21406 -#define uidhashentry(uid) (uidhash_table + __uidhashfn((uid)))
21407 +#define __uidhashfn(xid,uid) ((((uid) >> UIDHASH_BITS) + ((uid)^(xid))) & UIDHASH_MASK)
21408 +#define uidhashentry(xid,uid) (uidhash_table + __uidhashfn((xid),(uid)))
21410 static kmem_cache_t *uid_cachep;
21411 static struct list_head uidhash_table[UIDHASH_SZ];
21412 @@ -66,7 +66,7 @@ static inline void uid_hash_remove(struc
21413 list_del(&up->uidhash_list);
21416 -static inline struct user_struct *uid_hash_find(uid_t uid, struct list_head *hashent)
21417 +static inline struct user_struct *uid_hash_find(xid_t xid, uid_t uid, struct list_head *hashent)
21419 struct list_head *up;
21421 @@ -75,7 +75,7 @@ static inline struct user_struct *uid_ha
21423 user = list_entry(up, struct user_struct, uidhash_list);
21425 - if(user->uid == uid) {
21426 + if(user->uid == uid && user->xid == xid) {
21427 atomic_inc(&user->__count);
21430 @@ -90,13 +90,13 @@ static inline struct user_struct *uid_ha
21432 * If the user_struct could not be found, return NULL.
21434 -struct user_struct *find_user(uid_t uid)
21435 +struct user_struct *find_user(xid_t xid, uid_t uid)
21437 struct user_struct *ret;
21438 unsigned long flags;
21440 spin_lock_irqsave(&uidhash_lock, flags);
21441 - ret = uid_hash_find(uid, uidhashentry(uid));
21442 + ret = uid_hash_find(xid, uid, uidhashentry(xid, uid));
21443 spin_unlock_irqrestore(&uidhash_lock, flags);
21446 @@ -120,13 +120,13 @@ void free_uid(struct user_struct *up)
21450 -struct user_struct * alloc_uid(uid_t uid)
21451 +struct user_struct * alloc_uid(xid_t xid, uid_t uid)
21453 - struct list_head *hashent = uidhashentry(uid);
21454 + struct list_head *hashent = uidhashentry(xid, uid);
21455 struct user_struct *up;
21457 spin_lock_irq(&uidhash_lock);
21458 - up = uid_hash_find(uid, hashent);
21459 + up = uid_hash_find(xid, uid, hashent);
21460 spin_unlock_irq(&uidhash_lock);
21463 @@ -136,6 +136,7 @@ struct user_struct * alloc_uid(uid_t uid
21468 atomic_set(&new->__count, 1);
21469 atomic_set(&new->processes, 0);
21470 atomic_set(&new->files, 0);
21471 @@ -158,7 +159,7 @@ struct user_struct * alloc_uid(uid_t uid
21472 * on adding the same user already..
21474 spin_lock_irq(&uidhash_lock);
21475 - up = uid_hash_find(uid, hashent);
21476 + up = uid_hash_find(xid, uid, hashent);
21478 key_put(new->uid_keyring);
21479 key_put(new->session_keyring);
21480 @@ -215,7 +216,7 @@ static int __init uid_cache_init(void)
21482 /* Insert the root user immediately (init already runs as root) */
21483 spin_lock_irq(&uidhash_lock);
21484 - uid_hash_insert(&root_user, uidhashentry(0));
21485 + uid_hash_insert(&root_user, uidhashentry(0,0));
21486 spin_unlock_irq(&uidhash_lock);
21489 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/Kconfig linux-2.6.19.1-vs2.3.0.6/kernel/vserver/Kconfig
21490 --- linux-2.6.19.1/kernel/vserver/Kconfig 1970-01-01 01:00:00 +0100
21491 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/Kconfig 2006-12-17 04:04:22 +0100
21494 +# Linux VServer configuration
21497 +menu "Linux VServer"
21499 +config VSERVER_SINGLE_IP
21500 + bool "Single IP Special Casing"
21501 + depends on EXPERIMENTAL
21504 + This allows to have network contexts with a single
21505 + IP to remap 0.0.0.0 bindings to that IP, avoiding
21506 + further network checks and improving performance.
21508 + (note: such guests do not allow to change the ip
21509 + on the fly and do not show loopback addresses)
21511 +config VSERVER_AUTO_LBACK
21512 + bool "Automatically Assign Loopback IP"
21515 + This allows to have network contexts with a single
21516 + IP to remap 0.0.0.0 bindings to that IP, avoiding
21517 + further network checks and improving performance.
21519 + (note: such guests do not allow to change the ip
21520 + on the fly and do not show loopback addresses)
21522 +config VSERVER_COWBL
21523 + bool "Enable COW Immutable Link Breaking"
21524 + depends on EXPERIMENTAL
21527 + This enables the COW (Copy-On-Write) link break code.
21528 + It allows you to treat unified files like normal files
21529 + when writing to them (which will implicitely break the
21530 + link and create a copy of the unified file)
21532 +config VSERVER_VTIME
21533 + bool "Enable Virtualized Guest Time"
21534 + depends on EXPERIMENTAL
21537 + This enables per guest time offsets to allow for
21538 + adjusting the system clock individually per guest.
21539 + this adds some overhead to the time functions and
21540 + therefore should not be enabled without good reason.
21542 +config VSERVER_PROC_SECURE
21543 + bool "Enable Proc Security"
21544 + depends on PROC_FS
21547 + This configures ProcFS security to initially hide
21548 + non-process entries for all contexts except the main and
21549 + spectator context (i.e. for all guests), which is a secure
21552 + (note: on 1.2x the entries were visible by default)
21554 +config VSERVER_HARDCPU
21555 + bool "Enable Hard CPU Limits"
21556 + depends on EXPERIMENTAL
21559 + Activate the Hard CPU Limits
21561 + This will compile in code that allows the Token Bucket
21562 + Scheduler to put processes on hold when a context's
21563 + tokens are depleted (provided that its per-context
21564 + sched_hard flag is set).
21566 + Processes belonging to that context will not be able
21567 + to consume CPU resources again until a per-context
21568 + configured minimum of tokens has been reached.
21570 +config VSERVER_IDLETIME
21571 + bool "Avoid idle CPUs by skipping Time"
21572 + depends on VSERVER_HARDCPU
21575 + This option allows the scheduler to artificially
21576 + advance time (per cpu) when otherwise the idle
21577 + task would be scheduled, thus keeping the cpu
21578 + busy and sharing the available resources among
21579 + certain contexts.
21581 +config VSERVER_IDLELIMIT
21582 + bool "Limit the IDLE task"
21583 + depends on VSERVER_HARDCPU
21586 + Limit the idle slices, so the the next context
21587 + will be scheduled as soon as possible.
21589 + This might improve interactivity and latency, but
21590 + will also marginally increase scheduling overhead.
21593 + prompt "Persistent Inode Tagging"
21594 + default TAGGING_ID24
21596 + This adds persistent context information to filesystems
21597 + mounted with the tagxid option. Tagging is a requirement
21598 + for per-context disk limits and per-context quota.
21601 +config TAGGING_NONE
21604 + do not store per-context information in inodes.
21606 +config TAGGING_UID16
21607 + bool "UID16/GID32"
21609 + reduces UID to 16 bit, but leaves GID at 32 bit.
21611 +config TAGGING_GID16
21612 + bool "UID32/GID16"
21614 + reduces GID to 16 bit, but leaves UID at 32 bit.
21616 +config TAGGING_ID24
21617 + bool "UID24/GID24"
21619 + uses the upper 8bit from UID and GID for XID tagging
21620 + which leaves 24bit for UID/GID each, which should be
21621 + more than sufficient for normal use.
21623 +config TAGGING_INTERN
21624 + bool "UID32/GID32"
21626 + this uses otherwise reserved inode fields in the on
21627 + disk representation, which limits the use to a few
21628 + filesystems (currently ext2 and ext3)
21630 +config TAGGING_RUNTIME
21632 + depends on EXPERIMENTAL
21634 + inodes are tagged when first accessed, this doesn't
21635 + require any persistant information, but might give
21636 + funny results for mixed access.
21641 + bool "Tag NFSD User Auth and Files"
21644 + Enable this if you do want the in-kernel NFS
21645 + Server to use the tagging specified above.
21646 + (will require patched clients too)
21649 + bool "Enable Inode Tag Propagation"
21651 + depends on EXPERIMENTAL
21653 + This allows for the tagid= mount option to specify
21654 + a tagid which is to be used for the entire mount
21657 +config VSERVER_PRIVACY
21658 + bool "Honor Privacy Aspects of Guests"
21661 + When enabled, most context checks will disallow
21662 + access to structures assigned to a specific context,
21663 + like ptys or loop devices.
21665 +config VSERVER_DEBUG
21666 + bool "VServer Debugging Code"
21669 + Set this to yes if you want to be able to activate
21670 + debugging output at runtime. It adds a probably small
21671 + overhead to all vserver related functions and
21672 + increases the kernel size by about 20k.
21674 +config VSERVER_HISTORY
21675 + bool "VServer History Tracing"
21676 + depends on VSERVER_DEBUG
21679 + Set this to yes if you want to record the history of
21680 + linux-vserver activities, so they can be replayed in
21681 + the event of a kernel panic or oops.
21683 +config VSERVER_HISTORY_SIZE
21684 + int "Per-CPU History Size (32-65536)"
21685 + depends on VSERVER_HISTORY
21689 + This allows you to specify the number of entries in
21690 + the per-CPU history buffer.
21692 +config VSERVER_MONITOR
21693 + bool "VServer Scheduling Monitor"
21694 + depends on VSERVER_DEBUG
21697 + Set this to yes if you want to record the scheduling
21698 + decisions, so that they can be relayed to userspace
21699 + for detailed analysis.
21701 +config VSERVER_MONITOR_SIZE
21702 + int "Per-CPU Monitor Queue Size (32-65536)"
21703 + depends on VSERVER_MONITOR
21707 + This allows you to specify the number of entries in
21708 + the per-CPU scheduling monitor buffer.
21710 +config VSERVER_MONITOR_SYNC
21711 + int "Per-CPU Monitor Sync Interval (0-65536)"
21712 + depends on VSERVER_MONITOR
21716 + This allows you to specify the interval in ticks
21717 + when a time sync entry is inserted.
21728 +config VSERVER_SECURITY
21730 + depends on SECURITY
21732 + select SECURITY_CAPABILITIES
21734 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/Makefile linux-2.6.19.1-vs2.3.0.6/kernel/vserver/Makefile
21735 --- linux-2.6.19.1/kernel/vserver/Makefile 1970-01-01 01:00:00 +0100
21736 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/Makefile 2006-12-17 04:10:21 +0100
21739 +# Makefile for the Linux vserver routines.
21743 +obj-y += vserver.o
21745 +vserver-y := switch.o context.o space.o sched.o network.o inode.o \
21746 + limit.o cvirt.o cacct.o signal.o helper.o init.o dlimit.o
21748 +vserver-$(CONFIG_INET) += inet.o
21749 +vserver-$(CONFIG_PROC_FS) += proc.o
21750 +vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
21751 +vserver-$(CONFIG_VSERVER_HISTORY) += history.o
21752 +vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
21754 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cacct.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct.c
21755 --- linux-2.6.19.1/kernel/vserver/cacct.c 1970-01-01 01:00:00 +0100
21756 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct.c 2006-11-30 18:53:18 +0100
21759 + * linux/kernel/vserver/cacct.c
21761 + * Virtual Server: Context Accounting
21763 + * Copyright (C) 2006 Herbert Pötzl
21765 + * V0.01 added accounting stats
21769 +#include <linux/types.h>
21770 +#include <linux/sched.h>
21771 +#include <linux/vs_context.h>
21772 +#include <linux/vserver/switch.h>
21773 +#include <linux/vserver/cacct_cmd.h>
21774 +#include <linux/vserver/cacct_int.h>
21776 +#include <asm/errno.h>
21777 +#include <asm/uaccess.h>
21780 +int vc_sock_stat(struct vx_info *vxi, void __user *data)
21782 + struct vcmd_sock_stat_v0 vc_data;
21785 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
21788 + field = vc_data.field;
21789 + if ((field < 0) || (field >= VXA_SOCK_SIZE))
21792 + for (j=0; j<3; j++) {
21793 + vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
21794 + vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
21797 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
21802 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cacct_init.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct_init.h
21803 --- linux-2.6.19.1/kernel/vserver/cacct_init.h 1970-01-01 01:00:00 +0100
21804 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct_init.h 2006-11-08 04:57:49 +0100
21808 +static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
21813 + for (i=0; i<VXA_SOCK_SIZE; i++) {
21814 + for (j=0; j<3; j++) {
21815 + atomic_set(&cacct->sock[i][j].count, 0);
21816 + atomic_set(&cacct->sock[i][j].total, 0);
21819 + for (i=0; i<8; i++)
21820 + atomic_set(&cacct->slab[i], 0);
21821 + for (i=0; i<5; i++)
21822 + for (j=0; j<4; j++)
21823 + atomic_set(&cacct->page[i][j], 0);
21826 +static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
21831 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cacct_proc.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct_proc.h
21832 --- linux-2.6.19.1/kernel/vserver/cacct_proc.h 1970-01-01 01:00:00 +0100
21833 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct_proc.h 2006-11-08 04:57:49 +0100
21835 +#ifndef _VX_CACCT_PROC_H
21836 +#define _VX_CACCT_PROC_H
21838 +#include <linux/vserver/cacct_int.h>
21841 +#define VX_SOCKA_TOP \
21842 + "Type\t recv #/bytes\t\t send #/bytes\t\t fail #/bytes\n"
21844 +static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
21846 + int i,j, length = 0;
21847 + static char *type[VXA_SOCK_SIZE] = {
21848 + "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER" };
21850 + length += sprintf(buffer + length, VX_SOCKA_TOP);
21851 + for (i=0; i<VXA_SOCK_SIZE; i++) {
21852 + length += sprintf(buffer + length,
21854 + for (j=0; j<3; j++) {
21855 + length += sprintf(buffer + length,
21857 + ,vx_sock_count(cacct, i, j)
21858 + ,vx_sock_total(cacct, i, j)
21861 + buffer[length++] = '\n';
21864 + length += sprintf(buffer + length, "\n");
21865 + length += sprintf(buffer + length,
21866 + "slab:\t %8u %8u %8u %8u\n"
21867 + ,atomic_read(&cacct->slab[1])
21868 + ,atomic_read(&cacct->slab[4])
21869 + ,atomic_read(&cacct->slab[0])
21870 + ,atomic_read(&cacct->slab[2])
21873 + length += sprintf(buffer + length, "\n");
21874 + for (i=0; i<5; i++) {
21875 + length += sprintf(buffer + length,
21876 + "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n"
21878 + ,atomic_read(&cacct->page[i][0])
21879 + ,atomic_read(&cacct->page[i][1])
21880 + ,atomic_read(&cacct->page[i][2])
21881 + ,atomic_read(&cacct->page[i][3])
21882 + ,atomic_read(&cacct->page[i][4])
21883 + ,atomic_read(&cacct->page[i][5])
21884 + ,atomic_read(&cacct->page[i][6])
21885 + ,atomic_read(&cacct->page[i][7])
21892 +#endif /* _VX_CACCT_PROC_H */
21893 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/context.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/context.c
21894 --- linux-2.6.19.1/kernel/vserver/context.c 1970-01-01 01:00:00 +0100
21895 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/context.c 2006-12-17 05:32:40 +0100
21898 + * linux/kernel/vserver/context.c
21900 + * Virtual Server: Context Support
21902 + * Copyright (C) 2003-2006 Herbert Pötzl
21904 + * V0.01 context helper
21905 + * V0.02 vx_ctx_kill syscall command
21906 + * V0.03 replaced context_info calls
21907 + * V0.04 redesign of struct (de)alloc
21908 + * V0.05 rlimit basic implementation
21909 + * V0.06 task_xid and info commands
21910 + * V0.07 context flags and caps
21911 + * V0.08 switch to RCU based hash
21912 + * V0.09 revert to non RCU for now
21913 + * V0.10 and back to working RCU hash
21914 + * V0.11 and back to locking again
21915 + * V0.12 referenced context store
21916 + * V0.13 separate per cpu data
21917 + * V0.14 changed vcmds to vxi arg
21918 + * V0.15 added context stat
21922 +#include <linux/slab.h>
21923 +#include <linux/types.h>
21924 +#include <linux/namespace.h>
21926 +#include <linux/sched.h>
21927 +#include <linux/vserver/context.h>
21928 +#include <linux/vserver/network.h>
21929 +#include <linux/vserver/debug.h>
21930 +#include <linux/vserver/limit.h>
21931 +#include <linux/vserver/limit_int.h>
21932 +#include <linux/vserver/space.h>
21934 +#include <linux/vs_context.h>
21935 +#include <linux/vs_limit.h>
21936 +#include <linux/vserver/context_cmd.h>
21938 +#include <linux/err.h>
21939 +#include <asm/errno.h>
21941 +#include "cvirt_init.h"
21942 +#include "cacct_init.h"
21943 +#include "limit_init.h"
21944 +#include "sched_init.h"
21947 +atomic_t vx_global_ctotal = ATOMIC_INIT(0);
21948 +atomic_t vx_global_cactive = ATOMIC_INIT(0);
21951 +/* now inactive context structures */
21953 +static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
21955 +static spinlock_t vx_info_inactive_lock = SPIN_LOCK_UNLOCKED;
21958 +/* __alloc_vx_info()
21960 + * allocate an initialized vx_info struct
21961 + * doesn't make it visible (hash) */
21963 +static struct vx_info *__alloc_vx_info(xid_t xid)
21965 + struct vx_info *new = NULL;
21968 + vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
21970 + /* would this benefit from a slab cache? */
21971 + new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
21975 + memset (new, 0, sizeof(struct vx_info));
21977 + new->ptr_pc = alloc_percpu(struct _vx_info_pc);
21978 + if (!new->ptr_pc)
21981 + new->vx_id = xid;
21982 + INIT_HLIST_NODE(&new->vx_hlist);
21983 + atomic_set(&new->vx_usecnt, 0);
21984 + atomic_set(&new->vx_tasks, 0);
21985 + new->vx_parent = NULL;
21986 + new->vx_state = 0;
21987 + init_waitqueue_head(&new->vx_wait);
21989 + /* prepare reaper */
21990 + get_task_struct(child_reaper);
21991 + new->vx_reaper = child_reaper;
21993 + /* rest of init goes here */
21994 + vx_info_init_limit(&new->limit);
21995 + vx_info_init_sched(&new->sched);
21996 + vx_info_init_cvirt(&new->cvirt);
21997 + vx_info_init_cacct(&new->cacct);
21999 + /* per cpu data structures */
22000 + for_each_possible_cpu(cpu) {
22001 + vx_info_init_sched_pc(
22002 + &vx_per_cpu(new, sched_pc, cpu), cpu);
22003 + vx_info_init_cvirt_pc(
22004 + &vx_per_cpu(new, cvirt_pc, cpu), cpu);
22007 + new->vx_flags = VXF_INIT_SET;
22008 + new->vx_bcaps = CAP_INIT_EFF_SET;
22009 + new->vx_ccaps = 0;
22010 + new->vx_cap_bset = cap_bset;
22012 + new->reboot_cmd = 0;
22013 + new->exit_code = 0;
22015 + vxdprintk(VXD_CBIT(xid, 0),
22016 + "alloc_vx_info(%d) = %p", xid, new);
22017 + vxh_alloc_vx_info(new);
22018 + atomic_inc(&vx_global_ctotal);
22027 +/* __dealloc_vx_info()
22029 + * final disposal of vx_info */
22031 +static void __dealloc_vx_info(struct vx_info *vxi)
22035 + vxdprintk(VXD_CBIT(xid, 0),
22036 + "dealloc_vx_info(%p)", vxi);
22037 + vxh_dealloc_vx_info(vxi);
22041 + vx_info_exit_limit(&vxi->limit);
22042 + vx_info_exit_sched(&vxi->sched);
22043 + vx_info_exit_cvirt(&vxi->cvirt);
22044 + vx_info_exit_cacct(&vxi->cacct);
22046 + for_each_possible_cpu(cpu) {
22047 + vx_info_exit_sched_pc(
22048 + &vx_per_cpu(vxi, sched_pc, cpu), cpu);
22049 + vx_info_exit_cvirt_pc(
22050 + &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
22053 + vxi->vx_state |= VXS_RELEASED;
22056 + free_percpu(vxi->ptr_pc);
22059 + atomic_dec(&vx_global_ctotal);
22062 +static void __shutdown_vx_info(struct vx_info *vxi)
22064 + struct nsproxy *nsproxy;
22065 + struct fs_struct *fs;
22069 + vxi->vx_state |= VXS_SHUTDOWN;
22070 + vs_state_change(vxi, VSC_SHUTDOWN);
22072 + nsproxy = xchg(&vxi->vx_nsproxy, NULL);
22074 + put_nsproxy(nsproxy);
22076 + fs = xchg(&vxi->vx_fs, NULL);
22078 + put_fs_struct(fs);
22081 +/* exported stuff */
22083 +void free_vx_info(struct vx_info *vxi)
22085 + unsigned long flags;
22087 + /* context shutdown is mandatory */
22088 + BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
22090 + BUG_ON(atomic_read(&vxi->vx_usecnt));
22091 + BUG_ON(atomic_read(&vxi->vx_tasks));
22093 + BUG_ON(vx_info_state(vxi, VXS_HASHED));
22095 + BUG_ON(vxi->vx_nsproxy);
22096 + BUG_ON(vxi->vx_fs);
22098 + spin_lock_irqsave(&vx_info_inactive_lock, flags);
22099 + hlist_del(&vxi->vx_hlist);
22100 + spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
22102 + __dealloc_vx_info(vxi);
22106 +/* hash table for vx_info hash */
22108 +#define VX_HASH_SIZE 13
22110 +static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
22111 + { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
22113 +static spinlock_t vx_info_hash_lock = SPIN_LOCK_UNLOCKED;
22116 +static inline unsigned int __hashval(xid_t xid)
22118 + return (xid % VX_HASH_SIZE);
22123 +/* __hash_vx_info()
22125 + * add the vxi to the global hash table
22126 + * requires the hash_lock to be held */
22128 +static inline void __hash_vx_info(struct vx_info *vxi)
22130 + struct hlist_head *head;
22132 + vxd_assert_lock(&vx_info_hash_lock);
22133 + vxdprintk(VXD_CBIT(xid, 4),
22134 + "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
22135 + vxh_hash_vx_info(vxi);
22137 + /* context must not be hashed */
22138 + BUG_ON(vx_info_state(vxi, VXS_HASHED));
22140 + vxi->vx_state |= VXS_HASHED;
22141 + head = &vx_info_hash[__hashval(vxi->vx_id)];
22142 + hlist_add_head(&vxi->vx_hlist, head);
22143 + atomic_inc(&vx_global_cactive);
22146 +/* __unhash_vx_info()
22148 + * remove the vxi from the global hash table
22149 + * requires the hash_lock to be held */
22151 +static inline void __unhash_vx_info(struct vx_info *vxi)
22153 + unsigned long flags;
22155 + vxd_assert_lock(&vx_info_hash_lock);
22156 + vxdprintk(VXD_CBIT(xid, 4),
22157 + "__unhash_vx_info: %p[#%d]", vxi, vxi->vx_id);
22158 + vxh_unhash_vx_info(vxi);
22160 + /* context must be hashed */
22161 + BUG_ON(!vx_info_state(vxi, VXS_HASHED));
22163 + vxi->vx_state &= ~VXS_HASHED;
22164 + hlist_del_init(&vxi->vx_hlist);
22165 + spin_lock_irqsave(&vx_info_inactive_lock, flags);
22166 + hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
22167 + spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
22168 + atomic_dec(&vx_global_cactive);
22172 +/* __lookup_vx_info()
22174 + * requires the hash_lock to be held
22175 + * doesn't increment the vx_refcnt */
22177 +static inline struct vx_info *__lookup_vx_info(xid_t xid)
22179 + struct hlist_head *head = &vx_info_hash[__hashval(xid)];
22180 + struct hlist_node *pos;
22181 + struct vx_info *vxi;
22183 + vxd_assert_lock(&vx_info_hash_lock);
22184 + hlist_for_each(pos, head) {
22185 + vxi = hlist_entry(pos, struct vx_info, vx_hlist);
22187 + if (vxi->vx_id == xid)
22192 + vxdprintk(VXD_CBIT(xid, 0),
22193 + "__lookup_vx_info(#%u): %p[#%u]",
22194 + xid, vxi, vxi?vxi->vx_id:0);
22195 + vxh_lookup_vx_info(vxi, xid);
22200 +/* __create_vx_info()
22202 + * create the requested context
22203 + * get() and hash it */
22205 +static struct vx_info * __create_vx_info(int id)
22207 + struct vx_info *new, *vxi = NULL;
22209 + vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
22211 + if (!(new = __alloc_vx_info(id)))
22212 + return ERR_PTR(-ENOMEM);
22214 + /* required to make dynamic xids unique */
22215 + spin_lock(&vx_info_hash_lock);
22217 + /* static context requested */
22218 + if ((vxi = __lookup_vx_info(id))) {
22219 + vxdprintk(VXD_CBIT(xid, 0),
22220 + "create_vx_info(%d) = %p (already there)", id, vxi);
22221 + if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
22222 + vxi = ERR_PTR(-EBUSY);
22224 + vxi = ERR_PTR(-EEXIST);
22227 + /* new context */
22228 + vxdprintk(VXD_CBIT(xid, 0),
22229 + "create_vx_info(%d) = %p (new)", id, new);
22230 + __hash_vx_info(get_vx_info(new));
22231 + vxi = new, new = NULL;
22234 + spin_unlock(&vx_info_hash_lock);
22235 + vxh_create_vx_info(IS_ERR(vxi)?NULL:vxi, id);
22237 + __dealloc_vx_info(new);
22242 +/* exported stuff */
22245 +void unhash_vx_info(struct vx_info *vxi)
22247 + __shutdown_vx_info(vxi);
22248 + spin_lock(&vx_info_hash_lock);
22249 + __unhash_vx_info(vxi);
22250 + spin_unlock(&vx_info_hash_lock);
22251 + __wakeup_vx_info(vxi);
22255 +/* lookup_vx_info()
22257 + * search for a vx_info and get() it
22258 + * negative id means current */
22260 +struct vx_info *lookup_vx_info(int id)
22262 + struct vx_info *vxi = NULL;
22265 + vxi = get_vx_info(current->vx_info);
22266 + } else if (id > 1) {
22267 + spin_lock(&vx_info_hash_lock);
22268 + vxi = get_vx_info(__lookup_vx_info(id));
22269 + spin_unlock(&vx_info_hash_lock);
22274 +/* xid_is_hashed()
22276 + * verify that xid is still hashed */
22278 +int xid_is_hashed(xid_t xid)
22282 + spin_lock(&vx_info_hash_lock);
22283 + hashed = (__lookup_vx_info(xid) != NULL);
22284 + spin_unlock(&vx_info_hash_lock);
22288 +#ifdef CONFIG_PROC_FS
22292 + * get a subset of hashed xids for proc
22293 + * assumes size is at least one */
22295 +int get_xid_list(int index, unsigned int *xids, int size)
22297 + int hindex, nr_xids = 0;
22299 + /* only show current and children */
22300 + if (!vx_check(0, VS_ADMIN|VS_WATCH)) {
22303 + xids[nr_xids] = vx_current_xid();
22307 + for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
22308 + struct hlist_head *head = &vx_info_hash[hindex];
22309 + struct hlist_node *pos;
22311 + spin_lock(&vx_info_hash_lock);
22312 + hlist_for_each(pos, head) {
22313 + struct vx_info *vxi;
22318 + vxi = hlist_entry(pos, struct vx_info, vx_hlist);
22319 + xids[nr_xids] = vxi->vx_id;
22320 + if (++nr_xids >= size) {
22321 + spin_unlock(&vx_info_hash_lock);
22325 + /* keep the lock time short */
22326 + spin_unlock(&vx_info_hash_lock);
22333 +#ifdef CONFIG_VSERVER_DEBUG
22335 +void dump_vx_info_inactive(int level)
22337 + struct hlist_node *entry, *next;
22339 + hlist_for_each_safe(entry, next, &vx_info_inactive) {
22340 + struct vx_info *vxi =
22341 + list_entry(entry, struct vx_info, vx_hlist);
22343 + dump_vx_info(vxi, level);
22349 +int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
22351 + struct user_struct *new_user, *old_user;
22356 + if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
22359 + new_user = alloc_uid(vxi->vx_id, p->uid);
22363 + old_user = p->user;
22364 + if (new_user != old_user) {
22365 + atomic_inc(&new_user->processes);
22366 + atomic_dec(&old_user->processes);
22367 + p->user = new_user;
22369 + free_uid(old_user);
22373 +void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
22375 + p->cap_effective &= vxi->vx_cap_bset;
22376 + p->cap_inheritable &= vxi->vx_cap_bset;
22377 + p->cap_permitted &= vxi->vx_cap_bset;
22381 +#include <linux/file.h>
22383 +static int vx_openfd_task(struct task_struct *tsk)
22385 + struct files_struct *files = tsk->files;
22386 + struct fdtable *fdt;
22387 + const unsigned long *bptr;
22388 + int count, total;
22390 + /* no rcu_read_lock() because of spin_lock() */
22391 + spin_lock(&files->file_lock);
22392 + fdt = files_fdtable(files);
22393 + bptr = fdt->open_fds->fds_bits;
22394 + count = fdt->max_fds / (sizeof(unsigned long) * 8);
22395 + for (total = 0; count > 0; count--) {
22397 + total += hweight_long(*bptr);
22400 + spin_unlock(&files->file_lock);
22405 +/* for *space compatibility */
22407 +asmlinkage long sys_unshare(unsigned long);
22410 + * migrate task to new context
22411 + * gets vxi, puts old_vxi on change
22412 + * optionally unshares namespaces (hack)
22415 +int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare)
22417 + struct vx_info *old_vxi;
22423 + vxdprintk(VXD_CBIT(xid, 5),
22424 + "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
22425 + vxi->vx_id, atomic_read(&vxi->vx_usecnt));
22427 + if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) &&
22428 + !vx_info_flags(vxi, VXF_STATE_SETUP, 0))
22431 + old_vxi = task_get_vx_info(p);
22432 + if (old_vxi == vxi)
22435 + if (!(ret = vx_migrate_user(p, vxi))) {
22439 + openfd = vx_openfd_task(p);
22442 + atomic_dec(&old_vxi->cvirt.nr_threads);
22443 + atomic_dec(&old_vxi->cvirt.nr_running);
22444 + __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
22445 + /* FIXME: what about the struct files here? */
22446 + __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
22447 + /* account for the executable */
22448 + __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
22450 + atomic_inc(&vxi->cvirt.nr_threads);
22451 + atomic_inc(&vxi->cvirt.nr_running);
22452 + __rlim_inc(&vxi->limit, RLIMIT_NPROC);
22453 + /* FIXME: what about the struct files here? */
22454 + __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
22455 + /* account for the executable */
22456 + __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
22459 + release_vx_info(old_vxi, p);
22460 + clr_vx_info(&p->vx_info);
22462 + claim_vx_info(vxi, p);
22463 + set_vx_info(&p->vx_info, vxi);
22464 + p->xid = vxi->vx_id;
22466 + vxdprintk(VXD_CBIT(xid, 5),
22467 + "moved task %p into vxi:%p[#%d]",
22468 + p, vxi, vxi->vx_id);
22470 + vx_mask_cap_bset(vxi, p);
22473 + /* hack for *spaces to provide compatibility */
22475 + ret = sys_unshare(CLONE_NEWUTS|CLONE_NEWIPC);
22476 + vx_set_space(vxi, CLONE_NEWUTS|CLONE_NEWIPC);
22480 + put_vx_info(old_vxi);
22484 +int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
22486 + struct task_struct *old_reaper;
22491 + vxdprintk(VXD_CBIT(xid, 6),
22492 + "vx_set_reaper(%p[#%d],%p[#%d,%d])",
22493 + vxi, vxi->vx_id, p, p->xid, p->pid);
22495 + old_reaper = vxi->vx_reaper;
22496 + if (old_reaper == p)
22499 + /* set new child reaper */
22500 + get_task_struct(p);
22501 + vxi->vx_reaper = p;
22502 + put_task_struct(old_reaper);
22506 +int vx_set_init(struct vx_info *vxi, struct task_struct *p)
22511 + vxdprintk(VXD_CBIT(xid, 6),
22512 + "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
22513 + vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
22515 + vxi->vx_flags &= ~VXF_STATE_INIT;
22516 + vxi->vx_initpid = p->tgid;
22520 +void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
22522 + vxdprintk(VXD_CBIT(xid, 6),
22523 + "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
22524 + vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
22526 + vxi->exit_code = code;
22527 + vxi->vx_initpid = 0;
22531 +void vx_set_persistent(struct vx_info *vxi)
22533 + vxdprintk(VXD_CBIT(xid, 6),
22534 + "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
22536 + get_vx_info(vxi);
22537 + claim_vx_info(vxi, current);
22540 +void vx_clear_persistent(struct vx_info *vxi)
22542 + vxdprintk(VXD_CBIT(xid, 6),
22543 + "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
22545 + release_vx_info(vxi, current);
22546 + put_vx_info(vxi);
22549 +void vx_update_persistent(struct vx_info *vxi)
22551 + if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
22552 + vx_set_persistent(vxi);
22554 + vx_clear_persistent(vxi);
22558 +/* task must be current or locked */
22560 +void exit_vx_info(struct task_struct *p, int code)
22562 + struct vx_info *vxi = p->vx_info;
22565 + atomic_dec(&vxi->cvirt.nr_threads);
22568 + vxi->exit_code = code;
22569 + release_vx_info(vxi, p);
22573 +void exit_vx_info_early(struct task_struct *p, int code)
22575 + struct vx_info *vxi = p->vx_info;
22578 + if (vxi->vx_initpid == p->tgid)
22579 + vx_exit_init(vxi, p, code);
22580 + if (vxi->vx_reaper == p)
22581 + vx_set_reaper(vxi, child_reaper);
22586 +/* vserver syscall commands below here */
22588 +/* taks xid and vx_info functions */
22590 +#include <asm/uaccess.h>
22593 +int vc_task_xid(uint32_t id, void __user *data)
22598 + struct task_struct *tsk;
22600 + if (!vx_check(0, VS_ADMIN|VS_WATCH))
22603 + read_lock(&tasklist_lock);
22604 + tsk = find_task_by_real_pid(id);
22605 + xid = (tsk) ? tsk->xid : -ESRCH;
22606 + read_unlock(&tasklist_lock);
22609 + xid = vx_current_xid();
22614 +int vc_vx_info(struct vx_info *vxi, void __user *data)
22616 + struct vcmd_vx_info_v0 vc_data;
22618 + vc_data.xid = vxi->vx_id;
22619 + vc_data.initpid = vxi->vx_initpid;
22621 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22627 +int vc_ctx_stat(struct vx_info *vxi, void __user *data)
22629 + struct vcmd_ctx_stat_v0 vc_data;
22631 + vc_data.usecnt = atomic_read(&vxi->vx_usecnt);
22632 + vc_data.tasks = atomic_read(&vxi->vx_tasks);
22634 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22640 +/* context functions */
22642 +int vc_ctx_create(uint32_t xid, void __user *data)
22644 + struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
22645 + struct vx_info *new_vxi;
22648 + if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
22651 + if ((xid > MAX_S_CONTEXT) || (xid < 2))
22654 + new_vxi = __create_vx_info(xid);
22655 + if (IS_ERR(new_vxi))
22656 + return PTR_ERR(new_vxi);
22658 + /* initial flags */
22659 + new_vxi->vx_flags = vc_data.flagword;
22661 + /* get a reference for persistent contexts */
22662 + if ((vc_data.flagword & VXF_PERSISTENT))
22663 + vx_set_persistent(new_vxi);
22666 + if (vs_state_change(new_vxi, VSC_STARTUP))
22668 + ret = vx_migrate_task(current, new_vxi, (!data));
22670 + /* return context id on success */
22671 + ret = new_vxi->vx_id;
22675 + /* prepare for context disposal */
22676 + new_vxi->vx_state |= VXS_SHUTDOWN;
22677 + if ((vc_data.flagword & VXF_PERSISTENT))
22678 + vx_clear_persistent(new_vxi);
22679 + __unhash_vx_info(new_vxi);
22681 + put_vx_info(new_vxi);
22686 +int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
22688 + struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
22691 + if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
22694 + ret = vx_migrate_task(current, vxi, 0);
22697 + if (vc_data.flagword & VXM_SET_INIT)
22698 + ret = vx_set_init(vxi, current);
22701 + if (vc_data.flagword & VXM_SET_REAPER)
22702 + ret = vx_set_reaper(vxi, current);
22707 +int vc_get_cflags(struct vx_info *vxi, void __user *data)
22709 + struct vcmd_ctx_flags_v0 vc_data;
22711 + vc_data.flagword = vxi->vx_flags;
22713 + /* special STATE flag handling */
22714 + vc_data.mask = vs_mask_flags(~0UL, vxi->vx_flags, VXF_ONE_TIME);
22716 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22721 +int vc_set_cflags(struct vx_info *vxi, void __user *data)
22723 + struct vcmd_ctx_flags_v0 vc_data;
22724 + uint64_t mask, trigger;
22726 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22729 + /* special STATE flag handling */
22730 + mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
22731 + trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
22733 + if (vxi == current->vx_info) {
22734 + if (trigger & VXF_STATE_SETUP)
22735 + vx_mask_cap_bset(vxi, current);
22736 + if (trigger & VXF_STATE_INIT) {
22739 + ret = vx_set_init(vxi, current);
22742 + ret = vx_set_reaper(vxi, current);
22748 + vxi->vx_flags = vs_mask_flags(vxi->vx_flags,
22749 + vc_data.flagword, mask);
22750 + if (trigger & VXF_PERSISTENT)
22751 + vx_update_persistent(vxi);
22756 +static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
22759 + *bcaps = vxi->vx_bcaps;
22761 + *ccaps = vxi->vx_ccaps;
22766 +int vc_get_ccaps_v0(struct vx_info *vxi, void __user *data)
22768 + struct vcmd_ctx_caps_v0 vc_data;
22771 + ret = do_get_caps(vxi, &vc_data.bcaps, &vc_data.ccaps);
22774 + vc_data.cmask = ~0UL;
22776 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22781 +int vc_get_ccaps(struct vx_info *vxi, void __user *data)
22783 + struct vcmd_ctx_caps_v1 vc_data;
22786 + ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
22789 + vc_data.cmask = ~0UL;
22791 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22796 +static int do_set_caps(struct vx_info *vxi,
22797 + uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
22799 + vxi->vx_bcaps = vs_mask_flags(vxi->vx_bcaps, bcaps, bmask);
22800 + vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask);
22805 +int vc_set_ccaps_v0(struct vx_info *vxi, void __user *data)
22807 + struct vcmd_ctx_caps_v0 vc_data;
22809 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22812 + /* simulate old &= behaviour for bcaps */
22813 + return do_set_caps(vxi, 0, ~vc_data.bcaps,
22814 + vc_data.ccaps, vc_data.cmask);
22817 +int vc_set_ccaps(struct vx_info *vxi, void __user *data)
22819 + struct vcmd_ctx_caps_v1 vc_data;
22821 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22824 + return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
22827 +int vc_get_bcaps(struct vx_info *vxi, void __user *data)
22829 + struct vcmd_bcaps vc_data;
22832 + ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
22835 + vc_data.bmask = ~0UL;
22837 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22842 +int vc_set_bcaps(struct vx_info *vxi, void __user *data)
22844 + struct vcmd_bcaps vc_data;
22846 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22849 + return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
22852 +#include <linux/module.h>
22854 +EXPORT_SYMBOL_GPL(free_vx_info);
22856 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cvirt.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt.c
22857 --- linux-2.6.19.1/kernel/vserver/cvirt.c 1970-01-01 01:00:00 +0100
22858 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt.c 2006-11-14 02:30:02 +0100
22861 + * linux/kernel/vserver/cvirt.c
22863 + * Virtual Server: Context Virtualization
22865 + * Copyright (C) 2004-2006 Herbert Pötzl
22867 + * V0.01 broken out from limit.c
22868 + * V0.02 added utsname stuff
22869 + * V0.03 changed vcmds to vxi arg
22873 +#include <linux/sched.h>
22874 +#include <linux/sysctl.h>
22875 +#include <linux/types.h>
22876 +#include <linux/vs_context.h>
22877 +#include <linux/vs_cvirt.h>
22878 +#include <linux/vserver/switch.h>
22879 +#include <linux/vserver/cvirt_cmd.h>
22880 +//#include <linux/vserver/cacct_cmd.h>
22882 +#include <asm/errno.h>
22883 +#include <asm/uaccess.h>
22886 +void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
22888 + struct vx_info *vxi = current->vx_info;
22890 + set_normalized_timespec(uptime,
22891 + uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
22892 + uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
22895 + set_normalized_timespec(idle,
22896 + idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
22897 + idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
22901 +uint64_t vx_idle_jiffies(void)
22903 + return init_task.utime + init_task.stime;
22908 +static inline uint32_t __update_loadavg(uint32_t load,
22909 + int wsize, int delta, int n)
22911 + unsigned long long calc, prev;
22913 + /* just set it to n */
22914 + if (unlikely(delta >= wsize))
22915 + return (n << FSHIFT);
22917 + calc = delta * n;
22919 + prev = (wsize - delta);
22922 + do_div(calc, wsize);
22927 +void vx_update_load(struct vx_info *vxi)
22929 + uint32_t now, last, delta;
22930 + unsigned int nr_running, nr_uninterruptible;
22931 + unsigned int total;
22932 + unsigned long flags;
22934 + spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
22937 + last = vxi->cvirt.load_last;
22938 + delta = now - last;
22940 + if (delta < 5*HZ)
22943 + nr_running = atomic_read(&vxi->cvirt.nr_running);
22944 + nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
22945 + total = nr_running + nr_uninterruptible;
22947 + vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
22948 + 60*HZ, delta, total);
22949 + vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
22950 + 5*60*HZ, delta, total);
22951 + vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
22952 + 15*60*HZ, delta, total);
22954 + vxi->cvirt.load_last = now;
22956 + atomic_inc(&vxi->cvirt.load_updates);
22957 + spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
22962 + * Commands to do_syslog:
22964 + * 0 -- Close the log. Currently a NOP.
22965 + * 1 -- Open the log. Currently a NOP.
22966 + * 2 -- Read from the log.
22967 + * 3 -- Read all messages remaining in the ring buffer.
22968 + * 4 -- Read and clear all messages remaining in the ring buffer
22969 + * 5 -- Clear ring buffer.
22970 + * 6 -- Disable printk's to console
22971 + * 7 -- Enable printk's to console
22972 + * 8 -- Set level of messages printed to console
22973 + * 9 -- Return number of unread characters in the log buffer
22974 + * 10 -- Return size of the log buffer
22976 +int vx_do_syslog(int type, char __user *buf, int len)
22979 + int do_clear = 0;
22980 + struct vx_info *vxi = current->vx_info;
22981 + struct _vx_syslog *log;
22985 + log = &vxi->cvirt.syslog;
22988 + case 0: /* Close log */
22989 + case 1: /* Open log */
22991 + case 2: /* Read from log */
22992 + error = wait_event_interruptible(log->log_wait,
22993 + (log->log_start - log->log_end));
22996 + spin_lock_irq(&log->logbuf_lock);
22997 + spin_unlock_irq(&log->logbuf_lock);
22999 + case 4: /* Read/clear last kernel messages */
23001 + /* fall through */
23002 + case 3: /* Read last kernel messages */
23005 + case 5: /* Clear ring buffer */
23008 + case 6: /* Disable logging to console */
23009 + case 7: /* Enable logging to console */
23010 + case 8: /* Set level of messages printed to console */
23013 + case 9: /* Number of chars in the log buffer */
23015 + case 10: /* Size of the log buffer */
23025 +/* virtual host info names */
23027 +static char * vx_vhi_name(struct vx_info *vxi, int id)
23029 + struct nsproxy *nsproxy;
23030 + struct uts_namespace *uts;
23033 + if (id == VHIN_CONTEXT)
23034 + return vxi->vx_name;
23036 + nsproxy = vxi->vx_nsproxy;
23040 + uts = nsproxy->uts_ns;
23045 + case VHIN_SYSNAME:
23046 + return uts->name.sysname;
23047 + case VHIN_NODENAME:
23048 + return uts->name.nodename;
23049 + case VHIN_RELEASE:
23050 + return uts->name.release;
23051 + case VHIN_VERSION:
23052 + return uts->name.version;
23053 + case VHIN_MACHINE:
23054 + return uts->name.machine;
23055 + case VHIN_DOMAINNAME:
23056 + return uts->name.domainname;
23063 +int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
23065 + struct vcmd_vhi_name_v0 vc_data;
23068 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23071 + name = vx_vhi_name(vxi, vc_data.field);
23075 + memcpy(name, vc_data.name, 65);
23079 +int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
23081 + struct vcmd_vhi_name_v0 vc_data;
23084 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23087 + name = vx_vhi_name(vxi, vc_data.field);
23091 + memcpy(vc_data.name, name, 65);
23092 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
23098 +int vc_virt_stat(struct vx_info *vxi, void __user *data)
23100 + struct vcmd_virt_stat_v0 vc_data;
23101 + struct _vx_cvirt *cvirt = &vxi->cvirt;
23102 + struct timespec uptime;
23104 + do_posix_clock_monotonic_gettime(&uptime);
23105 + set_normalized_timespec(&uptime,
23106 + uptime.tv_sec - cvirt->bias_uptime.tv_sec,
23107 + uptime.tv_nsec - cvirt->bias_uptime.tv_nsec);
23109 + vc_data.offset = timeval_to_ns(&cvirt->bias_tv);
23110 + vc_data.uptime = timespec_to_ns(&uptime);
23111 + vc_data.nr_threads = atomic_read(&cvirt->nr_threads);
23112 + vc_data.nr_running = atomic_read(&cvirt->nr_running);
23113 + vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible);
23114 + vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold);
23115 + vc_data.nr_forks = atomic_read(&cvirt->total_forks);
23116 + vc_data.load[0] = cvirt->load[0];
23117 + vc_data.load[1] = cvirt->load[1];
23118 + vc_data.load[2] = cvirt->load[2];
23120 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
23126 +#ifdef CONFIG_VSERVER_VTIME
23128 +/* virtualized time base */
23130 +void vx_gettimeofday(struct timeval *tv)
23132 + do_gettimeofday(tv);
23133 + if (!vx_flags(VXF_VIRT_TIME, 0))
23136 + tv->tv_sec += current->vx_info->cvirt.bias_tv.tv_sec;
23137 + tv->tv_usec += current->vx_info->cvirt.bias_tv.tv_usec;
23139 + if (tv->tv_usec >= USEC_PER_SEC) {
23141 + tv->tv_usec -= USEC_PER_SEC;
23142 + } else if (tv->tv_usec < 0) {
23144 + tv->tv_usec += USEC_PER_SEC;
23148 +int vx_settimeofday(struct timespec *ts)
23150 + struct timeval tv;
23152 + if (!vx_flags(VXF_VIRT_TIME, 0))
23153 + return do_settimeofday(ts);
23155 + do_gettimeofday(&tv);
23156 + current->vx_info->cvirt.bias_tv.tv_sec =
23157 + ts->tv_sec - tv.tv_sec;
23158 + current->vx_info->cvirt.bias_tv.tv_usec =
23159 + (ts->tv_nsec/NSEC_PER_USEC) - tv.tv_usec;
23165 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cvirt_init.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt_init.h
23166 --- linux-2.6.19.1/kernel/vserver/cvirt_init.h 1970-01-01 01:00:00 +0100
23167 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt_init.h 2006-11-14 02:11:41 +0100
23171 +extern uint64_t vx_idle_jiffies(void);
23173 +static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
23175 + uint64_t idle_jiffies = vx_idle_jiffies();
23176 + uint64_t nsuptime;
23178 + do_posix_clock_monotonic_gettime(&cvirt->bias_uptime);
23179 + nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
23180 + * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
23181 + cvirt->bias_clock = nsec_to_clock_t(nsuptime);
23182 + cvirt->bias_tv.tv_sec = 0;
23183 + cvirt->bias_tv.tv_usec = 0;
23185 + jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle);
23186 + atomic_set(&cvirt->nr_threads, 0);
23187 + atomic_set(&cvirt->nr_running, 0);
23188 + atomic_set(&cvirt->nr_uninterruptible, 0);
23189 + atomic_set(&cvirt->nr_onhold, 0);
23191 + spin_lock_init(&cvirt->load_lock);
23192 + cvirt->load_last = jiffies;
23193 + atomic_set(&cvirt->load_updates, 0);
23194 + cvirt->load[0] = 0;
23195 + cvirt->load[1] = 0;
23196 + cvirt->load[2] = 0;
23197 + atomic_set(&cvirt->total_forks, 0);
23199 + spin_lock_init(&cvirt->syslog.logbuf_lock);
23200 + init_waitqueue_head(&cvirt->syslog.log_wait);
23201 + cvirt->syslog.log_start = 0;
23202 + cvirt->syslog.log_end = 0;
23203 + cvirt->syslog.con_start = 0;
23204 + cvirt->syslog.logged_chars = 0;
23208 +void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
23210 + // cvirt_pc->cpustat = { 0 };
23213 +static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
23215 +#ifdef CONFIG_VSERVER_DEBUG
23218 + vxwprintk((value = atomic_read(&cvirt->nr_threads)),
23219 + "!!! cvirt: %p[nr_threads] = %d on exit.",
23221 + vxwprintk((value = atomic_read(&cvirt->nr_running)),
23222 + "!!! cvirt: %p[nr_running] = %d on exit.",
23224 + vxwprintk((value = atomic_read(&cvirt->nr_uninterruptible)),
23225 + "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
23227 + vxwprintk((value = atomic_read(&cvirt->nr_onhold)),
23228 + "!!! cvirt: %p[nr_onhold] = %d on exit.",
23235 +void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
23240 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cvirt_proc.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt_proc.h
23241 --- linux-2.6.19.1/kernel/vserver/cvirt_proc.h 1970-01-01 01:00:00 +0100
23242 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt_proc.h 2006-11-14 03:08:43 +0100
23244 +#ifndef _VX_CVIRT_PROC_H
23245 +#define _VX_CVIRT_PROC_H
23247 +#include <linux/nsproxy.h>
23248 +#include <linux/namespace.h>
23249 +#include <linux/utsname.h>
23250 +#include <linux/ipc.h>
23254 +int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer)
23256 + struct namespace *ns;
23257 + struct uts_namespace *uts;
23258 + struct ipc_namespace *ipc;
23259 + struct vfsmount *mnt;
23260 + char *path, *root;
23266 + length += sprintf(buffer + length,
23267 + "NSProxy:\t%p [%p,%p,%p]\n",
23268 + nsproxy, nsproxy->namespace,
23269 + nsproxy->uts_ns, nsproxy->ipc_ns);
23271 + ns = nsproxy->namespace;
23275 + path = kmalloc(PATH_MAX, GFP_KERNEL);
23280 + root = d_path(mnt->mnt_root, mnt->mnt_parent, path, PATH_MAX-2);
23281 + length += sprintf(buffer + length,
23282 + "Namespace:\t%p [#%u]\n"
23283 + "RootPath:\t%s\n"
23284 + ,ns , atomic_read(&ns->count)
23289 + uts = nsproxy->uts_ns;
23293 + length += sprintf(buffer + length,
23294 + "SysName:\t%.*s\n"
23295 + "NodeName:\t%.*s\n"
23296 + "Release:\t%.*s\n"
23297 + "Version:\t%.*s\n"
23298 + "Machine:\t%.*s\n"
23299 + "DomainName:\t%.*s\n"
23300 + ,__NEW_UTS_LEN, uts->name.sysname
23301 + ,__NEW_UTS_LEN, uts->name.nodename
23302 + ,__NEW_UTS_LEN, uts->name.release
23303 + ,__NEW_UTS_LEN, uts->name.version
23304 + ,__NEW_UTS_LEN, uts->name.machine
23305 + ,__NEW_UTS_LEN, uts->name.domainname
23309 + ipc = nsproxy->ipc_ns;
23313 + length += sprintf(buffer + length,
23314 + "SEMS:\t\t%d %d %d %d %d\n"
23315 + "MSG:\t\t%d %d %d\n"
23316 + "SHM:\t\t%lu %lu %d %d\n"
23317 + ,ipc->sem_ctls[0], ipc->sem_ctls[1]
23318 + ,ipc->sem_ctls[2], ipc->sem_ctls[3]
23320 + ,ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni
23321 + ,(unsigned long)ipc->shm_ctlmax
23322 + ,(unsigned long)ipc->shm_ctlall
23323 + ,ipc->shm_ctlmni, ipc->shm_tot
23332 +#include <linux/sched.h>
23334 +#define LOAD_INT(x) ((x) >> FSHIFT)
23335 +#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
23338 +int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
23343 + length += sprintf(buffer + length,
23344 + "BiasUptime:\t%lu.%02lu\n",
23345 + (unsigned long)cvirt->bias_uptime.tv_sec,
23346 + (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
23348 + a = cvirt->load[0] + (FIXED_1/200);
23349 + b = cvirt->load[1] + (FIXED_1/200);
23350 + c = cvirt->load[2] + (FIXED_1/200);
23351 + length += sprintf(buffer + length,
23352 + "nr_threads:\t%d\n"
23353 + "nr_running:\t%d\n"
23354 + "nr_unintr:\t%d\n"
23355 + "nr_onhold:\t%d\n"
23356 + "load_updates:\t%d\n"
23357 + "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
23358 + "total_forks:\t%d\n"
23359 + ,atomic_read(&cvirt->nr_threads)
23360 + ,atomic_read(&cvirt->nr_running)
23361 + ,atomic_read(&cvirt->nr_uninterruptible)
23362 + ,atomic_read(&cvirt->nr_onhold)
23363 + ,atomic_read(&cvirt->load_updates)
23364 + ,LOAD_INT(a), LOAD_FRAC(a)
23365 + ,LOAD_INT(b), LOAD_FRAC(b)
23366 + ,LOAD_INT(c), LOAD_FRAC(c)
23367 + ,atomic_read(&cvirt->total_forks)
23374 +int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
23375 + char *buffer, int cpu)
23381 +#endif /* _VX_CVIRT_PROC_H */
23382 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/debug.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/debug.c
23383 --- linux-2.6.19.1/kernel/vserver/debug.c 1970-01-01 01:00:00 +0100
23384 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/debug.c 2006-11-30 18:53:18 +0100
23387 + * kernel/vserver/debug.c
23389 + * Copyright (C) 2005 Herbert Pötzl
23391 + * V0.01 vx_info dump support
23395 +#include <linux/errno.h>
23396 +#include <linux/kernel.h>
23397 +#include <linux/module.h>
23398 +#include <linux/vs_base.h>
23400 +#include <linux/vserver/context.h>
23403 +void dump_vx_info(struct vx_info *vxi, int level)
23405 + printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
23406 + atomic_read(&vxi->vx_usecnt),
23407 + atomic_read(&vxi->vx_tasks),
23410 + __dump_vx_limit(&vxi->limit);
23411 + __dump_vx_sched(&vxi->sched);
23412 + __dump_vx_cvirt(&vxi->cvirt);
23413 + __dump_vx_cacct(&vxi->cacct);
23419 +EXPORT_SYMBOL_GPL(dump_vx_info);
23421 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/dlimit.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/dlimit.c
23422 --- linux-2.6.19.1/kernel/vserver/dlimit.c 1970-01-01 01:00:00 +0100
23423 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/dlimit.c 2006-11-08 04:57:50 +0100
23426 + * linux/kernel/vserver/dlimit.c
23428 + * Virtual Server: Context Disk Limits
23430 + * Copyright (C) 2004-2005 Herbert Pötzl
23432 + * V0.01 initial version
23433 + * V0.02 compat32 splitup
23437 +#include <linux/fs.h>
23438 +#include <linux/namespace.h>
23439 +#include <linux/namei.h>
23440 +#include <linux/statfs.h>
23441 +#include <linux/compat.h>
23442 +#include <linux/vserver/switch.h>
23443 +#include <linux/vs_context.h>
23444 +#include <linux/vs_tag.h>
23445 +#include <linux/vs_dlimit.h>
23446 +#include <linux/vserver/dlimit_cmd.h>
23448 +#include <asm/errno.h>
23449 +#include <asm/uaccess.h>
23451 +/* __alloc_dl_info()
23453 + * allocate an initialized dl_info struct
23454 + * doesn't make it visible (hash) */
23456 +static struct dl_info *__alloc_dl_info(struct super_block *sb, tag_t tag)
23458 + struct dl_info *new = NULL;
23460 + vxdprintk(VXD_CBIT(dlim, 5),
23461 + "alloc_dl_info(%p,%d)*", sb, tag);
23463 + /* would this benefit from a slab cache? */
23464 + new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
23468 + memset (new, 0, sizeof(struct dl_info));
23469 + new->dl_tag = tag;
23471 + INIT_RCU_HEAD(&new->dl_rcu);
23472 + INIT_HLIST_NODE(&new->dl_hlist);
23473 + spin_lock_init(&new->dl_lock);
23474 + atomic_set(&new->dl_refcnt, 0);
23475 + atomic_set(&new->dl_usecnt, 0);
23477 + /* rest of init goes here */
23479 + vxdprintk(VXD_CBIT(dlim, 4),
23480 + "alloc_dl_info(%p,%d) = %p", sb, tag, new);
23484 +/* __dealloc_dl_info()
23486 + * final disposal of dl_info */
23488 +static void __dealloc_dl_info(struct dl_info *dli)
23490 + vxdprintk(VXD_CBIT(dlim, 4),
23491 + "dealloc_dl_info(%p)", dli);
23493 + dli->dl_hlist.next = LIST_POISON1;
23494 + dli->dl_tag = -1;
23497 + BUG_ON(atomic_read(&dli->dl_usecnt));
23498 + BUG_ON(atomic_read(&dli->dl_refcnt));
23504 +/* hash table for dl_info hash */
23506 +#define DL_HASH_SIZE 13
23508 +struct hlist_head dl_info_hash[DL_HASH_SIZE];
23510 +static spinlock_t dl_info_hash_lock = SPIN_LOCK_UNLOCKED;
23513 +static inline unsigned int __hashval(struct super_block *sb, tag_t tag)
23515 + return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
23520 +/* __hash_dl_info()
23522 + * add the dli to the global hash table
23523 + * requires the hash_lock to be held */
23525 +static inline void __hash_dl_info(struct dl_info *dli)
23527 + struct hlist_head *head;
23529 + vxdprintk(VXD_CBIT(dlim, 6),
23530 + "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
23531 + get_dl_info(dli);
23532 + head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
23533 + hlist_add_head_rcu(&dli->dl_hlist, head);
23536 +/* __unhash_dl_info()
23538 + * remove the dli from the global hash table
23539 + * requires the hash_lock to be held */
23541 +static inline void __unhash_dl_info(struct dl_info *dli)
23543 + vxdprintk(VXD_CBIT(dlim, 6),
23544 + "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
23545 + hlist_del_rcu(&dli->dl_hlist);
23546 + put_dl_info(dli);
23550 +/* __lookup_dl_info()
23552 + * requires the rcu_read_lock()
23553 + * doesn't increment the dl_refcnt */
23555 +static inline struct dl_info *__lookup_dl_info(struct super_block *sb, tag_t tag)
23557 + struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
23558 + struct hlist_node *pos;
23559 + struct dl_info *dli;
23561 + hlist_for_each_entry_rcu(dli, pos, head, dl_hlist) {
23563 + if (dli->dl_tag == tag && dli->dl_sb == sb) {
23571 +struct dl_info *locate_dl_info(struct super_block *sb, tag_t tag)
23573 + struct dl_info *dli;
23576 + dli = get_dl_info(__lookup_dl_info(sb, tag));
23577 + vxdprintk(VXD_CBIT(dlim, 7),
23578 + "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
23579 + rcu_read_unlock();
23583 +void rcu_free_dl_info(struct rcu_head *head)
23585 + struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
23586 + int usecnt, refcnt;
23588 + BUG_ON(!dli || !head);
23590 + usecnt = atomic_read(&dli->dl_usecnt);
23591 + BUG_ON(usecnt < 0);
23593 + refcnt = atomic_read(&dli->dl_refcnt);
23594 + BUG_ON(refcnt < 0);
23596 + vxdprintk(VXD_CBIT(dlim, 3),
23597 + "rcu_free_dl_info(%p)", dli);
23599 + __dealloc_dl_info(dli);
23601 + printk("!!! rcu didn't free\n");
23607 +static int do_addrem_dlimit(uint32_t id, const char __user *name,
23608 + uint32_t flags, int add)
23610 + struct nameidata nd;
23613 + ret = user_path_walk_link(name, &nd);
23615 + struct super_block *sb;
23616 + struct dl_info *dli;
23619 + if (!nd.dentry->d_inode)
23620 + goto out_release;
23621 + if (!(sb = nd.dentry->d_inode->i_sb))
23622 + goto out_release;
23625 + dli = __alloc_dl_info(sb, id);
23626 + spin_lock(&dl_info_hash_lock);
23629 + if (__lookup_dl_info(sb, id))
23631 + __hash_dl_info(dli);
23634 + spin_lock(&dl_info_hash_lock);
23635 + dli = __lookup_dl_info(sb, id);
23640 + __unhash_dl_info(dli);
23644 + spin_unlock(&dl_info_hash_lock);
23646 + __dealloc_dl_info(dli);
23648 + path_release(&nd);
23653 +int vc_add_dlimit(uint32_t id, void __user *data)
23655 + struct vcmd_ctx_dlimit_base_v0 vc_data;
23657 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23660 + return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
23663 +int vc_rem_dlimit(uint32_t id, void __user *data)
23665 + struct vcmd_ctx_dlimit_base_v0 vc_data;
23667 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23670 + return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
23673 +#ifdef CONFIG_COMPAT
23675 +int vc_add_dlimit_x32(uint32_t id, void __user *data)
23677 + struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
23679 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23682 + return do_addrem_dlimit(id,
23683 + compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
23686 +int vc_rem_dlimit_x32(uint32_t id, void __user *data)
23688 + struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
23690 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23693 + return do_addrem_dlimit(id,
23694 + compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
23697 +#endif /* CONFIG_COMPAT */
23701 +int do_set_dlimit(uint32_t id, const char __user *name,
23702 + uint32_t space_used, uint32_t space_total,
23703 + uint32_t inodes_used, uint32_t inodes_total,
23704 + uint32_t reserved, uint32_t flags)
23706 + struct nameidata nd;
23709 + ret = user_path_walk_link(name, &nd);
23711 + struct super_block *sb;
23712 + struct dl_info *dli;
23715 + if (!nd.dentry->d_inode)
23716 + goto out_release;
23717 + if (!(sb = nd.dentry->d_inode->i_sb))
23718 + goto out_release;
23719 + if ((reserved != CDLIM_KEEP &&
23720 + reserved > 100) ||
23721 + (inodes_used != CDLIM_KEEP &&
23722 + inodes_used > inodes_total) ||
23723 + (space_used != CDLIM_KEEP &&
23724 + space_used > space_total))
23725 + goto out_release;
23728 + dli = locate_dl_info(sb, id);
23730 + goto out_release;
23732 + spin_lock(&dli->dl_lock);
23734 + if (inodes_used != CDLIM_KEEP)
23735 + dli->dl_inodes_used = inodes_used;
23736 + if (inodes_total != CDLIM_KEEP)
23737 + dli->dl_inodes_total = inodes_total;
23738 + if (space_used != CDLIM_KEEP) {
23739 + dli->dl_space_used = space_used;
23740 + dli->dl_space_used <<= 10;
23742 + if (space_total == CDLIM_INFINITY)
23743 + dli->dl_space_total = DLIM_INFINITY;
23744 + else if (space_total != CDLIM_KEEP) {
23745 + dli->dl_space_total = space_total;
23746 + dli->dl_space_total <<= 10;
23748 + if (reserved != CDLIM_KEEP)
23749 + dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
23751 + spin_unlock(&dli->dl_lock);
23753 + put_dl_info(dli);
23757 + path_release(&nd);
23762 +int vc_set_dlimit(uint32_t id, void __user *data)
23764 + struct vcmd_ctx_dlimit_v0 vc_data;
23766 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23769 + return do_set_dlimit(id, vc_data.name,
23770 + vc_data.space_used, vc_data.space_total,
23771 + vc_data.inodes_used, vc_data.inodes_total,
23772 + vc_data.reserved, vc_data.flags);
23775 +#ifdef CONFIG_COMPAT
23777 +int vc_set_dlimit_x32(uint32_t id, void __user *data)
23779 + struct vcmd_ctx_dlimit_v0_x32 vc_data;
23781 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23784 + return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
23785 + vc_data.space_used, vc_data.space_total,
23786 + vc_data.inodes_used, vc_data.inodes_total,
23787 + vc_data.reserved, vc_data.flags);
23790 +#endif /* CONFIG_COMPAT */
23794 +int do_get_dlimit(uint32_t id, const char __user *name,
23795 + uint32_t *space_used, uint32_t *space_total,
23796 + uint32_t *inodes_used, uint32_t *inodes_total,
23797 + uint32_t *reserved, uint32_t *flags)
23799 + struct nameidata nd;
23802 + ret = user_path_walk_link(name, &nd);
23804 + struct super_block *sb;
23805 + struct dl_info *dli;
23808 + if (!nd.dentry->d_inode)
23809 + goto out_release;
23810 + if (!(sb = nd.dentry->d_inode->i_sb))
23811 + goto out_release;
23814 + dli = locate_dl_info(sb, id);
23816 + goto out_release;
23818 + spin_lock(&dli->dl_lock);
23819 + *inodes_used = dli->dl_inodes_used;
23820 + *inodes_total = dli->dl_inodes_total;
23821 + *space_used = dli->dl_space_used >> 10;
23822 + if (dli->dl_space_total == DLIM_INFINITY)
23823 + *space_total = CDLIM_INFINITY;
23825 + *space_total = dli->dl_space_total >> 10;
23827 + *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
23828 + spin_unlock(&dli->dl_lock);
23830 + put_dl_info(dli);
23835 + path_release(&nd);
23841 +int vc_get_dlimit(uint32_t id, void __user *data)
23843 + struct vcmd_ctx_dlimit_v0 vc_data;
23846 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23849 + ret = do_get_dlimit(id, vc_data.name,
23850 + &vc_data.space_used, &vc_data.space_total,
23851 + &vc_data.inodes_used, &vc_data.inodes_total,
23852 + &vc_data.reserved, &vc_data.flags);
23856 + if (copy_to_user(data, &vc_data, sizeof(vc_data)))
23861 +#ifdef CONFIG_COMPAT
23863 +int vc_get_dlimit_x32(uint32_t id, void __user *data)
23865 + struct vcmd_ctx_dlimit_v0_x32 vc_data;
23868 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23871 + ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
23872 + &vc_data.space_used, &vc_data.space_total,
23873 + &vc_data.inodes_used, &vc_data.inodes_total,
23874 + &vc_data.reserved, &vc_data.flags);
23878 + if (copy_to_user(data, &vc_data, sizeof(vc_data)))
23883 +#endif /* CONFIG_COMPAT */
23886 +void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
23888 + struct dl_info *dli;
23889 + __u64 blimit, bfree, bavail;
23892 + dli = locate_dl_info(sb, dx_current_tag());
23896 + spin_lock(&dli->dl_lock);
23897 + if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
23900 + /* reduce max inodes available to limit */
23901 + if (buf->f_files > dli->dl_inodes_total)
23902 + buf->f_files = dli->dl_inodes_total;
23904 + ifree = dli->dl_inodes_total - dli->dl_inodes_used;
23905 + /* reduce free inodes to min */
23906 + if (ifree < buf->f_ffree)
23907 + buf->f_ffree = ifree;
23910 + if (dli->dl_space_total == DLIM_INFINITY)
23913 + blimit = dli->dl_space_total >> sb->s_blocksize_bits;
23915 + if (dli->dl_space_total < dli->dl_space_used)
23918 + bfree = (dli->dl_space_total - dli->dl_space_used)
23919 + >> sb->s_blocksize_bits;
23921 + bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
23922 + if (bavail < dli->dl_space_used)
23925 + bavail = (bavail - dli->dl_space_used)
23926 + >> sb->s_blocksize_bits;
23928 + /* reduce max space available to limit */
23929 + if (buf->f_blocks > blimit)
23930 + buf->f_blocks = blimit;
23932 + /* reduce free space to min */
23933 + if (bfree < buf->f_bfree)
23934 + buf->f_bfree = bfree;
23936 + /* reduce avail space to min */
23937 + if (bavail < buf->f_bavail)
23938 + buf->f_bavail = bavail;
23941 + spin_unlock(&dli->dl_lock);
23942 + put_dl_info(dli);
23947 +#include <linux/module.h>
23949 +EXPORT_SYMBOL_GPL(locate_dl_info);
23950 +EXPORT_SYMBOL_GPL(rcu_free_dl_info);
23952 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/helper.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/helper.c
23953 --- linux-2.6.19.1/kernel/vserver/helper.c 1970-01-01 01:00:00 +0100
23954 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/helper.c 2006-12-17 04:34:43 +0100
23957 + * linux/kernel/vserver/helper.c
23959 + * Virtual Context Support
23961 + * Copyright (C) 2004-2005 Herbert Pötzl
23963 + * V0.01 basic helper
23967 +#include <linux/errno.h>
23968 +#include <linux/kmod.h>
23969 +#include <linux/sched.h>
23970 +#include <linux/reboot.h>
23971 +#include <linux/vs_context.h>
23972 +#include <linux/vs_network.h>
23973 +#include <linux/vserver/signal.h>
23975 +#include <asm/uaccess.h>
23976 +#include <asm/unistd.h>
23979 +char vshelper_path[255] = "/sbin/vshelper";
23982 +static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
23986 + if ((ret = call_usermodehelper(name, argv, envp, sync))) {
23987 + printk( KERN_WARNING
23988 + "%s: (%s %s) returned %s with %d\n",
23989 + name, argv[1], argv[2],
23990 + sync?"sync":"async", ret);
23992 + vxdprintk(VXD_CBIT(switch, 4),
23993 + "%s: (%s %s) returned %s with %d",
23994 + name, argv[1], argv[2], sync?"sync":"async", ret);
23999 + * vshelper path is set via /proc/sys
24000 + * invoked by vserver sys_reboot(), with
24001 + * the following arguments
24003 + * argv [0] = vshelper_path;
24004 + * argv [1] = action: "restart", "halt", "poweroff", ...
24005 + * argv [2] = context identifier
24007 + * envp [*] = type-specific parameters
24010 +long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
24012 + char id_buf[8], cmd_buf[16];
24013 + char uid_buf[16], pid_buf[16];
24016 + char *argv[] = {vshelper_path, NULL, id_buf, 0};
24017 + char *envp[] = {"HOME=/", "TERM=linux",
24018 + "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
24019 + uid_buf, pid_buf, cmd_buf, 0};
24021 + if (vx_info_state(vxi, VXS_HELPER))
24023 + vxi->vx_state |= VXS_HELPER;
24025 + snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
24027 + snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
24028 + snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid);
24029 + snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid);
24032 + case LINUX_REBOOT_CMD_RESTART:
24033 + argv[1] = "restart";
24036 + case LINUX_REBOOT_CMD_HALT:
24037 + argv[1] = "halt";
24040 + case LINUX_REBOOT_CMD_POWER_OFF:
24041 + argv[1] = "poweroff";
24044 + case LINUX_REBOOT_CMD_SW_SUSPEND:
24045 + argv[1] = "swsusp";
24049 + vxi->vx_state &= ~VXS_HELPER;
24053 + ret = do_vshelper(vshelper_path, argv, envp, 0);
24054 + vxi->vx_state &= ~VXS_HELPER;
24055 + __wakeup_vx_info(vxi);
24056 + return (ret) ? -EPERM : 0;
24060 +long vs_reboot(unsigned int cmd, void __user * arg)
24062 + struct vx_info *vxi = current->vx_info;
24065 + vxdprintk(VXD_CBIT(misc, 5),
24066 + "vs_reboot(%p[#%d],%d)",
24067 + vxi, vxi?vxi->vx_id:0, cmd);
24069 + ret = vs_reboot_helper(vxi, cmd, arg);
24073 + vxi->reboot_cmd = cmd;
24074 + if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
24076 + case LINUX_REBOOT_CMD_RESTART:
24077 + case LINUX_REBOOT_CMD_HALT:
24078 + case LINUX_REBOOT_CMD_POWER_OFF:
24079 + vx_info_kill(vxi, 0, SIGKILL);
24080 + vx_info_kill(vxi, 1, SIGKILL);
24090 + * argv [0] = vshelper_path;
24091 + * argv [1] = action: "startup", "shutdown"
24092 + * argv [2] = context identifier
24094 + * envp [*] = type-specific parameters
24097 +long vs_state_change(struct vx_info *vxi, unsigned int cmd)
24099 + char id_buf[8], cmd_buf[16];
24100 + char *argv[] = {vshelper_path, NULL, id_buf, 0};
24101 + char *envp[] = {"HOME=/", "TERM=linux",
24102 + "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
24104 + if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
24107 + snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
24108 + snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
24111 + case VSC_STARTUP:
24112 + argv[1] = "startup";
24114 + case VSC_SHUTDOWN:
24115 + argv[1] = "shutdown";
24121 + return do_vshelper(vshelper_path, argv, envp, 1);
24126 + * argv [0] = vshelper_path;
24127 + * argv [1] = action: "netup", "netdown"
24128 + * argv [2] = context identifier
24130 + * envp [*] = type-specific parameters
24133 +long vs_net_change(struct nx_info *nxi, unsigned int cmd)
24135 + char id_buf[8], cmd_buf[16];
24136 + char *argv[] = {vshelper_path, NULL, id_buf, 0};
24137 + char *envp[] = {"HOME=/", "TERM=linux",
24138 + "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
24140 + if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
24143 + snprintf(id_buf, sizeof(id_buf)-1, "%d", nxi->nx_id);
24144 + snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
24148 + argv[1] = "netup";
24150 + case VSC_NETDOWN:
24151 + argv[1] = "netdown";
24157 + return do_vshelper(vshelper_path, argv, envp, 1);
24160 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/history.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/history.c
24161 --- linux-2.6.19.1/kernel/vserver/history.c 1970-01-01 01:00:00 +0100
24162 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/history.c 2006-11-30 18:53:18 +0100
24165 + * kernel/vserver/history.c
24167 + * Virtual Context History Backtrace
24169 + * Copyright (C) 2004-2005 Herbert Pötzl
24171 + * V0.01 basic structure
24172 + * V0.02 hash/unhash and trace
24173 + * V0.03 preemption fixes
24177 +#include <linux/errno.h>
24178 +#include <linux/module.h>
24179 +#include <linux/types.h>
24180 +#include <linux/ctype.h>
24182 +#include <asm/uaccess.h>
24183 +#include <asm/atomic.h>
24184 +#include <asm/unistd.h>
24186 +#include <linux/vserver/context.h>
24187 +#include <linux/vserver/debug.h>
24188 +#include <linux/vserver/debug_cmd.h>
24189 +#include <linux/vserver/history.h>
24192 +#ifdef CONFIG_VSERVER_HISTORY
24193 +#define VXH_SIZE CONFIG_VSERVER_HISTORY_SIZE
24195 +#define VXH_SIZE 64
24198 +struct _vx_history {
24199 + unsigned int counter;
24201 + struct _vx_hist_entry entry[VXH_SIZE+1];
24205 +DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
24207 +unsigned volatile int vxh_active = 1;
24209 +static atomic_t sequence = ATOMIC_INIT(0);
24214 + * requires disabled preemption */
24216 +struct _vx_hist_entry *vxh_advance(void *loc)
24218 + unsigned int cpu = smp_processor_id();
24219 + struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
24220 + struct _vx_hist_entry *entry;
24221 + unsigned int index;
24223 + index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
24224 + entry = &hist->entry[index];
24226 + entry->seq = atomic_inc_return(&sequence);
24227 + entry->loc = loc;
24231 +EXPORT_SYMBOL_GPL(vxh_advance);
24234 +#define VXH_LOC_FMTS "(#%04x,*%d):%p"
24236 +#define VXH_LOC_ARGS(e) (e)->seq, cpu, (e)->loc
24239 +#define VXH_VXI_FMTS "%p[#%d,%d.%d]"
24241 +#define VXH_VXI_ARGS(e) (e)->vxi.ptr, \
24242 + (e)->vxi.ptr?(e)->vxi.xid:0, \
24243 + (e)->vxi.ptr?(e)->vxi.usecnt:0, \
24244 + (e)->vxi.ptr?(e)->vxi.tasks:0
24246 +void vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
24248 + switch (e->type) {
24249 + case VXH_THROW_OOPS:
24250 + printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
24253 + case VXH_GET_VX_INFO:
24254 + case VXH_PUT_VX_INFO:
24255 + printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
24257 + (e->type==VXH_GET_VX_INFO)?"get":"put",
24258 + VXH_VXI_ARGS(e));
24261 + case VXH_INIT_VX_INFO:
24262 + case VXH_SET_VX_INFO:
24263 + case VXH_CLR_VX_INFO:
24264 + printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
24266 + (e->type==VXH_INIT_VX_INFO)?"init":
24267 + ((e->type==VXH_SET_VX_INFO)?"set":"clr"),
24268 + VXH_VXI_ARGS(e), e->sc.data);
24271 + case VXH_CLAIM_VX_INFO:
24272 + case VXH_RELEASE_VX_INFO:
24273 + printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
24275 + (e->type==VXH_CLAIM_VX_INFO)?"claim":"release",
24276 + VXH_VXI_ARGS(e), e->sc.data);
24279 + case VXH_ALLOC_VX_INFO:
24280 + case VXH_DEALLOC_VX_INFO:
24281 + printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
24283 + (e->type==VXH_ALLOC_VX_INFO)?"alloc":"dealloc",
24284 + VXH_VXI_ARGS(e));
24287 + case VXH_HASH_VX_INFO:
24288 + case VXH_UNHASH_VX_INFO:
24289 + printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
24291 + (e->type==VXH_HASH_VX_INFO)?"hash":"unhash",
24292 + VXH_VXI_ARGS(e));
24295 + case VXH_LOC_VX_INFO:
24296 + case VXH_LOOKUP_VX_INFO:
24297 + case VXH_CREATE_VX_INFO:
24298 + printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
24300 + (e->type==VXH_CREATE_VX_INFO)?"create":
24301 + ((e->type==VXH_LOC_VX_INFO)?"loc":"lookup"),
24302 + e->ll.arg, VXH_VXI_ARGS(e));
24307 +static void __vxh_dump_history(void)
24309 + unsigned int i, cpu;
24311 + printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
24312 + atomic_read(&sequence), NR_CPUS);
24314 + for (i=0; i < VXH_SIZE; i++) {
24315 + for_each_online_cpu(cpu) {
24316 + struct _vx_history *hist =
24317 + &per_cpu(vx_history_buffer, cpu);
24318 + unsigned int index = (hist->counter-i) % VXH_SIZE;
24319 + struct _vx_hist_entry *entry = &hist->entry[index];
24321 + vxh_dump_entry(entry, cpu);
24326 +void vxh_dump_history(void)
24330 + local_irq_enable();
24332 + local_irq_disable();
24334 + __vxh_dump_history();
24338 +/* vserver syscall commands below here */
24341 +int vc_dump_history(uint32_t id)
24344 + __vxh_dump_history();
24351 +int do_read_history(struct __user _vx_hist_entry *data,
24352 + int cpu, uint32_t *index, uint32_t *count)
24354 + int pos, ret = 0;
24355 + struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
24356 + int end = hist->counter;
24357 + int start = end - VXH_SIZE + 2;
24358 + int idx = *index;
24360 + /* special case: get current pos */
24366 + /* have we lost some data? */
24370 + for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
24371 + struct _vx_hist_entry *entry =
24372 + &hist->entry[idx % VXH_SIZE];
24374 + /* send entry to userspace */
24375 + ret = copy_to_user (&data[pos], entry, sizeof(*entry));
24379 + /* save new index and count */
24382 + return ret ? ret : (*index < end);
24385 +int vc_read_history(uint32_t id, void __user *data)
24387 + struct vcmd_read_history_v0 vc_data;
24390 + if (id >= NR_CPUS)
24393 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24396 + ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data,
24397 + id, &vc_data.index, &vc_data.count);
24399 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24404 +#ifdef CONFIG_COMPAT
24406 +int vc_read_history_x32(uint32_t id, void __user *data)
24408 + struct vcmd_read_history_v0_x32 vc_data;
24411 + if (id >= NR_CPUS)
24414 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24417 + ret = do_read_history((struct __user _vx_hist_entry *)
24418 + compat_ptr(vc_data.data_ptr),
24419 + id, &vc_data.index, &vc_data.count);
24421 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24426 +#endif /* CONFIG_COMPAT */
24428 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/inet.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/inet.c
24429 --- linux-2.6.19.1/kernel/vserver/inet.c 1970-01-01 01:00:00 +0100
24430 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/inet.c 2006-12-17 03:23:33 +0100
24433 +#include <linux/sched.h>
24434 +#include <linux/vs_inet.h>
24437 +int nx_addr_conflict(struct nx_info *nxi, uint32_t addr, struct sock *sk)
24439 + vxdprintk(VXD_CBIT(net, 2),
24440 + "nx_addr_conflict(%p,%p) %d.%d,%d.%d",
24441 + nxi, sk, VXD_QUAD(addr));
24444 + /* check real address */
24445 + return __addr_in_socket(sk, addr);
24446 + } else if (nxi) {
24447 + /* check against nx_info */
24448 + int i, n = nxi->nbipv4;
24450 + for (i=0; i<n; i++)
24451 + if (__addr_in_socket(sk, nxi->ipv4[i]))
24455 + /* check against any */
24461 +int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
24463 + struct in_device *in_dev;
24464 + struct in_ifaddr **ifap;
24465 + struct in_ifaddr *ifa;
24471 + in_dev = in_dev_get(dev);
24475 + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
24476 + ifap = &ifa->ifa_next) {
24477 + if (addr_in_nx_info(nxi, ifa->ifa_local)) {
24482 + in_dev_put(in_dev);
24488 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/init.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/init.c
24489 --- linux-2.6.19.1/kernel/vserver/init.c 1970-01-01 01:00:00 +0100
24490 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/init.c 2006-11-09 01:00:34 +0100
24493 + * linux/kernel/init.c
24495 + * Virtual Server Init
24497 + * Copyright (C) 2004-2005 Herbert Pötzl
24499 + * V0.01 basic structure
24503 +#include <linux/errno.h>
24504 +#include <linux/init.h>
24505 +#include <linux/module.h>
24507 +int vserver_register_sysctl(void);
24508 +void vserver_unregister_sysctl(void);
24511 +static int __init init_vserver(void)
24515 +#ifdef CONFIG_VSERVER_DEBUG
24516 + vserver_register_sysctl();
24522 +static void __exit exit_vserver(void)
24525 +#ifdef CONFIG_VSERVER_DEBUG
24526 + vserver_unregister_sysctl();
24531 +/* FIXME: GFP_ZONETYPES gone
24532 +long vx_slab[GFP_ZONETYPES]; */
24536 +module_init(init_vserver);
24537 +module_exit(exit_vserver);
24539 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/inode.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/inode.c
24540 --- linux-2.6.19.1/kernel/vserver/inode.c 1970-01-01 01:00:00 +0100
24541 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/inode.c 2006-12-17 04:29:30 +0100
24544 + * linux/kernel/vserver/inode.c
24546 + * Virtual Server: File System Support
24548 + * Copyright (C) 2004-2005 Herbert Pötzl
24550 + * V0.01 separated from vcontext V0.05
24554 +#include <linux/sched.h>
24555 +#include <linux/proc_fs.h>
24556 +#include <linux/devpts_fs.h>
24557 +#include <linux/namei.h>
24558 +#include <linux/mount.h>
24559 +#include <linux/parser.h>
24560 +#include <linux/compat.h>
24561 +#include <linux/vserver/inode.h>
24562 +#include <linux/vserver/inode_cmd.h>
24563 +#include <linux/vs_base.h>
24564 +#include <linux/vs_tag.h>
24566 +#include <asm/errno.h>
24567 +#include <asm/uaccess.h>
24570 +static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
24572 + struct proc_dir_entry *entry;
24574 + if (!in || !in->i_sb)
24577 + *flags = IATTR_TAG
24578 + | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
24579 + | (IS_IUNLINK(in) ? IATTR_IUNLINK : 0)
24580 + | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0);
24581 + *mask = IATTR_IUNLINK | IATTR_IMMUTABLE;
24583 + if (S_ISDIR(in->i_mode))
24584 + *mask |= IATTR_BARRIER;
24586 + if (IS_TAGGED(in)) {
24587 + *tag = in->i_tag;
24588 + *mask |= IATTR_TAG;
24591 + switch (in->i_sb->s_magic) {
24592 + case PROC_SUPER_MAGIC:
24593 + entry = PROC_I(in)->pde;
24595 + /* check for specific inodes? */
24597 + *mask |= IATTR_FLAGS;
24599 + *flags |= (entry->vx_flags & IATTR_FLAGS);
24601 + *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
24604 + case DEVPTS_SUPER_MAGIC:
24605 + *tag = in->i_tag;
24606 + *mask |= IATTR_TAG;
24615 +int vc_get_iattr(uint32_t id, void __user *data)
24617 + struct nameidata nd;
24618 + struct vcmd_ctx_iattr_v1 vc_data = { .xid = -1 };
24621 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24624 + ret = user_path_walk_link(vc_data.name, &nd);
24626 + ret = __vc_get_iattr(nd.dentry->d_inode,
24627 + &vc_data.xid, &vc_data.flags, &vc_data.mask);
24628 + path_release(&nd);
24633 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24638 +#ifdef CONFIG_COMPAT
24640 +int vc_get_iattr_x32(uint32_t id, void __user *data)
24642 + struct nameidata nd;
24643 + struct vcmd_ctx_iattr_v1_x32 vc_data = { .xid = -1 };
24646 + if (!vx_check(0, VS_ADMIN))
24648 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24651 + ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
24653 + ret = __vc_get_iattr(nd.dentry->d_inode,
24654 + &vc_data.xid, &vc_data.flags, &vc_data.mask);
24655 + path_release(&nd);
24660 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24665 +#endif /* CONFIG_COMPAT */
24668 +static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
24670 + struct inode *in = de->d_inode;
24671 + int error = 0, is_proc = 0, has_tag = 0;
24672 + struct iattr attr = { 0 };
24674 + if (!in || !in->i_sb)
24677 + is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
24678 + if ((*mask & IATTR_FLAGS) && !is_proc)
24681 + has_tag = IS_TAGGED(in) ||
24682 + (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
24683 + if ((*mask & IATTR_TAG) && !has_tag)
24686 + mutex_lock(&in->i_mutex);
24687 + if (*mask & IATTR_TAG) {
24688 + attr.ia_tag = *tag;
24689 + attr.ia_valid |= ATTR_TAG;
24692 + if (*mask & IATTR_FLAGS) {
24693 + struct proc_dir_entry *entry = PROC_I(in)->pde;
24694 + unsigned int iflags = PROC_I(in)->vx_flags;
24696 + iflags = (iflags & ~(*mask & IATTR_FLAGS))
24697 + | (*flags & IATTR_FLAGS);
24698 + PROC_I(in)->vx_flags = iflags;
24700 + entry->vx_flags = iflags;
24703 + if (*mask & (IATTR_BARRIER | IATTR_IUNLINK | IATTR_IMMUTABLE)) {
24704 + if (*mask & IATTR_IMMUTABLE) {
24705 + if (*flags & IATTR_IMMUTABLE)
24706 + in->i_flags |= S_IMMUTABLE;
24708 + in->i_flags &= ~S_IMMUTABLE;
24710 + if (*mask & IATTR_IUNLINK) {
24711 + if (*flags & IATTR_IUNLINK)
24712 + in->i_flags |= S_IUNLINK;
24714 + in->i_flags &= ~S_IUNLINK;
24716 + if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
24717 + if (*flags & IATTR_BARRIER)
24718 + in->i_flags |= S_BARRIER;
24720 + in->i_flags &= ~S_BARRIER;
24722 + if (in->i_op && in->i_op->sync_flags) {
24723 + error = in->i_op->sync_flags(in);
24729 + if (attr.ia_valid) {
24730 + if (in->i_op && in->i_op->setattr)
24731 + error = in->i_op->setattr(de, &attr);
24733 + error = inode_change_ok(in, &attr);
24735 + error = inode_setattr(in, &attr);
24740 + mutex_unlock(&in->i_mutex);
24744 +int vc_set_iattr(uint32_t id, void __user *data)
24746 + struct nameidata nd;
24747 + struct vcmd_ctx_iattr_v1 vc_data;
24750 + if (!capable(CAP_LINUX_IMMUTABLE))
24752 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24755 + ret = user_path_walk_link(vc_data.name, &nd);
24757 + ret = __vc_set_iattr(nd.dentry,
24758 + &vc_data.xid, &vc_data.flags, &vc_data.mask);
24759 + path_release(&nd);
24762 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24767 +#ifdef CONFIG_COMPAT
24769 +int vc_set_iattr_x32(uint32_t id, void __user *data)
24771 + struct nameidata nd;
24772 + struct vcmd_ctx_iattr_v1_x32 vc_data;
24775 + if (!capable(CAP_LINUX_IMMUTABLE))
24777 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24780 + ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
24782 + ret = __vc_set_iattr(nd.dentry,
24783 + &vc_data.xid, &vc_data.flags, &vc_data.mask);
24784 + path_release(&nd);
24787 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24792 +#endif /* CONFIG_COMPAT */
24795 +#ifdef CONFIG_PROPAGATE
24797 +int dx_parse_tag(char *string, tag_t *tag, int remove)
24799 + static match_table_t tokens = {
24803 + substring_t args[MAX_OPT_ARGS];
24804 + int token, option = 0;
24809 + token = match_token(string, tokens, args);
24810 + if (token && tag && !match_int(args, &option))
24813 + vxdprintk(VXD_CBIT(tag, 7),
24814 + "dx_parse_tag(»%s«): %d:#%d",
24815 + string, token, option);
24817 + if ((token == 1) && remove) {
24818 + char *p = strstr(string, "tagid=");
24822 + while (*q != '\0' && *q != ',')
24833 +void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
24835 + tag_t new_tag = 0;
24836 + struct vfsmount *mnt;
24845 + propagate = (mnt->mnt_flags & MNT_TAGID);
24847 + new_tag = mnt->mnt_tag;
24849 + vxdprintk(VXD_CBIT(tag, 7),
24850 + "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
24851 + inode, inode->i_ino, inode->i_tag,
24852 + new_tag, (propagate)?1:0);
24855 + inode->i_tag = new_tag;
24858 +#include <linux/module.h>
24860 +EXPORT_SYMBOL_GPL(__dx_propagate_tag);
24862 +#endif /* CONFIG_PROPAGATE */
24864 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/limit.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit.c
24865 --- linux-2.6.19.1/kernel/vserver/limit.c 1970-01-01 01:00:00 +0100
24866 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit.c 2006-11-30 19:32:53 +0100
24869 + * linux/kernel/vserver/limit.c
24871 + * Virtual Server: Context Limits
24873 + * Copyright (C) 2004-2006 Herbert Pötzl
24875 + * V0.01 broken out from vcontext V0.05
24876 + * V0.02 changed vcmds to vxi arg
24880 +#include <linux/module.h>
24881 +#include <linux/vs_context.h>
24882 +#include <linux/vs_limit.h>
24883 +#include <linux/vserver/limit.h>
24884 +#include <linux/vserver/switch.h>
24885 +#include <linux/vserver/limit_cmd.h>
24887 +#include <asm/errno.h>
24888 +#include <asm/uaccess.h>
24891 +const char *vlimit_name[NUM_LIMITS] = {
24892 + [RLIMIT_CPU] = "CPU",
24893 + [RLIMIT_RSS] = "RSS",
24894 + [RLIMIT_NPROC] = "NPROC",
24895 + [RLIMIT_NOFILE] = "NOFILE",
24896 + [RLIMIT_MEMLOCK] = "VML",
24897 + [RLIMIT_AS] = "VM",
24898 + [RLIMIT_LOCKS] = "LOCKS",
24899 + [RLIMIT_SIGPENDING] = "SIGP",
24900 + [RLIMIT_MSGQUEUE] = "MSGQ",
24902 + [VLIMIT_NSOCK] = "NSOCK",
24903 + [VLIMIT_OPENFD] = "OPENFD",
24904 + [VLIMIT_ANON] = "ANON",
24905 + [VLIMIT_SHMEM] = "SHMEM",
24906 + [VLIMIT_DENTRY] = "DENTRY",
24909 +EXPORT_SYMBOL_GPL(vlimit_name);
24911 +#define MASK_ENTRY(x) (1 << (x))
24913 +const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
24916 + , /* softlimit */
24917 + MASK_ENTRY( RLIMIT_RSS ) |
24918 + MASK_ENTRY( VLIMIT_ANON ) |
24921 + MASK_ENTRY( RLIMIT_RSS ) |
24922 + MASK_ENTRY( RLIMIT_NPROC ) |
24923 + MASK_ENTRY( RLIMIT_NOFILE ) |
24924 + MASK_ENTRY( RLIMIT_MEMLOCK ) |
24925 + MASK_ENTRY( RLIMIT_AS ) |
24926 + MASK_ENTRY( RLIMIT_LOCKS ) |
24927 + MASK_ENTRY( RLIMIT_MSGQUEUE ) |
24929 + MASK_ENTRY( VLIMIT_NSOCK ) |
24930 + MASK_ENTRY( VLIMIT_OPENFD ) |
24931 + MASK_ENTRY( VLIMIT_ANON ) |
24932 + MASK_ENTRY( VLIMIT_SHMEM ) |
24933 + MASK_ENTRY( VLIMIT_DENTRY ) |
24936 + /* accounting only */
24937 +uint32_t account_mask =
24938 + MASK_ENTRY( VLIMIT_SEMARY ) |
24939 + MASK_ENTRY( VLIMIT_NSEMS ) |
24943 +static int is_valid_vlimit(int id)
24945 + uint32_t mask = vlimit_mask.minimum |
24946 + vlimit_mask.softlimit | vlimit_mask.maximum;
24947 + return mask & (1 << id);
24950 +static int is_accounted_vlimit(int id)
24952 + if (is_valid_vlimit(id))
24954 + return account_mask & (1 << id);
24958 +static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
24960 + rlim_t limit = __rlim_soft(&vxi->limit, id);
24961 + return VX_VLIM(limit);
24964 +static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
24966 + rlim_t limit = __rlim_hard(&vxi->limit, id);
24967 + return VX_VLIM(limit);
24970 +static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
24971 + uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
24973 + if (!is_valid_vlimit(id))
24977 + *minimum = CRLIM_UNSET;
24979 + *softlimit = vc_get_soft(vxi, id);
24981 + *maximum = vc_get_hard(vxi, id);
24985 +int vc_get_rlimit(struct vx_info *vxi, void __user *data)
24987 + struct vcmd_ctx_rlimit_v0 vc_data;
24990 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24993 + ret = do_get_rlimit(vxi, vc_data.id,
24994 + &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
24998 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25003 +static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
25004 + uint64_t minimum, uint64_t softlimit, uint64_t maximum)
25006 + if (!is_valid_vlimit(id))
25009 + if (maximum != CRLIM_KEEP)
25010 + __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
25011 + if (softlimit != CRLIM_KEEP)
25012 + __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
25014 + /* clamp soft limit */
25015 + if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
25016 + __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
25021 +int vc_set_rlimit(struct vx_info *vxi, void __user *data)
25023 + struct vcmd_ctx_rlimit_v0 vc_data;
25025 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25028 + return do_set_rlimit(vxi, vc_data.id,
25029 + vc_data.minimum, vc_data.softlimit, vc_data.maximum);
25032 +#ifdef CONFIG_IA32_EMULATION
25034 +int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
25036 + struct vcmd_ctx_rlimit_v0_x32 vc_data;
25038 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25041 + return do_set_rlimit(vxi, vc_data.id,
25042 + vc_data.minimum, vc_data.softlimit, vc_data.maximum);
25045 +int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
25047 + struct vcmd_ctx_rlimit_v0_x32 vc_data;
25050 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25053 + ret = do_get_rlimit(vxi, vc_data.id,
25054 + &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
25058 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25063 +#endif /* CONFIG_IA32_EMULATION */
25066 +int vc_get_rlimit_mask(uint32_t id, void __user *data)
25068 + if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
25074 +static inline void vx_reset_minmax(struct _vx_limit *limit)
25079 + for (lim=0; lim<NUM_LIMITS; lim++) {
25080 + value = __rlim_get(limit, lim);
25081 + __rlim_rmax(limit, lim) = value;
25082 + __rlim_rmin(limit, lim) = value;
25087 +int vc_reset_minmax(struct vx_info *vxi, void __user *data)
25089 + vx_reset_minmax(&vxi->limit);
25094 +int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
25096 + struct vcmd_rlimit_stat_v0 vc_data;
25097 + struct _vx_limit *limit = &vxi->limit;
25100 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25104 + if (!is_accounted_vlimit(id))
25107 + vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
25108 + vc_data.value = __rlim_get(limit, id);
25109 + vc_data.minimum = __rlim_rmin(limit, id);
25110 + vc_data.maximum = __rlim_rmax(limit, id);
25112 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25118 +void vx_vsi_meminfo(struct sysinfo *val)
25120 + struct vx_info *vxi = current->vx_info;
25121 + unsigned long totalram, freeram;
25124 + /* we blindly accept the max */
25125 + v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
25126 + totalram = (v != RLIM_INFINITY) ? v : val->totalram;
25128 + /* total minus used equals free */
25129 + v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
25130 + freeram = (v < totalram) ? totalram - v : 0;
25132 + val->totalram = totalram;
25133 + val->freeram = freeram;
25134 + val->bufferram = 0;
25135 + val->totalhigh = 0;
25136 + val->freehigh = 0;
25140 +void vx_vsi_swapinfo(struct sysinfo *val)
25142 + struct vx_info *vxi = current->vx_info;
25143 + unsigned long totalswap, freeswap;
25146 + v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
25147 + if (v == RLIM_INFINITY) {
25148 + val->freeswap = val->totalswap;
25152 + /* we blindly accept the max */
25153 + w = __rlim_hard(&vxi->limit, RLIMIT_RSS);
25154 + totalswap = (w != RLIM_INFINITY) ? (w - v) : val->totalswap;
25156 + /* currently 'used' swap */
25157 + w = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
25158 + w -= (w > v) ? v : w;
25160 + /* total minus used equals free */
25161 + freeswap = (w < totalswap) ? totalswap - w : 0;
25163 + val->totalswap = totalswap;
25164 + val->freeswap = freeswap;
25169 +unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm)
25171 + struct vx_info *vxi = mm->mm_vx_info;
25172 + unsigned long points;
25178 + v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
25179 + w = __rlim_soft(&vxi->limit, RLIMIT_RSS);
25180 + points = (v > w) ? (v - w) : 0;
25185 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/limit_init.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit_init.h
25186 --- linux-2.6.19.1/kernel/vserver/limit_init.h 1970-01-01 01:00:00 +0100
25187 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit_init.h 2006-11-08 04:57:49 +0100
25191 +static inline void vx_info_init_limit(struct _vx_limit *limit)
25195 + for (lim=0; lim<NUM_LIMITS; lim++) {
25196 + __rlim_soft(limit, lim) = RLIM_INFINITY;
25197 + __rlim_hard(limit, lim) = RLIM_INFINITY;
25198 + __rlim_set(limit, lim, 0);
25199 + atomic_set(&__rlim_lhit(limit, lim), 0);
25200 + __rlim_rmin(limit, lim) = 0;
25201 + __rlim_rmax(limit, lim) = 0;
25205 +static inline void vx_info_exit_limit(struct _vx_limit *limit)
25207 +#ifdef CONFIG_VSERVER_DEBUG
25211 + for (lim=0; lim<NUM_LIMITS; lim++) {
25212 + if ((1 << lim) & VLIM_NOCHECK)
25214 + value = __rlim_get(limit, lim);
25216 + "!!! limit: %p[%s,%d] = %ld on exit.",
25217 + limit, vlimit_name[lim], lim, (long)value);
25222 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/limit_proc.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit_proc.h
25223 --- linux-2.6.19.1/kernel/vserver/limit_proc.h 1970-01-01 01:00:00 +0100
25224 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit_proc.h 2006-11-30 19:31:41 +0100
25226 +#ifndef _VX_LIMIT_PROC_H
25227 +#define _VX_LIMIT_PROC_H
25229 +#include <linux/vserver/limit_int.h>
25231 +static inline void vx_limit_fixup(struct _vx_limit *limit)
25236 + /* complex resources first */
25237 + __vx_cres_array_fixup(limit, VLA_RSS);
25239 + for (res=0; res<NUM_LIMITS; res++) {
25240 + value = __rlim_get(limit, res);
25241 + __vx_cres_fixup(limit, res, value);
25243 + /* not supposed to happen, maybe warn? */
25244 + if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
25245 + __rlim_rmax(limit, res) = __rlim_hard(limit, res);
25250 +#define VX_LIMIT_FMT ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
25251 +#define VX_LIMIT_TOP \
25252 + "Limit\t current\t min/max\t\t soft/hard\t\thits\n"
25254 +#define VX_LIMIT_ARG(r) \
25255 + ,(unsigned long)__rlim_get(limit, r) \
25256 + ,(unsigned long)__rlim_rmin(limit, r) \
25257 + ,(unsigned long)__rlim_rmax(limit, r) \
25258 + ,VX_VLIM(__rlim_soft(limit, r)) \
25259 + ,VX_VLIM(__rlim_hard(limit, r)) \
25260 + ,atomic_read(&__rlim_lhit(limit, r))
25262 +static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
25264 + vx_limit_fixup(limit);
25265 + return sprintf(buffer, VX_LIMIT_TOP
25266 + "PROC" VX_LIMIT_FMT
25267 + "VM" VX_LIMIT_FMT
25268 + "VML" VX_LIMIT_FMT
25269 + "RSS" VX_LIMIT_FMT
25270 + "ANON" VX_LIMIT_FMT
25271 + "RMAP" VX_LIMIT_FMT
25272 + "FILES" VX_LIMIT_FMT
25273 + "OFD" VX_LIMIT_FMT
25274 + "LOCKS" VX_LIMIT_FMT
25275 + "SOCK" VX_LIMIT_FMT
25276 + "MSGQ" VX_LIMIT_FMT
25277 + "SHM" VX_LIMIT_FMT
25278 + "SEMA" VX_LIMIT_FMT
25279 + "SEMS" VX_LIMIT_FMT
25280 + "DENT" VX_LIMIT_FMT
25281 + VX_LIMIT_ARG(RLIMIT_NPROC)
25282 + VX_LIMIT_ARG(RLIMIT_AS)
25283 + VX_LIMIT_ARG(RLIMIT_MEMLOCK)
25284 + VX_LIMIT_ARG(RLIMIT_RSS)
25285 + VX_LIMIT_ARG(VLIMIT_ANON)
25286 + VX_LIMIT_ARG(VLIMIT_MAPPED)
25287 + VX_LIMIT_ARG(RLIMIT_NOFILE)
25288 + VX_LIMIT_ARG(VLIMIT_OPENFD)
25289 + VX_LIMIT_ARG(RLIMIT_LOCKS)
25290 + VX_LIMIT_ARG(VLIMIT_NSOCK)
25291 + VX_LIMIT_ARG(RLIMIT_MSGQUEUE)
25292 + VX_LIMIT_ARG(VLIMIT_SHMEM)
25293 + VX_LIMIT_ARG(VLIMIT_SEMARY)
25294 + VX_LIMIT_ARG(VLIMIT_NSEMS)
25295 + VX_LIMIT_ARG(VLIMIT_DENTRY)
25299 +#endif /* _VX_LIMIT_PROC_H */
25302 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/monitor.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/monitor.c
25303 --- linux-2.6.19.1/kernel/vserver/monitor.c 1970-01-01 01:00:00 +0100
25304 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/monitor.c 2006-11-08 04:57:48 +0100
25307 + * kernel/vserver/monitor.c
25309 + * Virtual Context Scheduler Monitor
25311 + * Copyright (C) 2006 Herbert Pötzl
25313 + * V0.01 basic design
25317 +#include <linux/errno.h>
25318 +#include <linux/module.h>
25319 +#include <linux/types.h>
25320 +#include <linux/ctype.h>
25322 +#include <asm/uaccess.h>
25323 +#include <asm/atomic.h>
25324 +#include <asm/unistd.h>
25326 +#include <linux/vserver/monitor.h>
25327 +#include <linux/vserver/debug_cmd.h>
25330 +#ifdef CONFIG_VSERVER_MONITOR
25331 +#define VXM_SIZE CONFIG_VSERVER_MONITOR_SIZE
25333 +#define VXM_SIZE 64
25336 +struct _vx_monitor {
25337 + unsigned int counter;
25339 + struct _vx_mon_entry entry[VXM_SIZE+1];
25343 +DEFINE_PER_CPU(struct _vx_monitor, vx_monitor_buffer);
25345 +unsigned volatile int vxm_active = 1;
25347 +static atomic_t sequence = ATOMIC_INIT(0);
25352 + * requires disabled preemption */
25354 +struct _vx_mon_entry *vxm_advance(int cpu)
25356 + struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu);
25357 + struct _vx_mon_entry *entry;
25358 + unsigned int index;
25360 + index = vxm_active ? (mon->counter++ % VXM_SIZE) : VXM_SIZE;
25361 + entry = &mon->entry[index];
25363 + entry->ev.seq = atomic_inc_return(&sequence);
25364 + entry->ev.jif = jiffies;
25368 +EXPORT_SYMBOL_GPL(vxm_advance);
25371 +int do_read_monitor(struct __user _vx_mon_entry *data,
25372 + int cpu, uint32_t *index, uint32_t *count)
25374 + int pos, ret = 0;
25375 + struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu);
25376 + int end = mon->counter;
25377 + int start = end - VXM_SIZE + 2;
25378 + int idx = *index;
25380 + /* special case: get current pos */
25386 + /* have we lost some data? */
25390 + for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
25391 + struct _vx_mon_entry *entry =
25392 + &mon->entry[idx % VXM_SIZE];
25394 + /* send entry to userspace */
25395 + ret = copy_to_user (&data[pos], entry, sizeof(*entry));
25399 + /* save new index and count */
25402 + return ret ? ret : (*index < end);
25405 +int vc_read_monitor(uint32_t id, void __user *data)
25407 + struct vcmd_read_monitor_v0 vc_data;
25410 + if (id >= NR_CPUS)
25413 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25416 + ret = do_read_monitor((struct __user _vx_mon_entry *)vc_data.data,
25417 + id, &vc_data.index, &vc_data.count);
25419 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25424 +#ifdef CONFIG_COMPAT
25426 +int vc_read_monitor_x32(uint32_t id, void __user *data)
25428 + struct vcmd_read_monitor_v0_x32 vc_data;
25431 + if (id >= NR_CPUS)
25434 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25437 + ret = do_read_monitor((struct __user _vx_mon_entry *)
25438 + compat_ptr(vc_data.data_ptr),
25439 + id, &vc_data.index, &vc_data.count);
25441 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25446 +#endif /* CONFIG_COMPAT */
25448 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/network.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/network.c
25449 --- linux-2.6.19.1/kernel/vserver/network.c 1970-01-01 01:00:00 +0100
25450 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/network.c 2006-12-17 05:38:36 +0100
25453 + * linux/kernel/vserver/network.c
25455 + * Virtual Server: Network Support
25457 + * Copyright (C) 2003-2006 Herbert Pötzl
25459 + * V0.01 broken out from vcontext V0.05
25460 + * V0.02 cleaned up implementation
25461 + * V0.03 added equiv nx commands
25462 + * V0.04 switch to RCU based hash
25463 + * V0.05 and back to locking again
25464 + * V0.06 changed vcmds to nxi arg
25468 +#include <linux/slab.h>
25469 +#include <linux/rcupdate.h>
25470 +#include <net/tcp.h>
25472 +#include <asm/errno.h>
25473 +#include <linux/vserver/base.h>
25474 +#include <linux/vserver/network_cmd.h>
25477 +atomic_t nx_global_ctotal = ATOMIC_INIT(0);
25478 +atomic_t nx_global_cactive = ATOMIC_INIT(0);
25481 +/* __alloc_nx_info()
25483 + * allocate an initialized nx_info struct
25484 + * doesn't make it visible (hash) */
25486 +static struct nx_info *__alloc_nx_info(nid_t nid)
25488 + struct nx_info *new = NULL;
25490 + vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
25492 + /* would this benefit from a slab cache? */
25493 + new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
25497 + memset (new, 0, sizeof(struct nx_info));
25498 + new->nx_id = nid;
25499 + INIT_HLIST_NODE(&new->nx_hlist);
25500 + atomic_set(&new->nx_usecnt, 0);
25501 + atomic_set(&new->nx_tasks, 0);
25502 + new->nx_state = 0;
25504 + new->nx_flags = NXF_INIT_SET;
25506 + /* rest of init goes here */
25508 + vxdprintk(VXD_CBIT(nid, 0),
25509 + "alloc_nx_info(%d) = %p", nid, new);
25510 + atomic_inc(&nx_global_ctotal);
25514 +/* __dealloc_nx_info()
25516 + * final disposal of nx_info */
25518 +static void __dealloc_nx_info(struct nx_info *nxi)
25520 + vxdprintk(VXD_CBIT(nid, 0),
25521 + "dealloc_nx_info(%p)", nxi);
25523 + nxi->nx_hlist.next = LIST_POISON1;
25526 + BUG_ON(atomic_read(&nxi->nx_usecnt));
25527 + BUG_ON(atomic_read(&nxi->nx_tasks));
25529 + nxi->nx_state |= NXS_RELEASED;
25531 + atomic_dec(&nx_global_ctotal);
25534 +static void __shutdown_nx_info(struct nx_info *nxi)
25536 + nxi->nx_state |= NXS_SHUTDOWN;
25537 + vs_net_change(nxi, VSC_NETDOWN);
25540 +/* exported stuff */
25542 +void free_nx_info(struct nx_info *nxi)
25544 + /* context shutdown is mandatory */
25545 + BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
25547 + /* context must not be hashed */
25548 + BUG_ON(nxi->nx_state & NXS_HASHED);
25550 + BUG_ON(atomic_read(&nxi->nx_usecnt));
25551 + BUG_ON(atomic_read(&nxi->nx_tasks));
25553 + __dealloc_nx_info(nxi);
25557 +void __nx_set_lback(struct nx_info *nxi)
25559 + int nid = nxi->nx_id;
25560 + uint32_t lback = htonl(INADDR_LOOPBACK ^ ((nid & 0xFFFF) << 8));
25562 + nxi->v4_lback = lback;
25566 +/* hash table for nx_info hash */
25568 +#define NX_HASH_SIZE 13
25570 +struct hlist_head nx_info_hash[NX_HASH_SIZE];
25572 +static spinlock_t nx_info_hash_lock = SPIN_LOCK_UNLOCKED;
25575 +static inline unsigned int __hashval(nid_t nid)
25577 + return (nid % NX_HASH_SIZE);
25582 +/* __hash_nx_info()
25584 + * add the nxi to the global hash table
25585 + * requires the hash_lock to be held */
25587 +static inline void __hash_nx_info(struct nx_info *nxi)
25589 + struct hlist_head *head;
25591 + vxd_assert_lock(&nx_info_hash_lock);
25592 + vxdprintk(VXD_CBIT(nid, 4),
25593 + "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
25595 + /* context must not be hashed */
25596 + BUG_ON(nx_info_state(nxi, NXS_HASHED));
25598 + nxi->nx_state |= NXS_HASHED;
25599 + head = &nx_info_hash[__hashval(nxi->nx_id)];
25600 + hlist_add_head(&nxi->nx_hlist, head);
25601 + atomic_inc(&nx_global_cactive);
25604 +/* __unhash_nx_info()
25606 + * remove the nxi from the global hash table
25607 + * requires the hash_lock to be held */
25609 +static inline void __unhash_nx_info(struct nx_info *nxi)
25611 + vxd_assert_lock(&nx_info_hash_lock);
25612 + vxdprintk(VXD_CBIT(nid, 4),
25613 + "__unhash_nx_info: %p[#%d]", nxi, nxi->nx_id);
25615 + /* context must be hashed */
25616 + BUG_ON(!nx_info_state(nxi, NXS_HASHED));
25618 + nxi->nx_state &= ~NXS_HASHED;
25619 + hlist_del(&nxi->nx_hlist);
25620 + atomic_dec(&nx_global_cactive);
25624 +/* __lookup_nx_info()
25626 + * requires the hash_lock to be held
25627 + * doesn't increment the nx_refcnt */
25629 +static inline struct nx_info *__lookup_nx_info(nid_t nid)
25631 + struct hlist_head *head = &nx_info_hash[__hashval(nid)];
25632 + struct hlist_node *pos;
25633 + struct nx_info *nxi;
25635 + vxd_assert_lock(&nx_info_hash_lock);
25636 + hlist_for_each(pos, head) {
25637 + nxi = hlist_entry(pos, struct nx_info, nx_hlist);
25639 + if (nxi->nx_id == nid)
25644 + vxdprintk(VXD_CBIT(nid, 0),
25645 + "__lookup_nx_info(#%u): %p[#%u]",
25646 + nid, nxi, nxi?nxi->nx_id:0);
25651 +/* __create_nx_info()
25653 + * create the requested context
25654 + * get() and hash it */
25656 +static struct nx_info * __create_nx_info(int id)
25658 + struct nx_info *new, *nxi = NULL;
25660 + vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
25662 + if (!(new = __alloc_nx_info(id)))
25663 + return ERR_PTR(-ENOMEM);
25665 + /* required to make dynamic xids unique */
25666 + spin_lock(&nx_info_hash_lock);
25668 + /* static context requested */
25669 + if ((nxi = __lookup_nx_info(id))) {
25670 + vxdprintk(VXD_CBIT(nid, 0),
25671 + "create_nx_info(%d) = %p (already there)", id, nxi);
25672 + if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
25673 + nxi = ERR_PTR(-EBUSY);
25675 + nxi = ERR_PTR(-EEXIST);
25678 + /* new context */
25679 + vxdprintk(VXD_CBIT(nid, 0),
25680 + "create_nx_info(%d) = %p (new)", id, new);
25681 + __hash_nx_info(get_nx_info(new));
25682 + nxi = new, new = NULL;
25685 + spin_unlock(&nx_info_hash_lock);
25687 + __dealloc_nx_info(new);
25693 +/* exported stuff */
25696 +void unhash_nx_info(struct nx_info *nxi)
25698 + __shutdown_nx_info(nxi);
25699 + spin_lock(&nx_info_hash_lock);
25700 + __unhash_nx_info(nxi);
25701 + spin_unlock(&nx_info_hash_lock);
25705 +/* lookup_nx_info()
25707 + * search for a nx_info and get() it
25708 + * negative id means current */
25710 +struct nx_info *lookup_nx_info(int id)
25712 + struct nx_info *nxi = NULL;
25715 + nxi = get_nx_info(current->nx_info);
25716 + } else if (id > 1) {
25717 + spin_lock(&nx_info_hash_lock);
25718 + nxi = get_nx_info(__lookup_nx_info(id));
25719 + spin_unlock(&nx_info_hash_lock);
25724 +/* nid_is_hashed()
25726 + * verify that nid is still hashed */
25728 +int nid_is_hashed(nid_t nid)
25732 + spin_lock(&nx_info_hash_lock);
25733 + hashed = (__lookup_nx_info(nid) != NULL);
25734 + spin_unlock(&nx_info_hash_lock);
25739 +#ifdef CONFIG_PROC_FS
25743 + * get a subset of hashed nids for proc
25744 + * assumes size is at least one */
25746 +int get_nid_list(int index, unsigned int *nids, int size)
25748 + int hindex, nr_nids = 0;
25750 + /* only show current and children */
25751 + if (!nx_check(0, VS_ADMIN|VS_WATCH)) {
25754 + nids[nr_nids] = nx_current_nid();
25758 + for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
25759 + struct hlist_head *head = &nx_info_hash[hindex];
25760 + struct hlist_node *pos;
25762 + spin_lock(&nx_info_hash_lock);
25763 + hlist_for_each(pos, head) {
25764 + struct nx_info *nxi;
25769 + nxi = hlist_entry(pos, struct nx_info, nx_hlist);
25770 + nids[nr_nids] = nxi->nx_id;
25771 + if (++nr_nids >= size) {
25772 + spin_unlock(&nx_info_hash_lock);
25776 + /* keep the lock time short */
25777 + spin_unlock(&nx_info_hash_lock);
25786 + * migrate task to new network
25787 + * gets nxi, puts old_nxi on change
25790 +int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
25792 + struct nx_info *old_nxi;
25798 + vxdprintk(VXD_CBIT(nid, 5),
25799 + "nx_migrate_task(%p,%p[#%d.%d.%d])",
25800 + p, nxi, nxi->nx_id,
25801 + atomic_read(&nxi->nx_usecnt),
25802 + atomic_read(&nxi->nx_tasks));
25804 + if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) &&
25805 + !nx_info_flags(nxi, NXF_STATE_SETUP, 0))
25808 + /* maybe disallow this completely? */
25809 + old_nxi = task_get_nx_info(p);
25810 + if (old_nxi == nxi)
25815 + clr_nx_info(&p->nx_info);
25816 + claim_nx_info(nxi, p);
25817 + set_nx_info(&p->nx_info, nxi);
25818 + p->nid = nxi->nx_id;
25821 + vxdprintk(VXD_CBIT(nid, 5),
25822 + "moved task %p into nxi:%p[#%d]",
25823 + p, nxi, nxi->nx_id);
25826 + release_nx_info(old_nxi, p);
25829 + put_nx_info(old_nxi);
25834 +void nx_set_persistent(struct nx_info *nxi)
25836 + get_nx_info(nxi);
25837 + claim_nx_info(nxi, current);
25840 +void nx_clear_persistent(struct nx_info *nxi)
25842 + vxdprintk(VXD_CBIT(nid, 6),
25843 + "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
25845 + release_nx_info(nxi, current);
25846 + put_nx_info(nxi);
25849 +void nx_update_persistent(struct nx_info *nxi)
25851 + if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
25852 + nx_set_persistent(nxi);
25854 + nx_clear_persistent(nxi);
25857 +/* vserver syscall commands below here */
25859 +/* taks nid and nx_info functions */
25861 +#include <asm/uaccess.h>
25864 +int vc_task_nid(uint32_t id, void __user *data)
25869 + struct task_struct *tsk;
25871 + if (!vx_check(0, VS_ADMIN|VS_WATCH))
25874 + read_lock(&tasklist_lock);
25875 + tsk = find_task_by_real_pid(id);
25876 + nid = (tsk) ? tsk->nid : -ESRCH;
25877 + read_unlock(&tasklist_lock);
25880 + nid = nx_current_nid();
25885 +int vc_nx_info(struct nx_info *nxi, void __user *data)
25887 + struct vcmd_nx_info_v0 vc_data;
25889 + vc_data.nid = nxi->nx_id;
25891 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25897 +/* network functions */
25899 +int vc_net_create(uint32_t nid, void __user *data)
25901 + struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
25902 + struct nx_info *new_nxi;
25905 + if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
25908 + if ((nid > MAX_S_CONTEXT) || (nid < 2))
25911 + new_nxi = __create_nx_info(nid);
25912 + if (IS_ERR(new_nxi))
25913 + return PTR_ERR(new_nxi);
25915 + /* initial flags */
25916 + new_nxi->nx_flags = vc_data.flagword;
25918 + /* get a reference for persistent contexts */
25919 + if ((vc_data.flagword & NXF_PERSISTENT))
25920 + nx_set_persistent(new_nxi);
25923 + if (vs_net_change(new_nxi, VSC_NETUP))
25925 + ret = nx_migrate_task(current, new_nxi);
25927 + /* return context id on success */
25928 + ret = new_nxi->nx_id;
25932 + /* prepare for context disposal */
25933 + new_nxi->nx_state |= NXS_SHUTDOWN;
25934 + if ((vc_data.flagword & NXF_PERSISTENT))
25935 + nx_clear_persistent(new_nxi);
25936 + __unhash_nx_info(new_nxi);
25938 + put_nx_info(new_nxi);
25943 +int vc_net_migrate(struct nx_info *nxi, void __user *data)
25945 + return nx_migrate_task(current, nxi);
25948 +int vc_net_add(struct nx_info *nxi, void __user *data)
25950 + struct vcmd_net_addr_v0 vc_data;
25951 + int index, pos, ret = 0;
25953 + if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
25956 + switch (vc_data.type) {
25957 + case NXA_TYPE_IPV4:
25958 + if ((vc_data.count < 1) || (vc_data.count > 4))
25966 + switch (vc_data.type) {
25967 + case NXA_TYPE_IPV4:
25969 + while ((index < vc_data.count) &&
25970 + ((pos = nxi->nbipv4) < NB_IPV4ROOT)) {
25971 + nxi->ipv4[pos] = vc_data.ip[index].s_addr;
25972 + nxi->mask[pos] = vc_data.mask[index].s_addr;
25979 + case NXA_TYPE_IPV4|NXA_MOD_BCAST:
25980 + nxi->v4_bcast = vc_data.ip[0].s_addr;
25984 + case NXA_TYPE_IPV4|NXA_MOD_LBACK:
25985 + nxi->v4_lback = vc_data.ip[0].s_addr;
25996 +int vc_net_remove(struct nx_info * nxi, void __user *data)
25998 + struct vcmd_net_addr_v0 vc_data;
26000 + if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
26003 + switch (vc_data.type) {
26004 + case NXA_TYPE_ANY:
26014 +int vc_get_nflags(struct nx_info *nxi, void __user *data)
26016 + struct vcmd_net_flags_v0 vc_data;
26018 + vc_data.flagword = nxi->nx_flags;
26020 + /* special STATE flag handling */
26021 + vc_data.mask = vs_mask_flags(~0UL, nxi->nx_flags, NXF_ONE_TIME);
26023 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
26028 +int vc_set_nflags(struct nx_info *nxi, void __user *data)
26030 + struct vcmd_net_flags_v0 vc_data;
26031 + uint64_t mask, trigger;
26033 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
26036 + /* special STATE flag handling */
26037 + mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
26038 + trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
26040 + nxi->nx_flags = vs_mask_flags(nxi->nx_flags,
26041 + vc_data.flagword, mask);
26042 + if (trigger & NXF_PERSISTENT)
26043 + nx_update_persistent(nxi);
26048 +int vc_get_ncaps(struct nx_info *nxi, void __user *data)
26050 + struct vcmd_net_caps_v0 vc_data;
26052 + vc_data.ncaps = nxi->nx_ncaps;
26053 + vc_data.cmask = ~0UL;
26055 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
26060 +int vc_set_ncaps(struct nx_info *nxi, void __user *data)
26062 + struct vcmd_net_caps_v0 vc_data;
26064 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
26067 + nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps,
26068 + vc_data.ncaps, vc_data.cmask);
26073 +#include <linux/module.h>
26075 +EXPORT_SYMBOL_GPL(free_nx_info);
26076 +EXPORT_SYMBOL_GPL(unhash_nx_info);
26078 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/proc.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/proc.c
26079 --- linux-2.6.19.1/kernel/vserver/proc.c 1970-01-01 01:00:00 +0100
26080 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/proc.c 2006-12-17 03:23:33 +0100
26083 + * linux/kernel/vserver/proc.c
26085 + * Virtual Context Support
26087 + * Copyright (C) 2003-2006 Herbert Pötzl
26089 + * V0.01 basic structure
26090 + * V0.02 adaptation vs1.3.0
26091 + * V0.03 proc permissions
26092 + * V0.04 locking/generic
26093 + * V0.05 next generation procfs
26094 + * V0.06 inode validation
26095 + * V0.07 generic rewrite vid
26096 + * V0.08 remove inode type
26100 +#include <linux/errno.h>
26101 +#include <linux/proc_fs.h>
26102 +#include <linux/sched.h>
26103 +#include <linux/vs_context.h>
26104 +#include <linux/vs_network.h>
26105 +#include <linux/vs_cvirt.h>
26107 +#include <linux/vserver/switch.h>
26108 +#include <linux/vserver/global.h>
26110 +#include <asm/uaccess.h>
26111 +#include <asm/unistd.h>
26113 +#include "cvirt_proc.h"
26114 +#include "cacct_proc.h"
26115 +#include "limit_proc.h"
26116 +#include "sched_proc.h"
26117 +#include "vci_config.h"
26119 +static struct proc_dir_entry *proc_virtual;
26121 +static struct proc_dir_entry *proc_virtnet;
26125 +// #define PROC_VID_MASK 0x60
26128 +/* first the actual feeds */
26131 +static int proc_vci(char *buffer)
26133 + return sprintf(buffer,
26134 + "VCIVersion:\t%04x:%04x\n"
26135 + "VCISyscall:\t%d\n"
26136 + "VCIKernel:\t%08x\n"
26137 + ,VCI_VERSION >> 16
26138 + ,VCI_VERSION & 0xFFFF
26140 + ,vci_kernel_config()
26144 +static int proc_virtual_info(char *buffer)
26146 + return proc_vci(buffer);
26149 +static int proc_virtual_status(char *buffer)
26151 + return sprintf(buffer,
26153 + "#CActive:\t%d\n"
26154 + ,atomic_read(&vx_global_ctotal)
26155 + ,atomic_read(&vx_global_cactive)
26160 +int proc_vxi_info (struct vx_info *vxi, char *buffer)
26164 + length = sprintf(buffer,
26175 +int proc_vxi_status (struct vx_info *vxi, char *buffer)
26179 + length = sprintf(buffer,
26182 + "Flags:\t%016llx\n"
26183 + "BCaps:\t%016llx\n"
26184 + "CCaps:\t%016llx\n"
26185 + "Spaces:\t%08lx\n"
26187 + ,atomic_read(&vxi->vx_usecnt)
26188 + ,atomic_read(&vxi->vx_tasks)
26189 + ,(unsigned long long)vxi->vx_flags
26190 + ,(unsigned long long)vxi->vx_bcaps
26191 + ,(unsigned long long)vxi->vx_ccaps
26193 +// ,atomic_read(&vxi->limit.ticks)
26198 +int proc_vxi_limit (struct vx_info *vxi, char *buffer)
26200 + return vx_info_proc_limit(&vxi->limit, buffer);
26203 +int proc_vxi_sched (struct vx_info *vxi, char *buffer)
26207 + length = vx_info_proc_sched(&vxi->sched, buffer);
26208 + for_each_online_cpu(cpu) {
26209 + length += vx_info_proc_sched_pc(
26210 + &vx_per_cpu(vxi, sched_pc, cpu),
26211 + buffer + length, cpu);
26216 +int proc_vxi_nsproxy (struct vx_info *vxi, char *buffer)
26218 + return vx_info_proc_nsproxy(vxi->vx_nsproxy, buffer);
26221 +int proc_vxi_cvirt (struct vx_info *vxi, char *buffer)
26225 + vx_update_load(vxi);
26226 + length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
26227 + for_each_online_cpu(cpu) {
26228 + length += vx_info_proc_cvirt_pc(
26229 + &vx_per_cpu(vxi, cvirt_pc, cpu),
26230 + buffer + length, cpu);
26235 +int proc_vxi_cacct (struct vx_info *vxi, char *buffer)
26237 + return vx_info_proc_cacct(&vxi->cacct, buffer);
26241 +static int proc_virtnet_info(char *buffer)
26243 + return proc_vci(buffer);
26246 +static int proc_virtnet_status(char *buffer)
26248 + return sprintf(buffer,
26250 + "#CActive:\t%d\n"
26251 + ,atomic_read(&nx_global_ctotal)
26252 + ,atomic_read(&nx_global_cactive)
26256 +int proc_nxi_info (struct nx_info *nxi, char *buffer)
26260 + length = sprintf(buffer,
26266 + for (i=0; i<nxi->nbipv4; i++) {
26267 + length += sprintf(buffer + length,
26268 + "%d:\t" NIPQUAD_FMT "/" NIPQUAD_FMT "\n", i,
26269 + NIPQUAD(nxi->ipv4[i]), NIPQUAD(nxi->mask[i]));
26274 +int proc_nxi_status (struct nx_info *nxi, char *buffer)
26278 + length = sprintf(buffer,
26281 + ,atomic_read(&nxi->nx_usecnt)
26282 + ,atomic_read(&nxi->nx_tasks)
26289 +/* here the inode helpers */
26295 + struct inode_operations *iop;
26296 + struct file_operations *fop;
26297 + union proc_op op;
26300 +static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
26302 + struct inode *inode = new_inode(sb);
26307 + inode->i_mode = p->mode;
26309 + inode->i_op = p->iop;
26311 + inode->i_fop = p->fop;
26313 + inode->i_nlink = (p->mode & S_IFDIR) ? 2 : 1;
26314 + inode->i_flags |= S_IMMUTABLE;
26316 + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
26318 + inode->i_uid = 0;
26319 + inode->i_gid = 0;
26320 + inode->i_tag = 0;
26325 +static struct dentry *vs_proc_instantiate(struct inode *dir,
26326 + struct dentry *dentry, int id, void *ptr)
26328 + struct vs_entry *p = ptr;
26329 + struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
26330 + struct dentry *error = ERR_PTR(-EINVAL);
26335 + PROC_I(inode)->op = p->op;
26336 + PROC_I(inode)->fd = id;
26337 + d_add(dentry, inode);
26345 +typedef struct dentry *instantiate_t(struct inode *, struct dentry *, int, void *);
26348 + * Fill a directory entry.
26350 + * If possible create the dcache entry and derive our inode number and
26351 + * file type from dcache entry.
26353 + * Since all of the proc inode numbers are dynamically generated, the inode
26354 + * numbers do not exist until the inode is cache. This means creating the
26355 + * the dcache entry in readdir is necessary to keep the inode numbers
26356 + * reported by readdir in sync with the inode numbers reported
26359 +static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
26360 + char *name, int len, instantiate_t instantiate, int id, void *ptr)
26362 + struct dentry *child, *dir = filp->f_dentry;
26363 + struct inode *inode;
26364 + struct qstr qname;
26366 + unsigned type = DT_UNKNOWN;
26368 + qname.name = name;
26370 + qname.hash = full_name_hash(name, len);
26372 + child = d_lookup(dir, &qname);
26374 + struct dentry *new;
26375 + new = d_alloc(dir, &qname);
26377 + child = instantiate(dir->d_inode, new, id, ptr);
26384 + if (!child || IS_ERR(child) || !child->d_inode)
26385 + goto end_instantiate;
26386 + inode = child->d_inode;
26388 + ino = inode->i_ino;
26389 + type = inode->i_mode >> 12;
26394 + ino = find_inode_number(dir, &qname);
26397 + return filldir(dirent, name, len, filp->f_pos, ino, type);
26402 +/* get and revalidate vx_info/xid */
26405 +struct vx_info *get_proc_vx_info(struct inode *inode)
26407 + return lookup_vx_info(PROC_I(inode)->fd);
26410 +static int proc_xid_revalidate(struct dentry * dentry, struct nameidata *nd)
26412 + struct inode *inode = dentry->d_inode;
26413 + xid_t xid = PROC_I(inode)->fd;
26415 + if (!xid || xid_is_hashed(xid))
26422 +/* get and revalidate nx_info/nid */
26424 +static int proc_nid_revalidate(struct dentry * dentry, struct nameidata *nd)
26426 + struct inode *inode = dentry->d_inode;
26427 + nid_t nid = PROC_I(inode)->fd;
26429 + if (!nid || nid_is_hashed(nid))
26437 +#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
26439 +static ssize_t proc_vs_info_read(struct file * file, char __user * buf,
26440 + size_t count, loff_t *ppos)
26442 + struct inode *inode = file->f_dentry->d_inode;
26443 + unsigned long page;
26444 + ssize_t length = 0;
26446 + if (count > PROC_BLOCK_SIZE)
26447 + count = PROC_BLOCK_SIZE;
26449 + /* fade that out as soon as stable */
26450 + WARN_ON(PROC_I(inode)->fd);
26452 + if (!(page = __get_free_page(GFP_KERNEL)))
26455 + BUG_ON(!PROC_I(inode)->op.proc_vs_read);
26456 + length = PROC_I(inode)->op.proc_vs_read((char*)page);
26459 + length = simple_read_from_buffer(buf, count, ppos,
26460 + (char *)page, length);
26466 +static ssize_t proc_vx_info_read(struct file * file, char __user * buf,
26467 + size_t count, loff_t *ppos)
26469 + struct inode *inode = file->f_dentry->d_inode;
26470 + struct vx_info *vxi = NULL;
26471 + xid_t xid = PROC_I(inode)->fd;
26472 + unsigned long page;
26473 + ssize_t length = 0;
26475 + if (count > PROC_BLOCK_SIZE)
26476 + count = PROC_BLOCK_SIZE;
26478 + /* fade that out as soon as stable */
26480 + vxi = lookup_vx_info(xid);
26484 + length = -ENOMEM;
26485 + if (!(page = __get_free_page(GFP_KERNEL)))
26488 + BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
26489 + length = PROC_I(inode)->op.proc_vxi_read(vxi, (char*)page);
26492 + length = simple_read_from_buffer(buf, count, ppos,
26493 + (char *)page, length);
26497 + put_vx_info(vxi);
26502 +static ssize_t proc_nx_info_read(struct file * file, char __user * buf,
26503 + size_t count, loff_t *ppos)
26505 + struct inode *inode = file->f_dentry->d_inode;
26506 + struct nx_info *nxi = NULL;
26507 + nid_t nid = PROC_I(inode)->fd;
26508 + unsigned long page;
26509 + ssize_t length = 0;
26511 + if (count > PROC_BLOCK_SIZE)
26512 + count = PROC_BLOCK_SIZE;
26514 + /* fade that out as soon as stable */
26516 + nxi = lookup_nx_info(nid);
26520 + length = -ENOMEM;
26521 + if (!(page = __get_free_page(GFP_KERNEL)))
26524 + BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
26525 + length = PROC_I(inode)->op.proc_nxi_read(nxi, (char*)page);
26528 + length = simple_read_from_buffer(buf, count, ppos,
26529 + (char *)page, length);
26533 + put_nx_info(nxi);
26540 +/* here comes the lower level */
26543 +#define NOD(NAME, MODE, IOP, FOP, OP) { \
26544 + .len = sizeof(NAME) - 1, \
26545 + .name = (NAME), \
26553 +#define DIR(NAME, MODE, OTYPE) \
26554 + NOD(NAME, (S_IFDIR|(MODE)), \
26555 + &proc_##OTYPE##_inode_operations, \
26556 + &proc_##OTYPE##_file_operations, { } )
26558 +#define INF(NAME, MODE, OTYPE) \
26559 + NOD(NAME, (S_IFREG|(MODE)), NULL, \
26560 + &proc_vs_info_file_operations, \
26561 + { .proc_vs_read = &proc_##OTYPE } )
26563 +#define VINF(NAME, MODE, OTYPE) \
26564 + NOD(NAME, (S_IFREG|(MODE)), NULL, \
26565 + &proc_vx_info_file_operations, \
26566 + { .proc_vxi_read = &proc_##OTYPE } )
26568 +#define NINF(NAME, MODE, OTYPE) \
26569 + NOD(NAME, (S_IFREG|(MODE)), NULL, \
26570 + &proc_nx_info_file_operations, \
26571 + { .proc_nxi_read = &proc_##OTYPE } )
26574 +static struct file_operations proc_vs_info_file_operations = {
26575 + .read = proc_vs_info_read,
26578 +static struct file_operations proc_vx_info_file_operations = {
26579 + .read = proc_vx_info_read,
26582 +static struct dentry_operations proc_xid_dentry_operations = {
26583 + .d_revalidate = proc_xid_revalidate,
26586 +static struct vs_entry vx_base_stuff[] = {
26587 + VINF("info", S_IRUGO, vxi_info),
26588 + VINF("status", S_IRUGO, vxi_status),
26589 + VINF("limit", S_IRUGO, vxi_limit),
26590 + VINF("sched", S_IRUGO, vxi_sched),
26591 + VINF("nsproxy", S_IRUGO, vxi_nsproxy),
26592 + VINF("cvirt", S_IRUGO, vxi_cvirt),
26593 + VINF("cacct", S_IRUGO, vxi_cacct),
26600 +static struct dentry *proc_xid_instantiate(struct inode *dir,
26601 + struct dentry *dentry, int id, void *ptr)
26603 + dentry->d_op = &proc_xid_dentry_operations;
26604 + return vs_proc_instantiate(dir, dentry, id, ptr);
26607 +static struct dentry *proc_xid_lookup(struct inode *dir,
26608 + struct dentry *dentry, struct nameidata *nd)
26610 + struct vs_entry *p = vx_base_stuff;
26611 + struct dentry *error = ERR_PTR(-ENOENT);
26613 + for (; p->name; p++) {
26614 + if (p->len != dentry->d_name.len)
26616 + if (!memcmp(dentry->d_name.name, p->name, p->len))
26622 + error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
26627 +static int proc_xid_readdir(struct file * filp,
26628 + void * dirent, filldir_t filldir)
26630 + struct dentry *dentry = filp->f_dentry;
26631 + struct inode *inode = dentry->d_inode;
26632 + struct vs_entry *p = vx_base_stuff;
26633 + int size = sizeof(vx_base_stuff)/sizeof(struct vs_entry);
26637 + pos = filp->f_pos;
26640 + ino = inode->i_ino;
26641 + if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
26644 + /* fall through */
26646 + ino = parent_ino(dentry);
26647 + if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
26650 + /* fall through */
26653 + if (index >= size)
26655 + for (p += index; p->name; p++) {
26656 + if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
26657 + vs_proc_instantiate, PROC_I(inode)->fd, p))
26663 + filp->f_pos = pos;
26669 +static struct file_operations proc_nx_info_file_operations = {
26670 + .read = proc_nx_info_read,
26673 +static struct dentry_operations proc_nid_dentry_operations = {
26674 + .d_revalidate = proc_nid_revalidate,
26677 +static struct vs_entry nx_base_stuff[] = {
26678 + NINF("info", S_IRUGO, nxi_info),
26679 + NINF("status", S_IRUGO, nxi_status),
26684 +static struct dentry *proc_nid_instantiate(struct inode *dir,
26685 + struct dentry *dentry, int id, void *ptr)
26687 + dentry->d_op = &proc_nid_dentry_operations;
26688 + return vs_proc_instantiate(dir, dentry, id, ptr);
26691 +static struct dentry *proc_nid_lookup(struct inode *dir,
26692 + struct dentry *dentry, struct nameidata *nd)
26694 + struct vs_entry *p = nx_base_stuff;
26695 + struct dentry *error = ERR_PTR(-ENOENT);
26697 + for (; p->name; p++) {
26698 + if (p->len != dentry->d_name.len)
26700 + if (!memcmp(dentry->d_name.name, p->name, p->len))
26706 + error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
26711 +static int proc_nid_readdir(struct file * filp,
26712 + void * dirent, filldir_t filldir)
26714 + struct dentry *dentry = filp->f_dentry;
26715 + struct inode *inode = dentry->d_inode;
26716 + struct vs_entry *p = nx_base_stuff;
26717 + int size = sizeof(nx_base_stuff)/sizeof(struct vs_entry);
26721 + pos = filp->f_pos;
26724 + ino = inode->i_ino;
26725 + if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
26728 + /* fall through */
26730 + ino = parent_ino(dentry);
26731 + if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
26734 + /* fall through */
26737 + if (index >= size)
26739 + for (p += index; p->name; p++) {
26740 + if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
26741 + vs_proc_instantiate, PROC_I(inode)->fd, p))
26747 + filp->f_pos = pos;
26752 +#define MAX_MULBY10 ((~0U-9)/10)
26754 +static inline int atovid(const char *str, int len)
26759 + while (len-- > 0) {
26764 + if (vid >= MAX_MULBY10)
26774 +/* now the upper level (virtual) */
26777 +static struct file_operations proc_xid_file_operations = {
26778 + .read = generic_read_dir,
26779 + .readdir = proc_xid_readdir,
26782 +static struct inode_operations proc_xid_inode_operations = {
26783 + .lookup = proc_xid_lookup,
26786 +static struct vs_entry vx_virtual_stuff[] = {
26787 + INF("info", S_IRUGO, virtual_info),
26788 + INF("status", S_IRUGO, virtual_status),
26789 + DIR(NULL, S_IRUGO|S_IXUGO, xid),
26793 +static struct dentry *proc_virtual_lookup(struct inode *dir,
26794 + struct dentry *dentry, struct nameidata *nd)
26796 + struct vs_entry *p = vx_virtual_stuff;
26797 + struct dentry *error = ERR_PTR(-ENOENT);
26800 + for (; p->name; p++) {
26801 + if (p->len != dentry->d_name.len)
26803 + if (!memcmp(dentry->d_name.name, p->name, p->len))
26807 + goto instantiate;
26809 + id = atovid(dentry->d_name.name, dentry->d_name.len);
26810 + if ((id < 0) || !xid_is_hashed(id))
26814 + error = proc_xid_instantiate(dir, dentry, id, p);
26819 +static struct file_operations proc_nid_file_operations = {
26820 + .read = generic_read_dir,
26821 + .readdir = proc_nid_readdir,
26824 +static struct inode_operations proc_nid_inode_operations = {
26825 + .lookup = proc_nid_lookup,
26828 +static struct vs_entry nx_virtnet_stuff[] = {
26829 + INF("info", S_IRUGO, virtnet_info),
26830 + INF("status", S_IRUGO, virtnet_status),
26831 + DIR(NULL, S_IRUGO|S_IXUGO, nid),
26835 +static struct dentry *proc_virtnet_lookup(struct inode *dir,
26836 + struct dentry *dentry, struct nameidata *nd)
26838 + struct vs_entry *p = nx_virtnet_stuff;
26839 + struct dentry *error = ERR_PTR(-ENOENT);
26842 + for (; p->name; p++) {
26843 + if (p->len != dentry->d_name.len)
26845 + if (!memcmp(dentry->d_name.name, p->name, p->len))
26849 + goto instantiate;
26851 + id = atovid(dentry->d_name.name, dentry->d_name.len);
26852 + if ((id < 0) || !nid_is_hashed(id))
26856 + error = proc_nid_instantiate(dir, dentry, id, p);
26863 +#define PROC_NUMBUF 10
26864 +#define PROC_MAXVIDS 32
26866 +int proc_virtual_readdir(struct file * filp,
26867 + void * dirent, filldir_t filldir)
26869 + struct dentry *dentry = filp->f_dentry;
26870 + struct inode *inode = dentry->d_inode;
26871 + struct vs_entry *p = vx_virtual_stuff;
26872 + int size = sizeof(vx_virtual_stuff)/sizeof(struct vs_entry);
26874 + unsigned int xid_array[PROC_MAXVIDS];
26875 + char buf[PROC_NUMBUF];
26876 + unsigned int nr_xids, i;
26879 + pos = filp->f_pos;
26882 + ino = inode->i_ino;
26883 + if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
26886 + /* fall through */
26888 + ino = parent_ino(dentry);
26889 + if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
26892 + /* fall through */
26895 + if (index >= size)
26897 + for (p += index; p->name; p++) {
26898 + if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
26899 + vs_proc_instantiate, 0, p))
26904 + index = pos - size;
26905 + p = &vx_virtual_stuff[size-1];
26906 + nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
26907 + for (i = 0; i < nr_xids; i++) {
26908 + int n, xid = xid_array[i];
26909 + unsigned int j = PROC_NUMBUF;
26912 + do buf[--j] = '0' + (n % 10); while (n /= 10);
26914 + if (proc_fill_cache(filp, dirent, filldir, buf+j, PROC_NUMBUF-j,
26915 + vs_proc_instantiate, xid, p))
26921 + filp->f_pos = pos;
26926 +static struct file_operations proc_virtual_dir_operations = {
26927 + .read = generic_read_dir,
26928 + .readdir = proc_virtual_readdir,
26931 +static struct inode_operations proc_virtual_dir_inode_operations = {
26932 + .lookup = proc_virtual_lookup,
26939 +int proc_virtnet_readdir(struct file * filp,
26940 + void * dirent, filldir_t filldir)
26942 + struct dentry *dentry = filp->f_dentry;
26943 + struct inode *inode = dentry->d_inode;
26944 + struct vs_entry *p = nx_virtnet_stuff;
26945 + int size = sizeof(nx_virtnet_stuff)/sizeof(struct vs_entry);
26947 + unsigned int nid_array[PROC_MAXVIDS];
26948 + char buf[PROC_NUMBUF];
26949 + unsigned int nr_nids, i;
26952 + pos = filp->f_pos;
26955 + ino = inode->i_ino;
26956 + if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
26959 + /* fall through */
26961 + ino = parent_ino(dentry);
26962 + if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
26965 + /* fall through */
26968 + if (index >= size)
26970 + for (p += index; p->name; p++) {
26971 + if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
26972 + vs_proc_instantiate, 0, p))
26977 + index = pos - size;
26978 + p = &nx_virtnet_stuff[size-1];
26979 + nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
26980 + for (i = 0; i < nr_nids; i++) {
26981 + int n, nid = nid_array[i];
26982 + unsigned int j = PROC_NUMBUF;
26985 + do buf[--j] = '0' + (n % 10); while (n /= 10);
26987 + if (proc_fill_cache(filp, dirent, filldir, buf+j, PROC_NUMBUF-j,
26988 + vs_proc_instantiate, nid, p))
26994 + filp->f_pos = pos;
26999 +static struct file_operations proc_virtnet_dir_operations = {
27000 + .read = generic_read_dir,
27001 + .readdir = proc_virtnet_readdir,
27004 +static struct inode_operations proc_virtnet_dir_inode_operations = {
27005 + .lookup = proc_virtnet_lookup,
27010 +void proc_vx_init(void)
27012 + struct proc_dir_entry *ent;
27014 + ent = proc_mkdir("virtual", 0);
27016 + ent->proc_fops = &proc_virtual_dir_operations;
27017 + ent->proc_iops = &proc_virtual_dir_inode_operations;
27019 + proc_virtual = ent;
27021 + ent = proc_mkdir("virtnet", 0);
27023 + ent->proc_fops = &proc_virtnet_dir_operations;
27024 + ent->proc_iops = &proc_virtnet_dir_inode_operations;
27026 + proc_virtnet = ent;
27032 +/* per pid info */
27035 +int proc_pid_vx_info(struct task_struct *p, char *buffer)
27037 + struct vx_info *vxi;
27038 + char * orig = buffer;
27040 + buffer += sprintf (buffer,"XID:\t%d\n", vx_task_xid(p));
27042 + vxi = task_get_vx_info(p);
27046 + buffer += sprintf (buffer,"BCaps:\t%016llx\n"
27047 + ,(unsigned long long)vxi->vx_bcaps);
27048 + buffer += sprintf (buffer,"CCaps:\t%016llx\n"
27049 + ,(unsigned long long)vxi->vx_ccaps);
27050 + buffer += sprintf (buffer,"CFlags:\t%016llx\n"
27051 + ,(unsigned long long)vxi->vx_flags);
27052 + buffer += sprintf (buffer,"CIPid:\t%d\n"
27053 + ,vxi->vx_initpid);
27055 + put_vx_info(vxi);
27057 + return buffer - orig;
27061 +int proc_pid_nx_info(struct task_struct *p, char *buffer)
27063 + struct nx_info *nxi;
27064 + char * orig = buffer;
27067 + buffer += sprintf (buffer,"NID:\t%d\n", nx_task_nid(p));
27069 + nxi = task_get_nx_info(p);
27073 + for (i=0; i<nxi->nbipv4; i++){
27074 + buffer += sprintf (buffer,
27075 + "V4Root[%d]:\t%d.%d.%d.%d/%d.%d.%d.%d\n", i
27076 + ,NIPQUAD(nxi->ipv4[i])
27077 + ,NIPQUAD(nxi->mask[i]));
27079 + buffer += sprintf (buffer,
27080 + "V4Root[bcast]:\t%d.%d.%d.%d\n"
27081 + ,NIPQUAD(nxi->v4_bcast));
27082 + buffer += sprintf (buffer,
27083 + "V4Root[lback]:\t%d.%d.%d.%d\n"
27084 + ,NIPQUAD(nxi->v4_lback));
27086 + put_nx_info(nxi);
27088 + return buffer - orig;
27091 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/sched.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched.c
27092 --- linux-2.6.19.1/kernel/vserver/sched.c 1970-01-01 01:00:00 +0100
27093 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched.c 2006-12-17 04:30:06 +0100
27096 + * linux/kernel/vserver/sched.c
27098 + * Virtual Server: Scheduler Support
27100 + * Copyright (C) 2004-2006 Herbert Pötzl
27102 + * V0.01 adapted Sam Vilains version to 2.6.3
27103 + * V0.02 removed legacy interface
27104 + * V0.03 changed vcmds to vxi arg
27108 +#include <linux/sched.h>
27109 +#include <linux/vs_context.h>
27110 +#include <linux/vs_sched.h>
27111 +#include <linux/vserver/sched_cmd.h>
27113 +#include <asm/errno.h>
27114 +#include <asm/uaccess.h>
27116 +#define vxd_check_range(val, min, max) do { \
27117 + vxlprintk((val<min) || (val>max), \
27118 + "check_range(%ld,%ld,%ld)", \
27119 + (long)val, (long)min, (long)max, \
27120 + __FILE__, __LINE__); \
27124 +void vx_update_sched_param(struct _vx_sched *sched,
27125 + struct _vx_sched_pc *sched_pc)
27127 + unsigned int set_mask = sched->update_mask;
27129 + if (set_mask & VXSM_FILL_RATE)
27130 + sched_pc->fill_rate[0] = sched->fill_rate[0];
27131 + if (set_mask & VXSM_INTERVAL)
27132 + sched_pc->interval[0] = sched->interval[0];
27133 + if (set_mask & VXSM_FILL_RATE2)
27134 + sched_pc->fill_rate[1] = sched->fill_rate[1];
27135 + if (set_mask & VXSM_INTERVAL2)
27136 + sched_pc->interval[1] = sched->interval[1];
27137 + if (set_mask & VXSM_TOKENS)
27138 + sched_pc->tokens = sched->tokens;
27139 + if (set_mask & VXSM_TOKENS_MIN)
27140 + sched_pc->tokens_min = sched->tokens_min;
27141 + if (set_mask & VXSM_TOKENS_MAX)
27142 + sched_pc->tokens_max = sched->tokens_max;
27144 + if (set_mask & VXSM_IDLE_TIME)
27145 + sched_pc->flags |= VXSF_IDLE_TIME;
27147 + sched_pc->flags &= ~VXSF_IDLE_TIME;
27150 + sched_pc->norm_time = jiffies;
27155 + * recalculate the context's scheduling tokens
27157 + * ret > 0 : number of tokens available
27158 + * ret < 0 : on hold, check delta_min[]
27159 + * -1 only jiffies
27160 + * -2 also idle time
27163 +int vx_tokens_recalc(struct _vx_sched_pc *sched_pc,
27164 + unsigned long *norm_time, unsigned long *idle_time, int delta_min[2])
27168 + int flags = sched_pc->flags;
27170 + /* how much time did pass? */
27171 + delta = *norm_time - sched_pc->norm_time;
27172 + vxd_check_range(delta, 0, INT_MAX);
27174 + if (delta >= sched_pc->interval[0]) {
27175 + long tokens, integral;
27177 + /* calc integral token part */
27178 + tokens = delta / sched_pc->interval[0];
27179 + integral = tokens * sched_pc->interval[0];
27180 + tokens *= sched_pc->fill_rate[0];
27181 +#ifdef CONFIG_VSERVER_HARDCPU
27182 + delta_min[0] = delta - integral;
27183 + vxd_check_range(delta_min[0], 0, sched_pc->interval[0]);
27185 + /* advance time */
27186 + sched_pc->norm_time += delta;
27189 + sched_pc->tokens += tokens;
27190 + sched_pc->token_time += tokens;
27193 + delta_min[0] = delta;
27195 +#ifdef CONFIG_VSERVER_IDLETIME
27196 + if (!(flags & VXSF_IDLE_TIME))
27199 + /* how much was the idle skip? */
27200 + delta = *idle_time - sched_pc->idle_time;
27201 + vxd_check_range(delta, 0, INT_MAX);
27203 + if (delta >= sched_pc->interval[1]) {
27204 + long tokens, integral;
27206 + /* calc fair share token part */
27207 + tokens = delta / sched_pc->interval[1];
27208 + integral = tokens * sched_pc->interval[1];
27209 + tokens *= sched_pc->fill_rate[1];
27210 + delta_min[1] = delta - integral;
27211 + vxd_check_range(delta_min[1], 0, sched_pc->interval[1]);
27213 + /* advance idle time */
27214 + sched_pc->idle_time += integral;
27217 + sched_pc->tokens += tokens;
27218 + sched_pc->token_time += tokens;
27221 + delta_min[1] = delta;
27225 + /* clip at maximum */
27226 + if (sched_pc->tokens > sched_pc->tokens_max)
27227 + sched_pc->tokens = sched_pc->tokens_max;
27228 + tokens = sched_pc->tokens;
27230 + if ((flags & VXSF_ONHOLD)) {
27231 + /* can we unhold? */
27232 + if (tokens >= sched_pc->tokens_min) {
27233 + flags &= ~VXSF_ONHOLD;
27234 + sched_pc->hold_ticks +=
27235 + *norm_time - sched_pc->onhold;
27240 + /* put on hold? */
27241 + if (tokens <= 0) {
27242 + flags |= VXSF_ONHOLD;
27243 + sched_pc->onhold = *norm_time;
27247 + sched_pc->flags = flags;
27251 + tokens = sched_pc->tokens_min - tokens;
27252 + sched_pc->flags = flags;
27253 + BUG_ON(tokens < 0);
27255 +#ifdef CONFIG_VSERVER_HARDCPU
27256 + /* next interval? */
27257 + if (!sched_pc->fill_rate[0])
27258 + delta_min[0] = HZ;
27259 + else if (tokens > sched_pc->fill_rate[0])
27260 + delta_min[0] += sched_pc->interval[0] *
27261 + tokens / sched_pc->fill_rate[0];
27263 + delta_min[0] = sched_pc->interval[0] - delta_min[0];
27264 + vxd_check_range(delta_min[0], 0, INT_MAX);
27266 +#ifdef CONFIG_VSERVER_IDLETIME
27267 + if (!(flags & VXSF_IDLE_TIME))
27270 + /* next interval? */
27271 + if (!sched_pc->fill_rate[1])
27272 + delta_min[1] = HZ;
27273 + else if (tokens > sched_pc->fill_rate[1])
27274 + delta_min[1] += sched_pc->interval[1] *
27275 + tokens / sched_pc->fill_rate[1];
27277 + delta_min[1] = sched_pc->interval[1] - delta_min[1];
27278 + vxd_check_range(delta_min[1], 0, INT_MAX);
27283 +#endif /* CONFIG_VSERVER_IDLETIME */
27286 +#endif /* CONFIG_VSERVER_HARDCPU */
27290 +static int do_set_sched(struct vx_info *vxi, struct vcmd_set_sched_v4 *data)
27292 + unsigned int set_mask = data->set_mask;
27293 + unsigned int update_mask;
27295 + /* Sanity check data values */
27296 + if (data->fill_rate < 0)
27297 + data->fill_rate = 1;
27298 + if (data->interval <= 0)
27299 + data->interval = HZ;
27300 + if (data->tokens_max <= 0)
27301 + data->tokens_max = HZ;
27302 + if (data->tokens_min < 0)
27303 + data->tokens_min = data->fill_rate*3;
27304 + if (data->tokens_min >= data->tokens_max)
27305 + data->tokens_min = data->tokens_max;
27307 + if (data->prio_bias > MAX_PRIO_BIAS)
27308 + data->prio_bias = MAX_PRIO_BIAS;
27309 + if (data->prio_bias < MIN_PRIO_BIAS)
27310 + data->prio_bias = MIN_PRIO_BIAS;
27312 + spin_lock(&vxi->sched.tokens_lock);
27314 + if (set_mask & VXSM_FILL_RATE)
27315 + vxi->sched.fill_rate[0] = data->fill_rate;
27316 + if (set_mask & VXSM_INTERVAL)
27317 + vxi->sched.interval[0] = data->interval;
27318 + if (set_mask & VXSM_FILL_RATE2)
27319 + vxi->sched.fill_rate[1] = data->fill_rate;
27320 + if (set_mask & VXSM_INTERVAL2)
27321 + vxi->sched.interval[1] = data->interval;
27322 + if (set_mask & VXSM_TOKENS)
27323 + vxi->sched.tokens = data->tokens;
27324 + if (set_mask & VXSM_TOKENS_MIN)
27325 + vxi->sched.tokens_min = data->tokens_min;
27326 + if (set_mask & VXSM_TOKENS_MAX)
27327 + vxi->sched.tokens_max = data->tokens_max;
27328 + if (set_mask & VXSM_PRIO_BIAS)
27329 + vxi->sched.prio_bias = data->prio_bias;
27331 + update_mask = vxi->sched.update_mask & VXSM_SET_MASK;
27332 + update_mask |= (set_mask & (VXSM_SET_MASK|VXSM_IDLE_TIME));
27333 + vxi->sched.update_mask = update_mask;
27336 + if (set_mask & VXSM_CPU_ID)
27337 + vxi->sched.update = cpumask_of_cpu(data->cpu_id);
27339 + vxi->sched.update = CPU_MASK_ALL;
27340 + /* forced reload? */
27341 + if (set_mask & VXSM_FORCE) {
27344 + for_each_possible_cpu(cpu)
27345 + vx_update_sched_param(&vxi->sched,
27346 + &vx_per_cpu(vxi, sched_pc, cpu));
27349 + /* on UP we update immediately */
27350 + vx_update_sched_param(&vxi->sched,
27351 + &vx_per_cpu(vxi, sched_pc, 0));
27354 + spin_unlock(&vxi->sched.tokens_lock);
27358 +int vc_set_sched_v3(struct vx_info *vxi, void __user *data)
27360 + struct vcmd_set_sched_v3 vc_data;
27361 + struct vcmd_set_sched_v4 vc_data_v4;
27363 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
27366 + /* structures are binary compatible */
27367 + memcpy(&vc_data_v4, &vc_data, sizeof(vc_data));
27368 + vc_data_v4.set_mask &= VXSM_V3_MASK;
27369 + vc_data_v4.bucket_id = 0;
27371 + return do_set_sched(vxi, &vc_data_v4);
27374 +int vc_set_sched(struct vx_info *vxi, void __user *data)
27376 + struct vcmd_set_sched_v4 vc_data;
27378 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
27381 + return do_set_sched(vxi, &vc_data);
27384 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/sched_init.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched_init.h
27385 --- linux-2.6.19.1/kernel/vserver/sched_init.h 1970-01-01 01:00:00 +0100
27386 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched_init.h 2006-11-08 04:57:49 +0100
27389 +static inline void vx_info_init_sched(struct _vx_sched *sched)
27391 + static struct lock_class_key tokens_lock_key;
27393 + /* scheduling; hard code starting values as constants */
27394 + sched->fill_rate[0] = 1;
27395 + sched->interval[0] = 4;
27396 + sched->fill_rate[1] = 1;
27397 + sched->interval[1] = 8;
27398 + sched->tokens = HZ >> 2;
27399 + sched->tokens_min = HZ >> 4;
27400 + sched->tokens_max = HZ >> 1;
27401 + sched->tokens_lock = SPIN_LOCK_UNLOCKED;
27402 + sched->prio_bias = 0;
27403 + sched->vavavoom = 0;
27405 + lockdep_set_class(&sched->tokens_lock, &tokens_lock_key);
27409 +void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
27411 + sched_pc->fill_rate[0] = 1;
27412 + sched_pc->interval[0] = 4;
27413 + sched_pc->fill_rate[1] = 1;
27414 + sched_pc->interval[1] = 8;
27415 + sched_pc->tokens = HZ >> 2;
27416 + sched_pc->tokens_min = HZ >> 4;
27417 + sched_pc->tokens_max = HZ >> 1;
27418 + sched_pc->token_time = 0;
27419 + sched_pc->idle_time = 0;
27420 + sched_pc->norm_time = jiffies;
27422 + sched_pc->user_ticks = 0;
27423 + sched_pc->sys_ticks = 0;
27424 + sched_pc->hold_ticks = 0;
27427 +static inline void vx_info_exit_sched(struct _vx_sched *sched)
27433 +void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
27437 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/sched_proc.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched_proc.h
27438 --- linux-2.6.19.1/kernel/vserver/sched_proc.h 1970-01-01 01:00:00 +0100
27439 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched_proc.h 2006-11-08 04:57:49 +0100
27441 +#ifndef _VX_SCHED_PROC_H
27442 +#define _VX_SCHED_PROC_H
27446 +int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
27450 + length += sprintf(buffer,
27451 + "FillRate:\t%8d,%d\n"
27452 + "Interval:\t%8d,%d\n"
27453 + "TokensMin:\t%8d\n"
27454 + "TokensMax:\t%8d\n"
27455 + "PrioBias:\t%8d\n"
27456 + "VaVaVoom:\t%8d\n"
27457 + ,sched->fill_rate[0]
27458 + ,sched->fill_rate[1]
27459 + ,sched->interval[0]
27460 + ,sched->interval[1]
27461 + ,sched->tokens_min
27462 + ,sched->tokens_max
27463 + ,sched->prio_bias
27470 +int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
27471 + char *buffer, int cpu)
27475 + length += sprintf(buffer + length,
27476 + "cpu %d: %lld %lld %lld %ld %ld"
27478 + ,(unsigned long long)sched_pc->user_ticks
27479 + ,(unsigned long long)sched_pc->sys_ticks
27480 + ,(unsigned long long)sched_pc->hold_ticks
27481 + ,sched_pc->token_time
27482 + ,sched_pc->idle_time
27484 + length += sprintf(buffer + length,
27485 + " %c%c %d %d %d %d/%d %d/%d\n"
27486 + ,(sched_pc->flags & VXSF_ONHOLD) ? 'H' : 'R'
27487 + ,(sched_pc->flags & VXSF_IDLE_TIME) ? 'I' : '-'
27488 + ,sched_pc->tokens
27489 + ,sched_pc->tokens_min
27490 + ,sched_pc->tokens_max
27491 + ,sched_pc->fill_rate[0]
27492 + ,sched_pc->interval[0]
27493 + ,sched_pc->fill_rate[1]
27494 + ,sched_pc->interval[1]
27499 +#endif /* _VX_SCHED_PROC_H */
27500 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/signal.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/signal.c
27501 --- linux-2.6.19.1/kernel/vserver/signal.c 1970-01-01 01:00:00 +0100
27502 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/signal.c 2006-11-08 04:57:45 +0100
27505 + * linux/kernel/vserver/signal.c
27507 + * Virtual Server: Signal Support
27509 + * Copyright (C) 2003-2006 Herbert Pötzl
27511 + * V0.01 broken out from vcontext V0.05
27512 + * V0.02 changed vcmds to vxi arg
27516 +#include <linux/sched.h>
27518 +#include <asm/errno.h>
27519 +#include <asm/uaccess.h>
27521 +#include <linux/vs_context.h>
27522 +#include <linux/vserver/signal_cmd.h>
27525 +int vx_info_kill(struct vx_info *vxi, int pid, int sig)
27527 + int retval, count=0;
27528 + struct task_struct *p;
27529 + unsigned long priv = 0;
27532 + vxdprintk(VXD_CBIT(misc, 4),
27533 + "vx_info_kill(%p[#%d],%d,%d)*",
27534 + vxi, vxi->vx_id, pid, sig);
27535 + read_lock(&tasklist_lock);
27540 + for_each_process(p) {
27543 + if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
27544 + (pid && vxi->vx_initpid == p->pid))
27547 + err = group_send_sig_info(sig, (void*)priv, p);
27549 + if (err != -EPERM)
27555 + if (vxi->vx_initpid) {
27556 + pid = vxi->vx_initpid;
27557 + /* for now, only SIGINT to private init ... */
27558 + if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
27559 + /* ... as long as there are tasks left */
27560 + (atomic_read(&vxi->vx_tasks) > 1))
27564 + /* fallthrough */
27566 + p = find_task_by_real_pid(pid);
27568 + if (vx_task_xid(p) == vxi->vx_id)
27569 + retval = group_send_sig_info(sig,
27574 + read_unlock(&tasklist_lock);
27575 + vxdprintk(VXD_CBIT(misc, 4),
27576 + "vx_info_kill(%p[#%d],%d,%d) = %d",
27577 + vxi, vxi->vx_id, pid, sig, retval);
27581 +int vc_ctx_kill(struct vx_info *vxi, void __user *data)
27583 + struct vcmd_ctx_kill_v0 vc_data;
27585 + if (copy_from_user (&vc_data, data, sizeof(vc_data)))
27588 + /* special check to allow guest shutdown */
27589 + if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
27590 + /* forbid killall pid=0 when init is present */
27591 + (((vc_data.pid < 1) && vxi->vx_initpid) ||
27592 + (vc_data.pid > 1)))
27595 + return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
27599 +static int __wait_exit(struct vx_info *vxi)
27601 + DECLARE_WAITQUEUE(wait, current);
27604 + add_wait_queue(&vxi->vx_wait, &wait);
27605 + set_current_state(TASK_INTERRUPTIBLE);
27608 + if (vx_info_state(vxi,
27609 + VXS_SHUTDOWN|VXS_HASHED|VXS_HELPER) == VXS_SHUTDOWN)
27611 + if (signal_pending(current)) {
27612 + ret = -ERESTARTSYS;
27619 + set_current_state(TASK_RUNNING);
27620 + remove_wait_queue(&vxi->vx_wait, &wait);
27626 +int vc_wait_exit(struct vx_info *vxi, void __user *data)
27628 + struct vcmd_wait_exit_v0 vc_data;
27631 + ret = __wait_exit(vxi);
27632 + vc_data.reboot_cmd = vxi->reboot_cmd;
27633 + vc_data.exit_code = vxi->exit_code;
27635 + if (copy_to_user (data, &vc_data, sizeof(vc_data)))
27640 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/space.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/space.c
27641 --- linux-2.6.19.1/kernel/vserver/space.c 1970-01-01 01:00:00 +0100
27642 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/space.c 2006-12-17 19:44:46 +0100
27645 + * linux/kernel/vserver/space.c
27647 + * Virtual Server: Context Space Support
27649 + * Copyright (C) 2003-2006 Herbert Pötzl
27651 + * V0.01 broken out from context.c 0.07
27652 + * V0.02 added task locking for namespace
27653 + * V0.03 broken out vx_enter_namespace
27654 + * V0.04 added *space support and commands
27658 +#include <linux/utsname.h>
27659 +#include <linux/sched.h>
27660 +#include <linux/vs_context.h>
27661 +#include <linux/vserver/space.h>
27662 +#include <linux/vserver/space_cmd.h>
27663 +#include <linux/dcache.h>
27664 +#include <linux/mount.h>
27665 +#include <linux/fs.h>
27667 +#include <asm/errno.h>
27668 +#include <asm/uaccess.h>
27671 +/* namespace functions */
27673 +#include <linux/namespace.h>
27675 +const struct vcmd_space_mask space_mask = {
27676 + .mask = CLONE_NEWNS |
27684 + * build a new nsproxy mix
27685 + * assumes that both proxies are 'const'
27686 + * does not touch nsproxy refcounts
27689 +struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy,
27690 + struct nsproxy *new_nsproxy, unsigned long mask)
27692 + struct namespace *old_ns;
27693 + struct uts_namespace *old_uts;
27694 + struct ipc_namespace *old_ipc;
27695 + struct nsproxy *nsproxy;
27697 + old_ns = old_nsproxy->namespace;
27698 + old_uts = old_nsproxy->uts_ns;
27699 + old_ipc = old_nsproxy->ipc_ns;
27701 + nsproxy = dup_namespaces(old_nsproxy);
27705 + if (mask & CLONE_NEWNS) {
27706 + nsproxy->namespace = new_nsproxy->namespace;
27707 + if (nsproxy->namespace)
27708 + get_namespace(nsproxy->namespace);
27712 + if (mask & CLONE_NEWUTS) {
27713 + nsproxy->uts_ns = new_nsproxy->uts_ns;
27714 + if (nsproxy->uts_ns)
27715 + get_uts_ns(nsproxy->uts_ns);
27719 + if (mask & CLONE_NEWIPC) {
27720 + nsproxy->ipc_ns = new_nsproxy->ipc_ns;
27721 + if (nsproxy->ipc_ns)
27722 + get_ipc_ns(nsproxy->ipc_ns);
27727 + put_namespace(old_ns);
27729 + put_uts_ns(old_uts);
27731 + put_ipc_ns(old_ipc);
27737 +void __vs_merge_nsproxy(struct nsproxy **ptr,
27738 + struct nsproxy *nsproxy, unsigned long mask)
27740 + struct nsproxy *old = *ptr;
27741 + struct nsproxy null_proxy = { .namespace = NULL };
27743 + BUG_ON(!nsproxy);
27746 + *ptr = vs_mix_nsproxy(old ? old : &null_proxy,
27750 + get_nsproxy(nsproxy);
27753 + put_nsproxy(old);
27757 +void __vs_merge_fs(struct fs_struct **ptr, struct fs_struct *fs)
27759 + struct fs_struct *old = *ptr;
27762 + atomic_inc(&fs->count);
27764 + put_fs_struct(old);
27768 +int vx_enter_space(struct vx_info *vxi, unsigned long mask)
27770 + struct fs_struct *fs = NULL;
27771 + struct nsproxy *nsproxy;
27773 + if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
27777 + mask = vxi->vx_nsmask;
27779 + if ((mask & vxi->vx_nsmask) != mask)
27782 + nsproxy = vxi->vx_nsproxy;
27783 + if ((mask & CLONE_FS)) {
27784 + BUG_ON(!vxi->vx_fs);
27785 + fs = copy_fs_struct(vxi->vx_fs);
27790 + task_lock(current);
27792 + __vs_merge_nsproxy(¤t->nsproxy, nsproxy, mask);
27794 + __vs_merge_fs(¤t->fs, fs);
27795 + task_unlock(current);
27800 +int vx_set_space(struct vx_info *vxi, unsigned long mask)
27802 + struct fs_struct *fs, *fs_copy = NULL;
27803 + struct nsproxy *nsproxy;
27807 + mask = space_mask.mask;
27809 + if ((mask & space_mask.mask) != mask)
27812 + task_lock(current);
27813 + fs = current->fs;
27814 + atomic_inc(&fs->count);
27815 + nsproxy = current->nsproxy;
27816 + get_nsproxy(nsproxy);
27817 + task_unlock(current);
27820 + if ((mask & CLONE_FS)) {
27821 + fs_copy = copy_fs_struct(fs);
27827 + __vs_merge_nsproxy(&vxi->vx_nsproxy, nsproxy, mask);
27829 + __vs_merge_fs(&vxi->vx_fs, fs_copy);
27830 + vxi->vx_nsmask |= mask;
27834 + put_fs_struct(fs);
27835 + put_nsproxy(nsproxy);
27840 +int vc_enter_space(struct vx_info *vxi, void __user *data)
27842 + struct vcmd_space_mask vc_data = { .mask = 0 };
27844 + if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
27847 + return vx_enter_space(vxi, vc_data.mask);
27850 +int vc_set_space(struct vx_info *vxi, void __user *data)
27852 + struct vcmd_space_mask vc_data = { .mask = 0 };
27854 + if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
27857 + return vx_set_space(vxi, vc_data.mask);
27860 +int vc_get_space_mask(struct vx_info *vxi, void __user *data)
27862 + if (copy_to_user(data, &space_mask, sizeof(space_mask)))
27867 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/switch.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/switch.c
27868 --- linux-2.6.19.1/kernel/vserver/switch.c 1970-01-01 01:00:00 +0100
27869 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/switch.c 2006-12-17 04:45:00 +0100
27872 + * linux/kernel/vserver/switch.c
27874 + * Virtual Server: Syscall Switch
27876 + * Copyright (C) 2003-2006 Herbert Pötzl
27878 + * V0.01 syscall switch
27879 + * V0.02 added signal to context
27880 + * V0.03 added rlimit functions
27881 + * V0.04 added iattr, task/xid functions
27882 + * V0.05 added debug/history stuff
27883 + * V0.06 added compat32 layer
27884 + * V0.07 vcmd args and perms
27885 + * V0.08 added status commands
27889 +#include <linux/linkage.h>
27890 +#include <linux/sched.h>
27891 +#include <linux/compat.h>
27892 +#include <asm/errno.h>
27894 +#include <linux/vs_context.h>
27895 +#include <linux/vs_network.h>
27896 +#include <linux/vserver/switch.h>
27899 +int vc_get_version(uint32_t id)
27901 + return VCI_VERSION;
27904 +#include "vci_config.h"
27907 +int vc_get_vci(uint32_t id)
27909 + return vci_kernel_config();
27912 +#include <linux/vserver/context_cmd.h>
27913 +#include <linux/vserver/cvirt_cmd.h>
27914 +#include <linux/vserver/cacct_cmd.h>
27915 +#include <linux/vserver/limit_cmd.h>
27916 +#include <linux/vserver/network_cmd.h>
27917 +#include <linux/vserver/sched_cmd.h>
27918 +#include <linux/vserver/debug_cmd.h>
27919 +#include <linux/vserver/inode_cmd.h>
27920 +#include <linux/vserver/dlimit_cmd.h>
27921 +#include <linux/vserver/signal_cmd.h>
27922 +#include <linux/vserver/space_cmd.h>
27924 +#include <linux/vserver/inode.h>
27925 +#include <linux/vserver/dlimit.h>
27928 +#ifdef CONFIG_COMPAT
27929 +#define __COMPAT(name, id, data, compat) \
27930 + (compat) ? name ## _x32 (id, data) : name (id, data)
27932 +#define __COMPAT(name, id, data, compat) \
27938 +long do_vcmd(uint32_t cmd, uint32_t id,
27939 + struct vx_info *vxi, struct nx_info *nxi,
27940 + void __user *data, int compat)
27944 + case VCMD_get_version:
27945 + return vc_get_version(id);
27946 + case VCMD_get_vci:
27947 + return vc_get_vci(id);
27949 + case VCMD_task_xid:
27950 + return vc_task_xid(id, data);
27951 + case VCMD_vx_info:
27952 + return vc_vx_info(vxi, data);
27954 + case VCMD_task_nid:
27955 + return vc_task_nid(id, data);
27956 + case VCMD_nx_info:
27957 + return vc_nx_info(nxi, data);
27959 + case VCMD_set_space_v0:
27960 + /* this is version 1 */
27961 + case VCMD_set_space:
27962 + return vc_set_space(vxi, data);
27964 + case VCMD_get_space_mask:
27965 + return vc_get_space_mask(vxi, data);
27967 +#ifdef CONFIG_IA32_EMULATION
27968 + case VCMD_get_rlimit:
27969 + return __COMPAT(vc_get_rlimit, vxi, data, compat);
27970 + case VCMD_set_rlimit:
27971 + return __COMPAT(vc_set_rlimit, vxi, data, compat);
27973 + case VCMD_get_rlimit:
27974 + return vc_get_rlimit(vxi, data);
27975 + case VCMD_set_rlimit:
27976 + return vc_set_rlimit(vxi, data);
27978 + case VCMD_get_rlimit_mask:
27979 + return vc_get_rlimit_mask(id, data);
27980 + case VCMD_reset_minmax:
27981 + return vc_reset_minmax(vxi, data);
27983 + case VCMD_get_vhi_name:
27984 + return vc_get_vhi_name(vxi, data);
27985 + case VCMD_set_vhi_name:
27986 + return vc_set_vhi_name(vxi, data);
27988 + case VCMD_ctx_stat:
27989 + return vc_ctx_stat(vxi, data);
27990 + case VCMD_virt_stat:
27991 + return vc_virt_stat(vxi, data);
27992 + case VCMD_sock_stat:
27993 + return vc_sock_stat(vxi, data);
27994 + case VCMD_rlimit_stat:
27995 + return vc_rlimit_stat(vxi, data);
27997 + case VCMD_set_cflags:
27998 + return vc_set_cflags(vxi, data);
27999 + case VCMD_get_cflags:
28000 + return vc_get_cflags(vxi, data);
28002 + case VCMD_set_ccaps_v0:
28003 + return vc_set_ccaps_v0(vxi, data);
28004 + /* this is version 1 */
28005 + case VCMD_set_ccaps:
28006 + return vc_set_ccaps(vxi, data);
28007 + case VCMD_get_ccaps_v0:
28008 + return vc_get_ccaps_v0(vxi, data);
28009 + /* this is version 1 */
28010 + case VCMD_get_ccaps:
28011 + return vc_get_ccaps(vxi, data);
28012 + case VCMD_set_bcaps:
28013 + return vc_set_bcaps(vxi, data);
28014 + case VCMD_get_bcaps:
28015 + return vc_get_bcaps(vxi, data);
28017 + case VCMD_set_nflags:
28018 + return vc_set_nflags(nxi, data);
28019 + case VCMD_get_nflags:
28020 + return vc_get_nflags(nxi, data);
28022 + case VCMD_set_ncaps:
28023 + return vc_set_ncaps(nxi, data);
28024 + case VCMD_get_ncaps:
28025 + return vc_get_ncaps(nxi, data);
28027 + case VCMD_set_sched_v3:
28028 + return vc_set_sched_v3(vxi, data);
28029 + /* this is version 4 */
28030 + case VCMD_set_sched:
28031 + return vc_set_sched(vxi, data);
28033 + case VCMD_add_dlimit:
28034 + return __COMPAT(vc_add_dlimit, id, data, compat);
28035 + case VCMD_rem_dlimit:
28036 + return __COMPAT(vc_rem_dlimit, id, data, compat);
28037 + case VCMD_set_dlimit:
28038 + return __COMPAT(vc_set_dlimit, id, data, compat);
28039 + case VCMD_get_dlimit:
28040 + return __COMPAT(vc_get_dlimit, id, data, compat);
28042 + case VCMD_ctx_kill:
28043 + return vc_ctx_kill(vxi, data);
28045 + case VCMD_wait_exit:
28046 + return vc_wait_exit(vxi, data);
28048 + case VCMD_get_iattr:
28049 + return __COMPAT(vc_get_iattr, id, data, compat);
28050 + case VCMD_set_iattr:
28051 + return __COMPAT(vc_set_iattr, id, data, compat);
28053 + case VCMD_enter_space_v0:
28054 + return vc_enter_space(vxi, NULL);
28055 + /* this is version 1 */
28056 + case VCMD_enter_space:
28057 + return vc_enter_space(vxi, data);
28059 + case VCMD_ctx_create_v0:
28060 + return vc_ctx_create(id, NULL);
28061 + case VCMD_ctx_create:
28062 + return vc_ctx_create(id, data);
28063 + case VCMD_ctx_migrate_v0:
28064 + return vc_ctx_migrate(vxi, NULL);
28065 + case VCMD_ctx_migrate:
28066 + return vc_ctx_migrate(vxi, data);
28068 + case VCMD_net_create_v0:
28069 + return vc_net_create(id, NULL);
28070 + case VCMD_net_create:
28071 + return vc_net_create(id, data);
28072 + case VCMD_net_migrate:
28073 + return vc_net_migrate(nxi, data);
28074 + case VCMD_net_add:
28075 + return vc_net_add(nxi, data);
28076 + case VCMD_net_remove:
28077 + return vc_net_remove(nxi, data);
28079 +#ifdef CONFIG_VSERVER_HISTORY
28080 + case VCMD_dump_history:
28081 + return vc_dump_history(id);
28082 + case VCMD_read_history:
28083 + return __COMPAT(vc_read_history, id, data, compat);
28085 +#ifdef CONFIG_VSERVER_MONITOR
28086 + case VCMD_read_monitor:
28087 + return __COMPAT(vc_read_monitor, id, data, compat);
28090 + vxwprintk(1, "unimplemented VCMD_%02d_%d[%d]",
28091 + VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
28097 +#define __VCMD(vcmd, _perm, _args, _flags) \
28098 + case VCMD_ ## vcmd: perm = _perm; \
28099 + args = _args; flags = _flags; break
28102 +#define VCA_NONE 0x00
28103 +#define VCA_VXI 0x01
28104 +#define VCA_NXI 0x02
28106 +#define VCF_NONE 0x00
28107 +#define VCF_INFO 0x01
28108 +#define VCF_ADMIN 0x02
28109 +#define VCF_ARES 0x06 /* includes admin */
28110 +#define VCF_SETUP 0x08
28114 +long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
28117 + int permit = -1, state = 0;
28118 + int perm = -1, args = 0, flags = 0;
28119 + struct vx_info *vxi = NULL;
28120 + struct nx_info *nxi = NULL;
28123 + /* unpriviledged commands */
28124 + __VCMD(get_version, 0, VCA_NONE, 0);
28125 + __VCMD(get_vci, 0, VCA_NONE, 0);
28126 + __VCMD(get_rlimit_mask, 0, VCA_NONE, 0);
28127 + __VCMD(get_space_mask, 0, VCA_NONE, 0);
28129 + /* info commands */
28130 + __VCMD(task_xid, 2, VCA_NONE, 0);
28131 + __VCMD(reset_minmax, 2, VCA_VXI, 0);
28132 + __VCMD(vx_info, 3, VCA_VXI, VCF_INFO);
28133 + __VCMD(get_bcaps, 3, VCA_VXI, VCF_INFO);
28134 + __VCMD(get_ccaps_v0, 3, VCA_VXI, VCF_INFO);
28135 + __VCMD(get_ccaps, 3, VCA_VXI, VCF_INFO);
28136 + __VCMD(get_cflags, 3, VCA_VXI, VCF_INFO);
28137 + __VCMD(get_vhi_name, 3, VCA_VXI, VCF_INFO);
28138 + __VCMD(get_rlimit, 3, VCA_VXI, VCF_INFO);
28140 + __VCMD(ctx_stat, 3, VCA_VXI, VCF_INFO);
28141 + __VCMD(virt_stat, 3, VCA_VXI, VCF_INFO);
28142 + __VCMD(sock_stat, 3, VCA_VXI, VCF_INFO);
28143 + __VCMD(rlimit_stat, 3, VCA_VXI, VCF_INFO);
28145 + __VCMD(task_nid, 2, VCA_NONE, 0);
28146 + __VCMD(nx_info, 3, VCA_NXI, VCF_INFO);
28147 + __VCMD(get_ncaps, 3, VCA_NXI, VCF_INFO);
28148 + __VCMD(get_nflags, 3, VCA_NXI, VCF_INFO);
28150 + __VCMD(get_iattr, 2, VCA_NONE, 0);
28151 + __VCMD(get_dlimit, 3, VCA_NONE, VCF_INFO);
28153 + /* lower admin commands */
28154 + __VCMD(wait_exit, 4, VCA_VXI, VCF_INFO);
28155 + __VCMD(ctx_create_v0, 5, VCA_NONE, 0);
28156 + __VCMD(ctx_create, 5, VCA_NONE, 0);
28157 + __VCMD(ctx_migrate_v0, 5, VCA_VXI, VCF_ADMIN);
28158 + __VCMD(ctx_migrate, 5, VCA_VXI, VCF_ADMIN);
28159 + __VCMD(enter_space_v0, 5, VCA_VXI, VCF_ADMIN);
28160 + __VCMD(enter_space, 5, VCA_VXI, VCF_ADMIN);
28162 + __VCMD(net_create_v0, 5, VCA_NONE, 0);
28163 + __VCMD(net_create, 5, VCA_NONE, 0);
28164 + __VCMD(net_migrate, 5, VCA_NXI, VCF_ADMIN);
28166 + /* higher admin commands */
28167 + __VCMD(ctx_kill, 6, VCA_VXI, VCF_ARES);
28168 + __VCMD(set_space_v0, 7, VCA_VXI, VCF_ARES|VCF_SETUP);
28169 + __VCMD(set_space, 7, VCA_VXI, VCF_ARES|VCF_SETUP);
28171 + __VCMD(set_ccaps_v0, 7, VCA_VXI, VCF_ARES|VCF_SETUP);
28172 + __VCMD(set_ccaps, 7, VCA_VXI, VCF_ARES|VCF_SETUP);
28173 + __VCMD(set_bcaps, 7, VCA_VXI, VCF_ARES|VCF_SETUP);
28174 + __VCMD(set_cflags, 7, VCA_VXI, VCF_ARES|VCF_SETUP);
28176 + __VCMD(set_vhi_name, 7, VCA_VXI, VCF_ARES|VCF_SETUP);
28177 + __VCMD(set_rlimit, 7, VCA_VXI, VCF_ARES|VCF_SETUP);
28178 + __VCMD(set_sched, 7, VCA_VXI, VCF_ARES|VCF_SETUP);
28179 + __VCMD(set_sched_v2, 7, VCA_VXI, VCF_ARES|VCF_SETUP);
28180 + __VCMD(set_sched_v3, 7, VCA_VXI, VCF_ARES|VCF_SETUP);
28182 + __VCMD(set_ncaps, 7, VCA_NXI, VCF_ARES|VCF_SETUP);
28183 + __VCMD(set_nflags, 7, VCA_NXI, VCF_ARES|VCF_SETUP);
28184 + __VCMD(net_add, 8, VCA_NXI, VCF_ARES|VCF_SETUP);
28185 + __VCMD(net_remove, 8, VCA_NXI, VCF_ARES|VCF_SETUP);
28187 + __VCMD(set_iattr, 7, VCA_NONE, 0);
28188 + __VCMD(set_dlimit, 7, VCA_NONE, VCF_ARES);
28189 + __VCMD(add_dlimit, 8, VCA_NONE, VCF_ARES);
28190 + __VCMD(rem_dlimit, 8, VCA_NONE, VCF_ARES);
28192 + /* debug level admin commands */
28193 +#ifdef CONFIG_VSERVER_HISTORY
28194 + __VCMD(dump_history, 9, VCA_NONE, 0);
28195 + __VCMD(read_history, 9, VCA_NONE, 0);
28197 +#ifdef CONFIG_VSERVER_MONITOR
28198 + __VCMD(read_monitor, 9, VCA_NONE, 0);
28204 + vxdprintk(VXD_CBIT(switch, 0),
28205 + "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
28206 + VC_CATEGORY(cmd), VC_COMMAND(cmd),
28207 + VC_VERSION(cmd), id, data, compat,
28208 + perm, args, flags);
28215 + if (!capable(CAP_CONTEXT))
28219 + /* moved here from the individual commands */
28221 + if ((perm > 1) && !capable(CAP_SYS_ADMIN))
28225 + /* vcmd involves resource management */
28227 + if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
28231 + /* various legacy exceptions */
28233 + /* will go away when admin is a cap */
28234 + case VCMD_ctx_migrate_v0:
28235 + case VCMD_ctx_migrate:
28237 + current->xid = 1;
28243 + /* legacy special casing */
28244 + case VCMD_set_space_v0:
28249 + /* vcmds are fine by default */
28252 + /* admin type vcmds require admin ... */
28253 + if (flags & VCF_ADMIN)
28254 + permit = vx_check(0, VS_ADMIN) ? 1 : 0;
28256 + /* ... but setup type vcmds override that */
28257 + if (!permit && (flags & VCF_SETUP))
28258 + permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
28267 + if (args & VCA_VXI) {
28268 + vxi = lookup_vx_info(id);
28272 + if ((flags & VCF_ADMIN) &&
28273 + /* special case kill for shutdown */
28274 + (cmd != VCMD_ctx_kill) &&
28275 + /* can context be administrated? */
28276 + !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
28282 + if (args & VCA_NXI) {
28283 + nxi = lookup_nx_info(id);
28287 + if ((flags & VCF_ADMIN) &&
28288 + /* can context be administrated? */
28289 + !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
28296 + ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
28299 + if (args & VCA_NXI)
28300 + put_nx_info(nxi);
28302 + if (args & VCA_VXI)
28303 + put_vx_info(vxi);
28305 + vxdprintk(VXD_CBIT(switch, 1),
28306 + "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
28307 + VC_CATEGORY(cmd), VC_COMMAND(cmd),
28308 + VC_VERSION(cmd), ret, ret, state, permit);
28313 +sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
28315 + return do_vserver(cmd, id, data, 0);
28318 +#ifdef CONFIG_COMPAT
28321 +sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
28323 + return do_vserver(cmd, id, data, 1);
28326 +#endif /* CONFIG_COMPAT */
28327 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/sysctl.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sysctl.c
28328 --- linux-2.6.19.1/kernel/vserver/sysctl.c 1970-01-01 01:00:00 +0100
28329 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sysctl.c 2006-11-08 04:57:40 +0100
28332 + * kernel/vserver/sysctl.c
28334 + * Virtual Context Support
28336 + * Copyright (C) 2004-2005 Herbert Pötzl
28338 + * V0.01 basic structure
28342 +#include <linux/errno.h>
28343 +#include <linux/module.h>
28344 +#include <linux/types.h>
28345 +#include <linux/ctype.h>
28346 +#include <linux/sysctl.h>
28347 +#include <linux/parser.h>
28348 +#include <linux/fs.h>
28350 +#include <asm/uaccess.h>
28351 +#include <asm/unistd.h>
28354 +#define CTL_VSERVER 4242 /* unused? */
28357 + CTL_DEBUG_ERROR = 0,
28358 + CTL_DEBUG_SWITCH = 1,
28372 +unsigned int vx_debug_switch = 0;
28373 +unsigned int vx_debug_xid = 0;
28374 +unsigned int vx_debug_nid = 0;
28375 +unsigned int vx_debug_tag = 0;
28376 +unsigned int vx_debug_net = 0;
28377 +unsigned int vx_debug_limit = 0;
28378 +unsigned int vx_debug_cres = 0;
28379 +unsigned int vx_debug_dlim = 0;
28380 +unsigned int vx_debug_quota = 0;
28381 +unsigned int vx_debug_cvirt = 0;
28382 +unsigned int vx_debug_misc = 0;
28385 +static struct ctl_table_header *vserver_table_header;
28386 +static ctl_table vserver_table[];
28389 +void vserver_register_sysctl(void)
28391 + if (!vserver_table_header) {
28392 + vserver_table_header = register_sysctl_table(vserver_table, 1);
28397 +void vserver_unregister_sysctl(void)
28399 + if (vserver_table_header) {
28400 + unregister_sysctl_table(vserver_table_header);
28401 + vserver_table_header = NULL;
28406 +static int proc_dodebug(ctl_table *table, int write,
28407 + struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
28409 + char tmpbuf[20], *p, c;
28410 + unsigned int value;
28411 + size_t left, len;
28413 + if ((*ppos && !write) || !*lenp) {
28421 + if (!access_ok(VERIFY_READ, buffer, left))
28423 + p = (char *) buffer;
28424 + while (left && __get_user(c, p) >= 0 && isspace(c))
28429 + if (left > sizeof(tmpbuf) - 1)
28431 + if (copy_from_user(tmpbuf, p, left))
28433 + tmpbuf[left] = '\0';
28435 + for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
28436 + value = 10 * value + (*p - '0');
28437 + if (*p && !isspace(*p))
28439 + while (left && isspace(*p))
28441 + *(unsigned int *) table->data = value;
28443 + if (!access_ok(VERIFY_WRITE, buffer, left))
28445 + len = sprintf(tmpbuf, "%d", *(unsigned int *) table->data);
28448 + if (__copy_to_user(buffer, tmpbuf, len))
28450 + if ((left -= len) > 0) {
28451 + if (put_user('\n', (char *)buffer + len))
28464 +#define CTL_ENTRY(ctl, name) \
28466 + .ctl_name = ctl, \
28467 + .procname = #name, \
28468 + .data = &vx_##name, \
28469 + .maxlen = sizeof(int), \
28471 + .proc_handler = &proc_dodebug \
28474 +static ctl_table debug_table[] = {
28475 + CTL_ENTRY (CTL_DEBUG_SWITCH, debug_switch),
28476 + CTL_ENTRY (CTL_DEBUG_XID, debug_xid),
28477 + CTL_ENTRY (CTL_DEBUG_NID, debug_nid),
28478 + CTL_ENTRY (CTL_DEBUG_TAG, debug_tag),
28479 + CTL_ENTRY (CTL_DEBUG_NET, debug_net),
28480 + CTL_ENTRY (CTL_DEBUG_LIMIT, debug_limit),
28481 + CTL_ENTRY (CTL_DEBUG_CRES, debug_cres),
28482 + CTL_ENTRY (CTL_DEBUG_DLIM, debug_dlim),
28483 + CTL_ENTRY (CTL_DEBUG_QUOTA, debug_quota),
28484 + CTL_ENTRY (CTL_DEBUG_CVIRT, debug_cvirt),
28485 + CTL_ENTRY (CTL_DEBUG_MISC, debug_misc),
28486 + { .ctl_name = 0 }
28489 +static ctl_table vserver_table[] = {
28491 + .ctl_name = CTL_VSERVER,
28492 + .procname = "vserver",
28494 + .child = debug_table
28496 + { .ctl_name = 0 }
28500 +static match_table_t tokens = {
28501 + { CTL_DEBUG_SWITCH, "switch=%x" },
28502 + { CTL_DEBUG_XID, "xid=%x" },
28503 + { CTL_DEBUG_NID, "nid=%x" },
28504 + { CTL_DEBUG_TAG, "tag=%x" },
28505 + { CTL_DEBUG_NET, "net=%x" },
28506 + { CTL_DEBUG_LIMIT, "limit=%x" },
28507 + { CTL_DEBUG_CRES, "cres=%x" },
28508 + { CTL_DEBUG_DLIM, "dlim=%x" },
28509 + { CTL_DEBUG_QUOTA, "quota=%x" },
28510 + { CTL_DEBUG_CVIRT, "cvirt=%x" },
28511 + { CTL_DEBUG_MISC, "misc=%x" },
28512 + { CTL_DEBUG_ERROR, NULL }
28515 +#define HANDLE_CASE(id, name, val) \
28516 + case CTL_DEBUG_ ## id: \
28517 + vx_debug_ ## name = val; \
28518 + printk("vs_debug_" #name "=0x%x\n", val); \
28522 +static int __init vs_debug_setup(char *str)
28527 + printk("vs_debug_setup(%s)\n", str);
28528 + while ((p = strsep(&str, ",")) != NULL) {
28529 + substring_t args[MAX_OPT_ARGS];
28530 + unsigned int value;
28535 + token = match_token(p, tokens, args);
28536 + value = (token>0)?simple_strtoul(args[0].from, NULL, 0):0;
28539 + HANDLE_CASE(SWITCH, switch, value);
28540 + HANDLE_CASE(XID, xid, value);
28541 + HANDLE_CASE(NID, nid, value);
28542 + HANDLE_CASE(TAG, tag, value);
28543 + HANDLE_CASE(NET, net, value);
28544 + HANDLE_CASE(LIMIT, limit, value);
28545 + HANDLE_CASE(CRES, cres, value);
28546 + HANDLE_CASE(DLIM, dlim, value);
28547 + HANDLE_CASE(QUOTA, quota, value);
28548 + HANDLE_CASE(CVIRT, cvirt, value);
28549 + HANDLE_CASE(MISC, misc, value);
28558 +__setup("vsdebug=", vs_debug_setup);
28562 +EXPORT_SYMBOL_GPL(vx_debug_switch);
28563 +EXPORT_SYMBOL_GPL(vx_debug_xid);
28564 +EXPORT_SYMBOL_GPL(vx_debug_nid);
28565 +EXPORT_SYMBOL_GPL(vx_debug_net);
28566 +EXPORT_SYMBOL_GPL(vx_debug_limit);
28567 +EXPORT_SYMBOL_GPL(vx_debug_cres);
28568 +EXPORT_SYMBOL_GPL(vx_debug_dlim);
28569 +EXPORT_SYMBOL_GPL(vx_debug_quota);
28570 +EXPORT_SYMBOL_GPL(vx_debug_cvirt);
28571 +EXPORT_SYMBOL_GPL(vx_debug_misc);
28573 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/vci_config.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/vci_config.h
28574 --- linux-2.6.19.1/kernel/vserver/vci_config.h 1970-01-01 01:00:00 +0100
28575 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/vci_config.h 2006-12-17 04:40:29 +0100
28579 + VCI_KCBIT_NO_DYNAMIC = 0,
28580 + VCI_KCBIT_LEGACY = 1,
28581 + VCI_KCBIT_LEGACYNET = 2,
28582 + VCI_KCBIT_NGNET = 3,
28584 + VCI_KCBIT_PROC_SECURE = 4,
28585 + VCI_KCBIT_HARDCPU = 5,
28586 + VCI_KCBIT_IDLELIMIT = 6,
28587 + VCI_KCBIT_IDLETIME = 7,
28589 + VCI_KCBIT_COWBL = 8,
28590 + VCI_KCBIT_FULLCOWBL = 9,
28591 + VCI_KCBIT_SPACES = 10,
28593 + VCI_KCBIT_LEGACY_VERSION = 15,
28594 + VCI_KCBIT_DEBUG = 16,
28595 + VCI_KCBIT_HISTORY = 20,
28596 + VCI_KCBIT_TAGGED = 24,
28600 +static inline uint32_t vci_kernel_config(void)
28603 + (1 << VCI_KCBIT_NO_DYNAMIC) |
28604 + (1 << VCI_KCBIT_NGNET) |
28606 + /* configured features */
28607 +#ifdef CONFIG_VSERVER_PROC_SECURE
28608 + (1 << VCI_KCBIT_PROC_SECURE) |
28610 +#ifdef CONFIG_VSERVER_HARDCPU
28611 + (1 << VCI_KCBIT_HARDCPU) |
28613 +#ifdef CONFIG_VSERVER_IDLELIMIT
28614 + (1 << VCI_KCBIT_IDLELIMIT) |
28616 +#ifdef CONFIG_VSERVER_IDLETIME
28617 + (1 << VCI_KCBIT_IDLETIME) |
28619 +#ifdef CONFIG_VSERVER_COWBL
28620 + (1 << VCI_KCBIT_COWBL) |
28621 + (1 << VCI_KCBIT_FULLCOWBL) |
28623 + (1 << VCI_KCBIT_SPACES) |
28625 + /* debug options */
28626 +#ifdef CONFIG_VSERVER_DEBUG
28627 + (1 << VCI_KCBIT_DEBUG) |
28629 +#ifdef CONFIG_VSERVER_HISTORY
28630 + (1 << VCI_KCBIT_HISTORY) |
28632 + /* inode context tagging */
28633 +#if defined(CONFIG_TAGGING_NONE)
28634 + (0 << VCI_KCBIT_TAGGED) |
28635 +#elif defined(CONFIG_TAGGING_UID16)
28636 + (1 << VCI_KCBIT_TAGGED) |
28637 +#elif defined(CONFIG_TAGGING_GID16)
28638 + (2 << VCI_KCBIT_TAGGED) |
28639 +#elif defined(CONFIG_TAGGING_ID24)
28640 + (3 << VCI_KCBIT_TAGGED) |
28641 +#elif defined(CONFIG_TAGGING_INTERN)
28642 + (4 << VCI_KCBIT_TAGGED) |
28643 +#elif defined(CONFIG_TAGGING_RUNTIME)
28644 + (5 << VCI_KCBIT_TAGGED) |
28646 + (7 << VCI_KCBIT_TAGGED) |
28651 diff -NurpP --minimal linux-2.6.19.1/mm/filemap.c linux-2.6.19.1-vs2.3.0.6/mm/filemap.c
28652 --- linux-2.6.19.1/mm/filemap.c 2006-11-30 21:19:44 +0100
28653 +++ linux-2.6.19.1-vs2.3.0.6/mm/filemap.c 2006-11-08 22:42:35 +0100
28654 @@ -1236,6 +1236,31 @@ int file_send_actor(read_descriptor_t *
28658 +/* FIXME: It would be as simple as this, if we had a (void __user*) to write.
28659 + * We already have a kernel buffer, so it should be even simpler, right? ;)
28661 + * Yes, sorta. After duplicating the complete path of generic_file_write(),
28662 + * at least some special cases could be removed, so the copy is simpler than
28663 + * the original. But it remains a copy, so overall complexity increases.
28666 +generic_kernel_file_write(struct file *, const char *, size_t, loff_t *);
28668 +ssize_t generic_file_sendpage(struct file *file, struct page *page,
28669 + int offset, size_t size, loff_t *ppos, int more)
28674 + kaddr = kmap(page);
28675 + ret = generic_kernel_file_write(file, kaddr + offset, size, ppos);
28681 +EXPORT_SYMBOL(generic_file_sendpage);
28683 ssize_t generic_file_sendfile(struct file *in_file, loff_t *ppos,
28684 size_t count, read_actor_t actor, void *target)
28686 @@ -1913,6 +1938,19 @@ int remove_suid(struct dentry *dentry)
28688 EXPORT_SYMBOL(remove_suid);
28690 +static inline size_t
28691 +filemap_copy_from_kernel(struct page *page, unsigned long offset,
28692 + const char *buf, unsigned bytes)
28696 + kaddr = kmap(page);
28697 + memcpy(kaddr + offset, buf, bytes);
28704 __filemap_copy_from_user_iovec_inatomic(char *vaddr,
28705 const struct iovec *iov, size_t base, size_t bytes)
28706 @@ -2219,6 +2257,175 @@ zero_length_segment:
28708 EXPORT_SYMBOL(generic_file_buffered_write);
28710 +static inline void
28711 +filemap_set_next_kvec(const struct kvec **iovp, size_t *basep, size_t bytes)
28713 + const struct kvec *iov = *iovp;
28714 + size_t base = *basep;
28717 + int copy = min(bytes, iov->iov_len - base);
28721 + if (iov->iov_len == base) {
28732 + * This largely tries to copy generic_file_aio_write_nolock(), although it
28733 + * doesn't have to be nearly as generic. A real cleanup should either
28734 + * merge this into generic_file_aio_write_nolock() as well or keep it special
28735 + * and remove as much code as possible.
28738 +generic_kernel_file_aio_write_nolock(struct kiocb *iocb, const struct kvec*iov,
28739 + unsigned long nr_segs, loff_t *ppos)
28741 + struct file *file = iocb->ki_filp;
28742 + struct address_space * mapping = file->f_mapping;
28743 + const struct address_space_operations *a_ops = mapping->a_ops;
28744 + size_t ocount; /* original count */
28745 + size_t count; /* after file limit checks */
28746 + struct inode *inode = mapping->host;
28749 + struct page *page;
28750 + struct page *cached_page = NULL;
28751 + const int isblk = S_ISBLK(inode->i_mode);
28755 + struct pagevec lru_pvec;
28756 + const struct kvec *cur_iov = iov; /* current kvec */
28757 + size_t iov_base = 0; /* offset in the current kvec */
28758 + unsigned long seg;
28762 + for (seg = 0; seg < nr_segs; seg++) {
28763 + const struct kvec *iv = &iov[seg];
28766 + * If any segment has a negative length, or the cumulative
28767 + * length ever wraps negative then return -EINVAL.
28769 + ocount += iv->iov_len;
28770 + if (unlikely((ssize_t)(ocount|iv->iov_len) < 0))
28776 + pagevec_init(&lru_pvec, 0);
28778 + /* We can write back this queue in page reclaim */
28779 + current->backing_dev_info = mapping->backing_dev_info;
28782 + err = generic_write_checks(file, &pos, &count, isblk);
28790 + remove_suid(file->f_dentry);
28791 + file_update_time(file);
28793 + /* There is no sane reason to use O_DIRECT */
28794 + BUG_ON(file->f_flags & O_DIRECT);
28796 + buf = iov->iov_base;
28798 + unsigned long index;
28799 + unsigned long offset;
28802 + offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
28803 + index = pos >> PAGE_CACHE_SHIFT;
28804 + bytes = PAGE_CACHE_SIZE - offset;
28805 + if (bytes > count)
28808 + page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
28810 + status = -ENOMEM;
28814 + status = a_ops->prepare_write(file, page, offset, offset+bytes);
28815 + if (unlikely(status)) {
28816 + loff_t isize = i_size_read(inode);
28818 + * prepare_write() may have instantiated a few blocks
28819 + * outside i_size. Trim these off again.
28821 + unlock_page(page);
28822 + page_cache_release(page);
28823 + if (pos + bytes > isize)
28824 + vmtruncate(inode, isize);
28828 + BUG_ON(nr_segs != 1);
28829 + copied = filemap_copy_from_kernel(page, offset, buf, bytes);
28831 + flush_dcache_page(page);
28832 + status = a_ops->commit_write(file, page, offset, offset+bytes);
28833 + if (likely(copied > 0)) {
28837 + if (status >= 0) {
28838 + written += status;
28842 + if (unlikely(nr_segs > 1))
28843 + filemap_set_next_kvec(&cur_iov,
28844 + &iov_base, status);
28847 + if (unlikely(copied != bytes))
28849 + status = -EFAULT;
28850 + unlock_page(page);
28851 + mark_page_accessed(page);
28852 + page_cache_release(page);
28855 + balance_dirty_pages_ratelimited(mapping);
28861 + page_cache_release(cached_page);
28864 + * For now, when the user asks for O_SYNC, we'll actually give O_DSYNC
28866 + if (status >= 0) {
28867 + if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
28868 + status = generic_osync_inode(inode, mapping,
28869 + OSYNC_METADATA|OSYNC_DATA);
28872 + err = written ? written : status;
28874 + pagevec_lru_add(&lru_pvec);
28875 + current->backing_dev_info = 0;
28880 __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
28881 unsigned long nr_segs, loff_t *ppos)
28882 @@ -2335,6 +2542,36 @@ out:
28883 return written ? written : err;
28887 +generic_kernel_file_write_nolock(struct file *file, const struct kvec *iov,
28888 + unsigned long nr_segs, loff_t *ppos)
28890 + struct kiocb kiocb;
28893 + init_sync_kiocb(&kiocb, file);
28894 + ret = generic_kernel_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
28895 + if (ret == -EIOCBQUEUED)
28896 + ret = wait_on_sync_kiocb(&kiocb);
28900 +static ssize_t generic_kernel_file_write(struct file *file, const char *buf,
28901 + size_t count, loff_t *ppos)
28903 + struct inode *inode = file->f_mapping->host;
28905 + struct kvec local_iov = { .iov_base = (char *) buf,
28906 + .iov_len = count };
28908 + mutex_lock(&inode->i_mutex);
28909 + err = generic_kernel_file_write_nolock(file, &local_iov, 1, ppos);
28910 + mutex_unlock(&inode->i_mutex);
28916 ssize_t generic_file_aio_write_nolock(struct kiocb *iocb,
28917 const struct iovec *iov, unsigned long nr_segs, loff_t pos)
28919 diff -NurpP --minimal linux-2.6.19.1/mm/filemap_xip.c linux-2.6.19.1-vs2.3.0.6/mm/filemap_xip.c
28920 --- linux-2.6.19.1/mm/filemap_xip.c 2006-09-20 16:58:44 +0200
28921 +++ linux-2.6.19.1-vs2.3.0.6/mm/filemap_xip.c 2006-11-08 04:57:40 +0100
28923 #include <linux/module.h>
28924 #include <linux/uio.h>
28925 #include <linux/rmap.h>
28926 +#include <linux/vs_memory.h>
28927 #include <asm/tlbflush.h>
28928 #include "filemap.h"
28930 diff -NurpP --minimal linux-2.6.19.1/mm/fremap.c linux-2.6.19.1-vs2.3.0.6/mm/fremap.c
28931 --- linux-2.6.19.1/mm/fremap.c 2006-11-30 21:19:44 +0100
28932 +++ linux-2.6.19.1-vs2.3.0.6/mm/fremap.c 2006-11-30 19:31:41 +0100
28934 #include <linux/rmap.h>
28935 #include <linux/module.h>
28936 #include <linux/syscalls.h>
28937 +#include <linux/vs_memory.h>
28939 #include <asm/mmu_context.h>
28940 #include <asm/cacheflush.h>
28941 @@ -74,6 +75,8 @@ int install_page(struct mm_struct *mm, s
28943 if (page_mapcount(page) > INT_MAX/2)
28945 + if (!vx_rss_avail(mm, 1))
28948 if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte))
28949 inc_mm_counter(mm, file_rss);
28950 diff -NurpP --minimal linux-2.6.19.1/mm/hugetlb.c linux-2.6.19.1-vs2.3.0.6/mm/hugetlb.c
28951 --- linux-2.6.19.1/mm/hugetlb.c 2006-11-30 21:19:44 +0100
28952 +++ linux-2.6.19.1-vs2.3.0.6/mm/hugetlb.c 2006-11-08 04:57:40 +0100
28954 #include <asm/pgtable.h>
28956 #include <linux/hugetlb.h>
28957 +#include <linux/vs_memory.h>
28958 #include "internal.h"
28960 const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
28961 diff -NurpP --minimal linux-2.6.19.1/mm/memory.c linux-2.6.19.1-vs2.3.0.6/mm/memory.c
28962 --- linux-2.6.19.1/mm/memory.c 2006-11-30 21:19:44 +0100
28963 +++ linux-2.6.19.1-vs2.3.0.6/mm/memory.c 2006-11-30 19:31:41 +0100
28964 @@ -498,6 +498,9 @@ static int copy_pte_range(struct mm_stru
28968 + if (!vx_rss_avail(dst_mm, ((end - addr)/PAGE_SIZE + 1)))
28972 rss[1] = rss[0] = 0;
28973 dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
28974 @@ -2011,6 +2014,11 @@ static int do_swap_page(struct mm_struct
28978 + if (!vx_rss_avail(mm, 1)) {
28979 + ret = VM_FAULT_OOM;
28983 delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
28984 mark_page_accessed(page);
28986 @@ -2083,6 +2091,8 @@ static int do_anonymous_page(struct mm_s
28987 /* Allocate our own private page. */
28988 pte_unmap(page_table);
28990 + if (!vx_rss_avail(mm, 1))
28992 if (unlikely(anon_vma_prepare(vma)))
28994 page = alloc_zeroed_user_highpage(vma, address);
28995 @@ -2156,6 +2166,9 @@ static int do_no_page(struct mm_struct *
28996 pte_unmap(page_table);
28997 BUG_ON(vma->vm_flags & VM_PFNMAP);
28999 + if (!vx_rss_avail(mm, 1))
29000 + return VM_FAULT_OOM;
29002 if (vma->vm_file) {
29003 mapping = vma->vm_file->f_mapping;
29004 sequence = mapping->truncate_count;
29005 @@ -2380,6 +2393,7 @@ static inline int handle_pte_fault(struc
29009 + int ret, type = VXPT_UNKNOWN;
29011 old_entry = entry = *pte;
29012 if (!pte_present(entry)) {
29013 @@ -2408,9 +2422,12 @@ static inline int handle_pte_fault(struc
29014 if (unlikely(!pte_same(*pte, entry)))
29016 if (write_access) {
29017 - if (!pte_write(entry))
29018 - return do_wp_page(mm, vma, address,
29019 + if (!pte_write(entry)) {
29020 + ret = do_wp_page(mm, vma, address,
29021 pte, pmd, ptl, entry);
29022 + type = VXPT_WRITE;
29025 entry = pte_mkdirty(entry);
29027 entry = pte_mkyoung(entry);
29028 @@ -2430,7 +2447,10 @@ static inline int handle_pte_fault(struc
29031 pte_unmap_unlock(pte, ptl);
29032 - return VM_FAULT_MINOR;
29033 + ret = VM_FAULT_MINOR;
29035 + vx_page_fault(mm, vma, type, ret);
29040 diff -NurpP --minimal linux-2.6.19.1/mm/mlock.c linux-2.6.19.1-vs2.3.0.6/mm/mlock.c
29041 --- linux-2.6.19.1/mm/mlock.c 2006-04-09 13:49:58 +0200
29042 +++ linux-2.6.19.1-vs2.3.0.6/mm/mlock.c 2006-11-08 04:57:47 +0100
29044 #include <linux/mm.h>
29045 #include <linux/mempolicy.h>
29046 #include <linux/syscalls.h>
29047 +#include <linux/vs_memory.h>
29050 static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
29051 @@ -65,7 +66,7 @@ success:
29052 ret = make_pages_present(start, end);
29055 - vma->vm_mm->locked_vm -= pages;
29056 + vx_vmlocked_sub(vma->vm_mm, pages);
29058 if (ret == -ENOMEM)
29060 @@ -123,7 +124,7 @@ static int do_mlock(unsigned long start,
29062 asmlinkage long sys_mlock(unsigned long start, size_t len)
29064 - unsigned long locked;
29065 + unsigned long locked, grow;
29066 unsigned long lock_limit;
29067 int error = -ENOMEM;
29069 @@ -134,8 +135,10 @@ asmlinkage long sys_mlock(unsigned long
29070 len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
29071 start &= PAGE_MASK;
29073 - locked = len >> PAGE_SHIFT;
29074 - locked += current->mm->locked_vm;
29075 + grow = len >> PAGE_SHIFT;
29076 + if (!vx_vmlocked_avail(current->mm, grow))
29078 + locked = current->mm->locked_vm + grow;
29080 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
29081 lock_limit >>= PAGE_SHIFT;
29082 @@ -143,6 +146,7 @@ asmlinkage long sys_mlock(unsigned long
29083 /* check against resource limits */
29084 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
29085 error = do_mlock(start, len, 1);
29087 up_write(¤t->mm->mmap_sem);
29090 @@ -202,6 +206,8 @@ asmlinkage long sys_mlockall(int flags)
29091 lock_limit >>= PAGE_SHIFT;
29094 + if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
29096 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
29097 capable(CAP_IPC_LOCK))
29098 ret = do_mlockall(flags);
29099 diff -NurpP --minimal linux-2.6.19.1/mm/mmap.c linux-2.6.19.1-vs2.3.0.6/mm/mmap.c
29100 --- linux-2.6.19.1/mm/mmap.c 2006-11-30 21:19:44 +0100
29101 +++ linux-2.6.19.1-vs2.3.0.6/mm/mmap.c 2006-11-20 21:12:32 +0100
29102 @@ -1141,10 +1141,10 @@ munmap_back:
29103 kmem_cache_free(vm_area_cachep, vma);
29106 - mm->total_vm += len >> PAGE_SHIFT;
29107 + vx_vmpages_add(mm, len >> PAGE_SHIFT);
29108 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
29109 if (vm_flags & VM_LOCKED) {
29110 - mm->locked_vm += len >> PAGE_SHIFT;
29111 + vx_vmlocked_add(mm, len >> PAGE_SHIFT);
29112 make_pages_present(addr, addr + len);
29114 if (flags & MAP_POPULATE) {
29115 @@ -1504,9 +1504,9 @@ static int acct_stack_growth(struct vm_a
29118 /* Ok, everything looks good - let it rip */
29119 - mm->total_vm += grow;
29120 + vx_vmpages_add(mm, grow);
29121 if (vma->vm_flags & VM_LOCKED)
29122 - mm->locked_vm += grow;
29123 + vx_vmlocked_add(mm, grow);
29124 vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
29127 @@ -1659,9 +1659,9 @@ static void remove_vma_list(struct mm_st
29129 long nrpages = vma_pages(vma);
29131 - mm->total_vm -= nrpages;
29132 + vx_vmpages_sub(mm, nrpages);
29133 if (vma->vm_flags & VM_LOCKED)
29134 - mm->locked_vm -= nrpages;
29135 + vx_vmlocked_sub(mm, nrpages);
29136 vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
29137 vma = remove_vma(vma);
29139 @@ -1900,6 +1900,8 @@ unsigned long do_brk(unsigned long addr,
29140 lock_limit >>= PAGE_SHIFT;
29141 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
29143 + if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
29148 @@ -1926,7 +1928,8 @@ unsigned long do_brk(unsigned long addr,
29149 if (mm->map_count > sysctl_max_map_count)
29152 - if (security_vm_enough_memory(len >> PAGE_SHIFT))
29153 + if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
29154 + !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
29157 /* Can we just expand an old private anonymous mapping? */
29158 @@ -1952,9 +1955,9 @@ unsigned long do_brk(unsigned long addr,
29159 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
29160 vma_link(mm, vma, prev, rb_link, rb_parent);
29162 - mm->total_vm += len >> PAGE_SHIFT;
29163 + vx_vmpages_add(mm, len >> PAGE_SHIFT);
29164 if (flags & VM_LOCKED) {
29165 - mm->locked_vm += len >> PAGE_SHIFT;
29166 + vx_vmlocked_add(mm, len >> PAGE_SHIFT);
29167 make_pages_present(addr, addr + len);
29170 @@ -1980,6 +1983,11 @@ void exit_mmap(struct mm_struct *mm)
29171 free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
29172 tlb_finish_mmu(tlb, 0, end);
29174 + set_mm_counter(mm, file_rss, 0);
29175 + set_mm_counter(mm, anon_rss, 0);
29176 + vx_vmpages_sub(mm, mm->total_vm);
29177 + vx_vmlocked_sub(mm, mm->locked_vm);
29180 * Walk the list again, actually closing and freeing it,
29181 * with preemption enabled, without holding any MM locks.
29182 @@ -2019,7 +2027,8 @@ int insert_vm_struct(struct mm_struct *
29183 if (__vma && __vma->vm_start < vma->vm_end)
29185 if ((vma->vm_flags & VM_ACCOUNT) &&
29186 - security_vm_enough_memory(vma_pages(vma)))
29187 + (security_vm_enough_memory(vma_pages(vma)) ||
29188 + !vx_vmpages_avail(mm, vma_pages(vma))))
29190 vma_link(mm, vma, prev, rb_link, rb_parent);
29192 @@ -2092,5 +2101,7 @@ int may_expand_vm(struct mm_struct *mm,
29194 if (cur + npages > lim)
29196 + if (!vx_vmpages_avail(mm, npages))
29200 diff -NurpP --minimal linux-2.6.19.1/mm/mremap.c linux-2.6.19.1-vs2.3.0.6/mm/mremap.c
29201 --- linux-2.6.19.1/mm/mremap.c 2006-11-30 21:19:44 +0100
29202 +++ linux-2.6.19.1-vs2.3.0.6/mm/mremap.c 2006-11-08 04:57:47 +0100
29204 #include <linux/highmem.h>
29205 #include <linux/security.h>
29206 #include <linux/syscalls.h>
29207 +#include <linux/vs_memory.h>
29209 #include <asm/uaccess.h>
29210 #include <asm/cacheflush.h>
29211 @@ -213,7 +214,7 @@ static unsigned long move_vma(struct vm_
29212 * If this were a serious issue, we'd add a flag to do_munmap().
29214 hiwater_vm = mm->hiwater_vm;
29215 - mm->total_vm += new_len >> PAGE_SHIFT;
29216 + vx_vmpages_add(mm, new_len >> PAGE_SHIFT);
29217 vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
29219 if (do_munmap(mm, old_addr, old_len) < 0) {
29220 @@ -231,7 +232,7 @@ static unsigned long move_vma(struct vm_
29223 if (vm_flags & VM_LOCKED) {
29224 - mm->locked_vm += new_len >> PAGE_SHIFT;
29225 + vx_vmlocked_add(mm, new_len >> PAGE_SHIFT);
29226 if (new_len > old_len)
29227 make_pages_present(new_addr + old_len,
29228 new_addr + new_len);
29229 @@ -338,6 +339,9 @@ unsigned long do_mremap(unsigned long ad
29231 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
29233 + if (!vx_vmlocked_avail(current->mm,
29234 + (new_len - old_len) >> PAGE_SHIFT))
29237 if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
29239 @@ -366,10 +370,10 @@ unsigned long do_mremap(unsigned long ad
29240 vma_adjust(vma, vma->vm_start,
29241 addr + new_len, vma->vm_pgoff, NULL);
29243 - mm->total_vm += pages;
29244 + vx_vmpages_add(mm, pages);
29245 vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
29246 if (vma->vm_flags & VM_LOCKED) {
29247 - mm->locked_vm += pages;
29248 + vx_vmlocked_add(mm, pages);
29249 make_pages_present(addr + old_len,
29252 diff -NurpP --minimal linux-2.6.19.1/mm/nommu.c linux-2.6.19.1-vs2.3.0.6/mm/nommu.c
29253 --- linux-2.6.19.1/mm/nommu.c 2006-11-30 21:19:44 +0100
29254 +++ linux-2.6.19.1-vs2.3.0.6/mm/nommu.c 2006-11-08 04:57:47 +0100
29255 @@ -921,7 +921,7 @@ unsigned long do_mmap_pgoff(struct file
29256 realalloc += kobjsize(vma);
29257 askedalloc += sizeof(*vma);
29259 - current->mm->total_vm += len >> PAGE_SHIFT;
29260 + vx_vmpages_add(current->mm, len >> PAGE_SHIFT);
29262 add_nommu_vma(vma);
29264 @@ -1046,7 +1046,7 @@ int do_munmap(struct mm_struct *mm, unsi
29267 update_hiwater_vm(mm);
29268 - mm->total_vm -= len >> PAGE_SHIFT;
29269 + vx_vmpages_sub(mm, len >> PAGE_SHIFT);
29272 show_process_blocks();
29273 @@ -1078,7 +1078,7 @@ void exit_mmap(struct mm_struct * mm)
29274 printk("Exit_mmap:\n");
29277 - mm->total_vm = 0;
29278 + vx_vmpages_sub(mm, mm->total_vm);
29280 while ((tmp = mm->context.vmlist)) {
29281 mm->context.vmlist = tmp->next;
29282 diff -NurpP --minimal linux-2.6.19.1/mm/oom_kill.c linux-2.6.19.1-vs2.3.0.6/mm/oom_kill.c
29283 --- linux-2.6.19.1/mm/oom_kill.c 2006-11-30 21:19:44 +0100
29284 +++ linux-2.6.19.1-vs2.3.0.6/mm/oom_kill.c 2006-11-30 19:33:42 +0100
29286 #include <linux/cpuset.h>
29287 #include <linux/module.h>
29288 #include <linux/notifier.h>
29289 +#include <linux/vs_memory.h>
29291 int sysctl_panic_on_oom;
29292 /* #define DEBUG */
29293 @@ -72,6 +73,12 @@ unsigned long badness(struct task_struct
29294 points = mm->total_vm;
29297 + * add points for context badness
29300 + points += vx_badness(p, mm);
29303 * After this unlock we can no longer dereference local variable `mm'
29306 @@ -154,8 +161,8 @@ unsigned long badness(struct task_struct
29310 - printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n",
29311 - p->pid, p->comm, points);
29312 + printk(KERN_DEBUG "OOMkill: task %d:#%u (%s) got %d points\n",
29313 + p->pid, p->xid, p->comm, points);
29317 @@ -279,8 +286,8 @@ static void __oom_kill_task(struct task_
29321 - printk(KERN_ERR "%s: Killed process %d (%s).\n",
29322 - message, p->pid, p->comm);
29323 + printk(KERN_ERR "%s: Killed process %d:#%u (%s).\n",
29324 + message, p->pid, p->xid, p->comm);
29328 @@ -341,8 +348,8 @@ static int oom_kill_process(struct task_
29332 - printk(KERN_ERR "Out of Memory: Kill process %d (%s) score %li"
29333 - " and children.\n", p->pid, p->comm, points);
29334 + printk(KERN_ERR "Out of Memory: Kill process %d:#%u (%s) score %li"
29335 + " and children.\n", p->pid, p->xid, p->comm, points);
29336 /* Try to kill a child first */
29337 list_for_each(tsk, &p->children) {
29338 c = list_entry(tsk, struct task_struct, sibling);
29339 diff -NurpP --minimal linux-2.6.19.1/mm/page_alloc.c linux-2.6.19.1-vs2.3.0.6/mm/page_alloc.c
29340 --- linux-2.6.19.1/mm/page_alloc.c 2006-11-30 21:19:44 +0100
29341 +++ linux-2.6.19.1-vs2.3.0.6/mm/page_alloc.c 2006-11-30 20:55:45 +0100
29343 #include <linux/sort.h>
29344 #include <linux/pfn.h>
29345 #include <linux/backing-dev.h>
29346 +#include <linux/vs_base.h>
29347 +#include <linux/vs_limit.h>
29349 #include <asm/tlbflush.h>
29350 #include <asm/div64.h>
29351 @@ -1274,6 +1276,9 @@ void si_meminfo(struct sysinfo *val)
29352 val->totalhigh = totalhigh_pages;
29353 val->freehigh = nr_free_highpages();
29354 val->mem_unit = PAGE_SIZE;
29356 + if (vx_flags(VXF_VIRT_MEM, 0))
29357 + vx_vsi_meminfo(val);
29360 EXPORT_SYMBOL(si_meminfo);
29361 @@ -1293,6 +1298,9 @@ void si_meminfo_node(struct sysinfo *val
29364 val->mem_unit = PAGE_SIZE;
29366 + if (vx_flags(VXF_VIRT_MEM, 0))
29367 + vx_vsi_meminfo(val);
29371 diff -NurpP --minimal linux-2.6.19.1/mm/rmap.c linux-2.6.19.1-vs2.3.0.6/mm/rmap.c
29372 --- linux-2.6.19.1/mm/rmap.c 2006-11-30 21:19:44 +0100
29373 +++ linux-2.6.19.1-vs2.3.0.6/mm/rmap.c 2006-11-08 04:57:40 +0100
29375 #include <linux/rmap.h>
29376 #include <linux/rcupdate.h>
29377 #include <linux/module.h>
29378 +#include <linux/vs_memory.h>
29380 #include <asm/tlbflush.h>
29382 diff -NurpP --minimal linux-2.6.19.1/mm/shmem.c linux-2.6.19.1-vs2.3.0.6/mm/shmem.c
29383 --- linux-2.6.19.1/mm/shmem.c 2006-11-30 21:19:44 +0100
29384 +++ linux-2.6.19.1-vs2.3.0.6/mm/shmem.c 2006-11-08 04:57:53 +0100
29386 #include <asm/pgtable.h>
29388 /* This magic number is used in glibc for posix shared memory */
29389 -#define TMPFS_MAGIC 0x01021994
29391 #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
29392 #define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
29393 @@ -1658,7 +1657,7 @@ static int shmem_statfs(struct dentry *d
29395 struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
29397 - buf->f_type = TMPFS_MAGIC;
29398 + buf->f_type = TMPFS_SUPER_MAGIC;
29399 buf->f_bsize = PAGE_CACHE_SIZE;
29400 buf->f_namelen = NAME_MAX;
29401 spin_lock(&sbinfo->stat_lock);
29402 @@ -2232,7 +2231,7 @@ static int shmem_fill_super(struct super
29403 sb->s_maxbytes = SHMEM_MAX_BYTES;
29404 sb->s_blocksize = PAGE_CACHE_SIZE;
29405 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
29406 - sb->s_magic = TMPFS_MAGIC;
29407 + sb->s_magic = TMPFS_SUPER_MAGIC;
29408 sb->s_op = &shmem_ops;
29409 sb->s_time_gran = 1;
29410 #ifdef CONFIG_TMPFS_POSIX_ACL
29411 diff -NurpP --minimal linux-2.6.19.1/mm/slab.c linux-2.6.19.1-vs2.3.0.6/mm/slab.c
29412 --- linux-2.6.19.1/mm/slab.c 2006-11-30 21:19:44 +0100
29413 +++ linux-2.6.19.1-vs2.3.0.6/mm/slab.c 2006-11-08 21:52:09 +0100
29414 @@ -499,6 +499,8 @@ struct kmem_cache {
29415 #define STATS_INC_FREEMISS(x) do { } while (0)
29418 +#include "slab_vs.h"
29423 @@ -3109,6 +3111,8 @@ static __always_inline void *__cache_all
29425 if (NUMA_BUILD && !objp)
29426 objp = __cache_alloc_node(cachep, flags, numa_node_id());
29428 + vx_slab_alloc(cachep, flags);
29429 local_irq_restore(save_flags);
29430 objp = cache_alloc_debugcheck_after(cachep, flags, objp,
29432 @@ -3202,6 +3206,7 @@ retry:
29434 obj = slab_get_obj(cachep, slabp, nodeid);
29435 check_slabp(cachep, slabp);
29436 + vx_slab_alloc(cachep, flags);
29437 l3->free_objects--;
29438 /* move slabp to correct slabp list: */
29439 list_del(&slabp->list);
29440 @@ -3339,6 +3344,7 @@ static inline void __cache_free(struct k
29443 objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
29444 + vx_slab_free(cachep);
29446 if (cache_free_alien(cachep, objp))
29448 diff -NurpP --minimal linux-2.6.19.1/mm/slab_vs.h linux-2.6.19.1-vs2.3.0.6/mm/slab_vs.h
29449 --- linux-2.6.19.1/mm/slab_vs.h 1970-01-01 01:00:00 +0100
29450 +++ linux-2.6.19.1-vs2.3.0.6/mm/slab_vs.h 2006-11-30 18:53:18 +0100
29453 +#include <linux/vserver/context.h>
29455 +#include <linux/vs_context.h>
29458 +void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
29460 + int what = gfp_zone(cachep->gfpflags);
29462 + if (!current->vx_info)
29465 + atomic_add(cachep->buffer_size, ¤t->vx_info->cacct.slab[what]);
29469 +void vx_slab_free(struct kmem_cache *cachep)
29471 + int what = gfp_zone(cachep->gfpflags);
29473 + if (!current->vx_info)
29476 + atomic_sub(cachep->buffer_size, ¤t->vx_info->cacct.slab[what]);
29479 diff -NurpP --minimal linux-2.6.19.1/mm/swapfile.c linux-2.6.19.1-vs2.3.0.6/mm/swapfile.c
29480 --- linux-2.6.19.1/mm/swapfile.c 2006-11-30 21:19:44 +0100
29481 +++ linux-2.6.19.1-vs2.3.0.6/mm/swapfile.c 2006-11-08 06:23:28 +0100
29483 #include <asm/pgtable.h>
29484 #include <asm/tlbflush.h>
29485 #include <linux/swapops.h>
29486 +#include <linux/vs_base.h>
29487 +#include <linux/vs_memory.h>
29489 DEFINE_SPINLOCK(swap_lock);
29490 unsigned int nr_swapfiles;
29491 @@ -1667,6 +1669,8 @@ void si_swapinfo(struct sysinfo *val)
29492 val->freeswap = nr_swap_pages + nr_to_be_unused;
29493 val->totalswap = total_swap_pages + nr_to_be_unused;
29494 spin_unlock(&swap_lock);
29495 + if (vx_flags(VXF_VIRT_MEM, 0))
29496 + vx_vsi_swapinfo(val);
29500 diff -NurpP --minimal linux-2.6.19.1/net/core/dev.c linux-2.6.19.1-vs2.3.0.6/net/core/dev.c
29501 --- linux-2.6.19.1/net/core/dev.c 2006-11-30 21:19:44 +0100
29502 +++ linux-2.6.19.1-vs2.3.0.6/net/core/dev.c 2006-12-17 03:23:33 +0100
29503 @@ -117,6 +117,7 @@
29504 #include <linux/dmaengine.h>
29505 #include <linux/err.h>
29506 #include <linux/ctype.h>
29507 +#include <linux/vs_inet.h>
29510 * The list of packet types we will receive (as opposed to discard)
29511 @@ -2051,6 +2052,8 @@ static int dev_ifconf(char __user *arg)
29514 for (dev = dev_base; dev; dev = dev->next) {
29515 + if (!nx_dev_visible(current->nx_info, dev))
29517 for (i = 0; i < NPROTO; i++) {
29518 if (gifconf_list[i]) {
29520 @@ -2111,6 +2114,8 @@ void dev_seq_stop(struct seq_file *seq,
29522 static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
29524 + if (!nx_dev_visible(current->nx_info, dev))
29526 if (dev->get_stats) {
29527 struct net_device_stats *stats = dev->get_stats(dev);
29529 diff -NurpP --minimal linux-2.6.19.1/net/core/rtnetlink.c linux-2.6.19.1-vs2.3.0.6/net/core/rtnetlink.c
29530 --- linux-2.6.19.1/net/core/rtnetlink.c 2006-11-30 21:19:44 +0100
29531 +++ linux-2.6.19.1-vs2.3.0.6/net/core/rtnetlink.c 2006-12-17 03:34:44 +0100
29532 @@ -359,6 +359,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
29533 for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
29536 + if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
29538 if (rtnl_fill_ifinfo(skb, dev, NULL, 0, RTM_NEWLINK,
29539 NETLINK_CB(cb->skb).pid,
29540 cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0)
29541 @@ -639,6 +641,9 @@ void rtmsg_ifinfo(int type, struct net_d
29542 struct sk_buff *skb;
29543 int err = -ENOBUFS;
29545 + if (!nx_dev_visible(current->nx_info, dev))
29548 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
29551 diff -NurpP --minimal linux-2.6.19.1/net/core/sock.c linux-2.6.19.1-vs2.3.0.6/net/core/sock.c
29552 --- linux-2.6.19.1/net/core/sock.c 2006-11-30 21:19:44 +0100
29553 +++ linux-2.6.19.1-vs2.3.0.6/net/core/sock.c 2006-11-08 21:52:09 +0100
29554 @@ -124,6 +124,9 @@
29555 #include <linux/ipsec.h>
29557 #include <linux/filter.h>
29558 +#include <linux/vs_socket.h>
29559 +#include <linux/vs_limit.h>
29560 +#include <linux/vs_context.h>
29563 #include <net/tcp.h>
29564 @@ -855,6 +858,8 @@ struct sock *sk_alloc(int family, gfp_t
29565 sk->sk_prot = sk->sk_prot_creator = prot;
29566 sock_lock_init(sk);
29568 + sock_vx_init(sk);
29569 + sock_nx_init(sk);
29571 if (security_sk_alloc(sk, family, priority))
29573 @@ -893,6 +898,11 @@ void sk_free(struct sock *sk)
29574 __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
29576 security_sk_free(sk);
29578 + clr_vx_info(&sk->sk_vx_info);
29580 + clr_nx_info(&sk->sk_nx_info);
29582 if (sk->sk_prot_creator->slab != NULL)
29583 kmem_cache_free(sk->sk_prot_creator->slab, sk);
29585 @@ -910,6 +920,8 @@ struct sock *sk_clone(const struct sock
29586 sock_copy(newsk, sk);
29589 + sock_vx_init(newsk);
29590 + sock_nx_init(newsk);
29591 sk_node_init(&newsk->sk_node);
29592 sock_lock_init(newsk);
29593 bh_lock_sock(newsk);
29594 @@ -955,6 +967,12 @@ struct sock *sk_clone(const struct sock
29595 newsk->sk_priority = 0;
29596 atomic_set(&newsk->sk_refcnt, 2);
29598 + set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
29599 + newsk->sk_xid = sk->sk_xid;
29600 + vx_sock_inc(newsk);
29601 + set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
29602 + newsk->sk_nid = sk->sk_nid;
29605 * Increment the counter in the same struct proto as the master
29606 * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
29607 @@ -1524,6 +1542,11 @@ void sock_init_data(struct socket *sock,
29608 sk->sk_stamp.tv_sec = -1L;
29609 sk->sk_stamp.tv_usec = -1L;
29611 + set_vx_info(&sk->sk_vx_info, current->vx_info);
29612 + sk->sk_xid = vx_current_xid();
29614 + set_nx_info(&sk->sk_nx_info, current->nx_info);
29615 + sk->sk_nid = nx_current_nid();
29616 atomic_set(&sk->sk_refcnt, 1);
29619 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/af_inet.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/af_inet.c
29620 --- linux-2.6.19.1/net/ipv4/af_inet.c 2006-11-30 21:19:45 +0100
29621 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/af_inet.c 2006-11-08 04:57:50 +0100
29622 @@ -114,6 +114,7 @@
29623 #ifdef CONFIG_IP_MROUTE
29624 #include <linux/mroute.h>
29626 +#include <linux/vs_limit.h>
29628 DEFINE_SNMP_STAT(struct linux_mib, net_statistics) __read_mostly;
29630 @@ -282,9 +283,11 @@ lookup_protocol:
29634 + if ((protocol == IPPROTO_ICMP) && vx_ccaps(VXC_RAW_ICMP))
29636 if (answer->capability > 0 && !capable(answer->capability))
29637 goto out_rcu_unlock;
29640 sock->ops = answer->ops;
29641 answer_prot = answer->prot;
29642 answer_no_check = answer->no_check;
29643 @@ -401,6 +404,10 @@ int inet_bind(struct socket *sock, struc
29644 unsigned short snum;
29647 + __u32 s_addr; /* Address used for validation */
29648 + __u32 s_addr1; /* Address used for socket */
29649 + __u32 s_addr2; /* Broadcast address for the socket */
29650 + struct nx_info *nxi = sk->sk_nx_info;
29652 /* If the socket has its own bind function then use it. (RAW) */
29653 if (sk->sk_prot->bind) {
29654 @@ -411,7 +418,40 @@ int inet_bind(struct socket *sock, struc
29655 if (addr_len < sizeof(struct sockaddr_in))
29658 - chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
29659 + s_addr = addr->sin_addr.s_addr;
29660 + s_addr1 = s_addr;
29661 + s_addr2 = 0xffffffffl;
29663 + vxdprintk(VXD_CBIT(net, 3),
29664 + "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d",
29665 + sk, sk->sk_nx_info, sk->sk_socket,
29666 + (sk->sk_socket?sk->sk_socket->flags:0),
29667 + VXD_QUAD(s_addr));
29669 + __u32 v4_bcast = nxi->v4_bcast;
29670 + __u32 ipv4root = nxi->ipv4[0];
29671 + int nbipv4 = nxi->nbipv4;
29673 + if (s_addr == 0) {
29674 + /* bind to any for 1-n */
29675 + s_addr = ipv4root;
29676 + s_addr1 = (nbipv4 > 1) ? 0 : s_addr;
29677 + s_addr2 = v4_bcast;
29678 + } else if (s_addr == IPI_LOOPBACK) {
29679 + /* rewrite localhost to ipv4root */
29680 + s_addr = ipv4root;
29681 + s_addr1 = ipv4root;
29682 + } else if (s_addr != v4_bcast) {
29683 + /* normal address bind */
29684 + if (!addr_in_nx_info(nxi, s_addr))
29685 + return -EADDRNOTAVAIL;
29688 + chk_addr_ret = inet_addr_type(s_addr);
29690 + vxdprintk(VXD_CBIT(net, 3),
29691 + "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d",
29692 + sk, VXD_QUAD(s_addr), VXD_QUAD(s_addr1), VXD_QUAD(s_addr2));
29694 /* Not specified by any standard per-se, however it breaks too
29695 * many applications when removed. It is unfortunate since
29696 @@ -423,7 +463,7 @@ int inet_bind(struct socket *sock, struc
29697 err = -EADDRNOTAVAIL;
29698 if (!sysctl_ip_nonlocal_bind &&
29700 - addr->sin_addr.s_addr != INADDR_ANY &&
29701 + s_addr != INADDR_ANY &&
29702 chk_addr_ret != RTN_LOCAL &&
29703 chk_addr_ret != RTN_MULTICAST &&
29704 chk_addr_ret != RTN_BROADCAST)
29705 @@ -448,7 +488,8 @@ int inet_bind(struct socket *sock, struc
29706 if (sk->sk_state != TCP_CLOSE || inet->num)
29707 goto out_release_sock;
29709 - inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr;
29710 + inet->rcv_saddr = inet->saddr = s_addr1;
29711 + inet->rcv_saddr2 = s_addr2;
29712 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
29713 inet->saddr = 0; /* Use device */
29715 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/devinet.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/devinet.c
29716 --- linux-2.6.19.1/net/ipv4/devinet.c 2006-11-30 21:19:45 +0100
29717 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/devinet.c 2006-12-17 03:23:33 +0100
29718 @@ -675,6 +675,8 @@ int devinet_ioctl(unsigned int cmd, void
29721 if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
29722 + struct nx_info *nxi = current->nx_info;
29724 if (tryaddrmatch) {
29725 /* Matthias Andree */
29726 /* compare label and address (4.4BSD style) */
29727 @@ -683,6 +685,8 @@ int devinet_ioctl(unsigned int cmd, void
29728 This is checked above. */
29729 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
29730 ifap = &ifa->ifa_next) {
29731 + if (!nx_ifa_visible(nxi, ifa))
29733 if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
29734 sin_orig.sin_addr.s_addr ==
29735 ifa->ifa_address) {
29736 @@ -695,9 +699,12 @@ int devinet_ioctl(unsigned int cmd, void
29737 comparing just the label */
29739 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
29740 - ifap = &ifa->ifa_next)
29741 + ifap = &ifa->ifa_next) {
29742 + if (!nx_ifa_visible(nxi, ifa))
29744 if (!strcmp(ifr.ifr_name, ifa->ifa_label))
29750 @@ -848,6 +855,8 @@ static int inet_gifconf(struct net_devic
29753 for (; ifa; ifa = ifa->ifa_next) {
29754 + if (!nx_ifa_visible(current->nx_info, ifa))
29757 done += sizeof(ifr);
29759 @@ -1164,6 +1173,7 @@ static int inet_dump_ifaddr(struct sk_bu
29760 struct net_device *dev;
29761 struct in_device *in_dev;
29762 struct in_ifaddr *ifa;
29763 + struct sock *sk = skb->sk;
29764 int s_ip_idx, s_idx = cb->args[0];
29766 s_ip_idx = ip_idx = cb->args[1];
29767 @@ -1181,6 +1191,8 @@ static int inet_dump_ifaddr(struct sk_bu
29769 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
29770 ifa = ifa->ifa_next, ip_idx++) {
29771 + if (sk && !nx_ifa_visible(sk->sk_nx_info, ifa))
29773 if (ip_idx < s_ip_idx)
29775 if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
29776 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/fib_hash.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/fib_hash.c
29777 --- linux-2.6.19.1/net/ipv4/fib_hash.c 2006-11-30 21:19:45 +0100
29778 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/fib_hash.c 2006-12-17 03:23:33 +0100
29779 @@ -1011,7 +1011,7 @@ static int fib_seq_show(struct seq_file
29780 prefix = f->fn_key;
29781 mask = FZ_MASK(iter->zone);
29782 flags = fib_flag_trans(fa->fa_type, mask, fi);
29784 + if (fi && nx_dev_visible(current->nx_info, fi->fib_dev))
29785 snprintf(bf, sizeof(bf),
29786 "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
29787 fi->fib_dev ? fi->fib_dev->name : "*", prefix,
29788 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/inet_connection_sock.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_connection_sock.c
29789 --- linux-2.6.19.1/net/ipv4/inet_connection_sock.c 2006-11-30 21:19:45 +0100
29790 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_connection_sock.c 2006-11-08 04:57:42 +0100
29791 @@ -39,7 +39,6 @@ int sysctl_local_port_range[2] = { 1024,
29792 int inet_csk_bind_conflict(const struct sock *sk,
29793 const struct inet_bind_bucket *tb)
29795 - const __be32 sk_rcv_saddr = inet_rcv_saddr(sk);
29797 struct hlist_node *node;
29798 int reuse = sk->sk_reuse;
29799 @@ -52,9 +51,8 @@ int inet_csk_bind_conflict(const struct
29800 sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
29801 if (!reuse || !sk2->sk_reuse ||
29802 sk2->sk_state == TCP_LISTEN) {
29803 - const __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
29804 - if (!sk2_rcv_saddr || !sk_rcv_saddr ||
29805 - sk2_rcv_saddr == sk_rcv_saddr)
29806 + if (nx_addr_conflict(sk->sk_nx_info,
29807 + inet_rcv_saddr(sk), sk2))
29811 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/inet_diag.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_diag.c
29812 --- linux-2.6.19.1/net/ipv4/inet_diag.c 2006-11-30 21:19:45 +0100
29813 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_diag.c 2006-12-04 05:06:57 +0100
29815 #include <linux/cache.h>
29816 #include <linux/init.h>
29817 #include <linux/time.h>
29818 +// #include <linux/vs_base.h>
29820 #include <net/icmp.h>
29821 #include <net/tcp.h>
29822 @@ -693,6 +694,8 @@ static int inet_diag_dump(struct sk_buff
29823 sk_for_each(sk, node, &hashinfo->listening_hash[i]) {
29824 struct inet_sock *inet = inet_sk(sk);
29826 + if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
29831 @@ -753,6 +756,8 @@ skip_listen_ht:
29832 sk_for_each(sk, node, &head->chain) {
29833 struct inet_sock *inet = inet_sk(sk);
29835 + if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
29839 if (!(r->idiag_states & (1 << sk->sk_state)))
29840 @@ -777,6 +782,8 @@ next_normal:
29841 inet_twsk_for_each(tw, node,
29842 &hashinfo->ehash[i + hashinfo->ehash_size].chain) {
29844 + if (!vx_check(tw->tw_xid, VS_WATCH_P|VS_IDENT))
29848 if (r->id.idiag_sport != tw->tw_sport &&
29849 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/inet_hashtables.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_hashtables.c
29850 --- linux-2.6.19.1/net/ipv4/inet_hashtables.c 2006-11-30 21:19:45 +0100
29851 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_hashtables.c 2006-11-08 04:57:42 +0100
29852 @@ -140,11 +140,10 @@ static struct sock *inet_lookup_listener
29853 const __be32 rcv_saddr = inet->rcv_saddr;
29854 int score = sk->sk_family == PF_INET ? 1 : 0;
29857 - if (rcv_saddr != daddr)
29859 + if (inet_addr_match(sk->sk_nx_info, daddr, rcv_saddr))
29864 if (sk->sk_bound_dev_if) {
29865 if (sk->sk_bound_dev_if != dif)
29867 @@ -175,7 +174,7 @@ struct sock *__inet_lookup_listener(stru
29868 const struct inet_sock *inet = inet_sk((sk = __sk_head(head)));
29870 if (inet->num == hnum && !sk->sk_node.next &&
29871 - (!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
29872 + inet_addr_match(sk->sk_nx_info, daddr, inet->rcv_saddr) &&
29873 (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
29874 !sk->sk_bound_dev_if)
29876 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/raw.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/raw.c
29877 --- linux-2.6.19.1/net/ipv4/raw.c 2006-11-30 21:19:45 +0100
29878 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/raw.c 2006-12-17 03:23:33 +0100
29880 #include <linux/seq_file.h>
29881 #include <linux/netfilter.h>
29882 #include <linux/netfilter_ipv4.h>
29883 +// #include <linux/vs_base.h>
29885 struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
29886 DEFINE_RWLOCK(raw_v4_lock);
29887 @@ -112,7 +113,8 @@ struct sock *__raw_v4_lookup(struct sock
29889 if (inet->num == num &&
29890 !(inet->daddr && inet->daddr != raddr) &&
29891 - !(inet->rcv_saddr && inet->rcv_saddr != laddr) &&
29892 + raw_addr_match(sk->sk_nx_info, laddr,
29893 + inet->rcv_saddr, inet->rcv_saddr2) &&
29894 !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
29895 goto found; /* gotcha */
29897 @@ -312,6 +314,11 @@ static int raw_send_hdrinc(struct sock *
29898 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
29902 + if (!vx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW)
29903 + && (!addr_in_nx_info(sk->sk_nx_info, iph->saddr)))
29906 err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
29909 @@ -323,6 +330,7 @@ out:
29916 IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
29917 @@ -489,6 +497,12 @@ static int raw_sendmsg(struct kiocb *ioc
29920 security_sk_classify_flow(sk, &fl);
29921 + if (sk->sk_nx_info) {
29922 + err = ip_find_src(sk->sk_nx_info, &rt, &fl);
29927 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
29930 @@ -793,7 +807,8 @@ static struct sock *raw_get_first(struct
29931 struct hlist_node *node;
29933 sk_for_each(sk, node, &raw_v4_htable[state->bucket])
29934 - if (sk->sk_family == PF_INET)
29935 + if (sk->sk_family == PF_INET &&
29936 + nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
29940 @@ -809,7 +824,8 @@ static struct sock *raw_get_next(struct
29944 - } while (sk && sk->sk_family != PF_INET);
29945 + } while (sk && (sk->sk_family != PF_INET ||
29946 + !nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)));
29948 if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) {
29949 sk = sk_head(&raw_v4_htable[state->bucket]);
29950 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/tcp.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp.c
29951 --- linux-2.6.19.1/net/ipv4/tcp.c 2006-11-30 21:19:45 +0100
29952 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp.c 2006-11-30 20:55:45 +0100
29953 @@ -258,6 +258,7 @@
29954 #include <linux/bootmem.h>
29955 #include <linux/cache.h>
29956 #include <linux/err.h>
29957 +#include <linux/in.h>
29959 #include <net/icmp.h>
29960 #include <net/tcp.h>
29961 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/tcp_ipv4.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp_ipv4.c
29962 --- linux-2.6.19.1/net/ipv4/tcp_ipv4.c 2006-11-30 21:19:45 +0100
29963 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp_ipv4.c 2006-12-04 04:51:13 +0100
29965 #include <linux/stddef.h>
29966 #include <linux/proc_fs.h>
29967 #include <linux/seq_file.h>
29968 +// #include <linux/vs_base.h>
29970 int sysctl_tcp_tw_reuse __read_mostly;
29971 int sysctl_tcp_low_latency __read_mostly;
29972 @@ -1389,6 +1390,12 @@ static void *listening_get_next(struct s
29973 req = req->dl_next;
29976 + vxdprintk(VXD_CBIT(net, 6),
29977 + "sk,req: %p [#%d] (from %d)", req->sk,
29978 + (req->sk)?req->sk->sk_nid:0, nx_current_nid());
29980 + !nx_check(req->sk->sk_nid, VS_WATCH_P|VS_IDENT))
29982 if (req->rsk_ops->family == st->family) {
29985 @@ -1413,6 +1420,10 @@ get_req:
29988 sk_for_each_from(sk, node) {
29989 + vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
29990 + sk, sk->sk_nid, nx_current_nid());
29991 + if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
29993 if (sk->sk_family == st->family) {
29996 @@ -1464,18 +1475,26 @@ static void *established_get_first(struc
29998 read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
29999 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
30000 - if (sk->sk_family != st->family) {
30001 + vxdprintk(VXD_CBIT(net, 6),
30002 + "sk,egf: %p [#%d] (from %d)",
30003 + sk, sk->sk_nid, nx_current_nid());
30004 + if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
30006 + if (sk->sk_family != st->family)
30012 st->state = TCP_SEQ_STATE_TIME_WAIT;
30013 inet_twsk_for_each(tw, node,
30014 &tcp_hashinfo.ehash[st->bucket + tcp_hashinfo.ehash_size].chain) {
30015 - if (tw->tw_family != st->family) {
30016 + vxdprintk(VXD_CBIT(net, 6),
30017 + "tw: %p [#%d] (from %d)",
30018 + tw, tw->tw_nid, nx_current_nid());
30019 + if (!nx_check(tw->tw_nid, VS_WATCH_P|VS_IDENT))
30021 + if (tw->tw_family != st->family)
30027 @@ -1499,7 +1518,8 @@ static void *established_get_next(struct
30031 - while (tw && tw->tw_family != st->family) {
30032 + while (tw && (tw->tw_family != st->family ||
30033 + !nx_check(tw->tw_nid, VS_WATCH_P|VS_IDENT))) {
30037 @@ -1523,6 +1543,11 @@ get_tw:
30040 sk_for_each_from(sk, node) {
30041 + vxdprintk(VXD_CBIT(net, 6),
30042 + "sk,egn: %p [#%d] (from %d)",
30043 + sk, sk->sk_nid, nx_current_nid());
30044 + if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
30046 if (sk->sk_family == st->family)
30049 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/tcp_minisocks.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp_minisocks.c
30050 --- linux-2.6.19.1/net/ipv4/tcp_minisocks.c 2006-11-30 21:19:45 +0100
30051 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp_minisocks.c 2006-11-08 04:57:42 +0100
30053 #include <net/inet_common.h>
30054 #include <net/xfrm.h>
30056 +#include <linux/vs_limit.h>
30057 +#include <linux/vs_socket.h>
30058 +#include <linux/vs_context.h>
30060 #ifdef CONFIG_SYSCTL
30061 #define SYNC_INIT 0 /* let the user enable it */
30063 @@ -294,6 +298,11 @@ void tcp_time_wait(struct sock *sk, int
30064 tcptw->tw_ts_recent = tp->rx_opt.ts_recent;
30065 tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp;
30067 + tw->tw_xid = sk->sk_xid;
30068 + tw->tw_vx_info = NULL;
30069 + tw->tw_nid = sk->sk_nid;
30070 + tw->tw_nx_info = NULL;
30072 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
30073 if (tw->tw_family == PF_INET6) {
30074 struct ipv6_pinfo *np = inet6_sk(sk);
30075 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/udp.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/udp.c
30076 --- linux-2.6.19.1/net/ipv4/udp.c 2006-11-30 21:19:45 +0100
30077 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/udp.c 2006-12-17 03:36:34 +0100
30078 @@ -108,6 +108,7 @@
30079 #include <net/inet_common.h>
30080 #include <net/checksum.h>
30081 #include <net/xfrm.h>
30082 +// #include <linux/vs_base.h>
30085 * Snmp MIB for the UDP layer
30086 @@ -195,6 +196,8 @@ gotit:
30087 (!sk2->sk_reuse || !sk->sk_reuse) &&
30088 (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
30089 || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
30090 + /* FIXME: nx_addr_conflict(sk->sk_nx_info,
30091 + inet_rcv_saddr(sk), sk2) && */
30092 (*saddr_cmp)(sk, sk2) )
30095 @@ -260,6 +263,11 @@ static struct sock *udp_v4_lookup_longwa
30096 if (inet->rcv_saddr != daddr)
30099 + } else if (sk->sk_nx_info) {
30100 + if (addr_in_nx_info(sk->sk_nx_info, daddr))
30106 if (inet->daddr != saddr)
30107 @@ -316,7 +324,8 @@ static inline struct sock *udp_v4_mcast_
30108 if (inet->num != hnum ||
30109 (inet->daddr && inet->daddr != rmt_addr) ||
30110 (inet->dport != rmt_port && inet->dport) ||
30111 - (inet->rcv_saddr && inet->rcv_saddr != loc_addr) ||
30112 + (inet->rcv_saddr && inet->rcv_saddr != loc_addr &&
30113 + inet->rcv_saddr2 && inet->rcv_saddr2 != loc_addr) ||
30114 ipv6_only_sock(s) ||
30115 (s->sk_bound_dev_if && s->sk_bound_dev_if != dif))
30117 @@ -626,7 +635,13 @@ int udp_sendmsg(struct kiocb *iocb, stru
30118 .uli_u = { .ports =
30119 { .sport = inet->sport,
30120 .dport = dport } } };
30121 + struct nx_info *nxi = sk->sk_nx_info;
30123 security_sk_classify_flow(sk, &fl);
30124 + err = ip_find_src(nxi, &rt, &fl);
30128 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
30131 @@ -1451,8 +1466,10 @@ static struct sock *udp_get_first(struct
30133 for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
30134 struct hlist_node *node;
30136 sk_for_each(sk, node, &udp_hash[state->bucket]) {
30137 - if (sk->sk_family == state->family)
30138 + if (sk->sk_family == state->family &&
30139 + nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
30143 @@ -1469,7 +1486,8 @@ static struct sock *udp_get_next(struct
30147 - } while (sk && sk->sk_family != state->family);
30148 + } while (sk && (sk->sk_family != state->family ||
30149 + !nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)));
30151 if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
30152 sk = sk_head(&udp_hash[state->bucket]);
30153 diff -NurpP --minimal linux-2.6.19.1/net/ipv6/addrconf.c linux-2.6.19.1-vs2.3.0.6/net/ipv6/addrconf.c
30154 --- linux-2.6.19.1/net/ipv6/addrconf.c 2006-11-30 21:19:45 +0100
30155 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv6/addrconf.c 2006-12-08 00:31:37 +0100
30156 @@ -2730,7 +2730,10 @@ static void if6_seq_stop(struct seq_file
30157 static int if6_seq_show(struct seq_file *seq, void *v)
30159 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
30162 + /* no ipv6 inside a vserver for now */
30163 + if (vx_check(0, VS_ADMIN|VS_WATCH))
30165 NIP6_SEQFMT " %02x %02x %02x %02x %8s\n",
30167 ifp->idev->dev->ifindex,
30168 @@ -3203,6 +3206,10 @@ static int inet6_dump_addr(struct sk_buf
30169 struct ifmcaddr6 *ifmca;
30170 struct ifacaddr6 *ifaca;
30172 + /* no ipv6 inside a vserver for now */
30173 + if (skb->sk && skb->sk->sk_vx_info)
30176 s_idx = cb->args[0];
30177 s_ip_idx = ip_idx = cb->args[1];
30178 read_lock(&dev_base_lock);
30179 @@ -3480,6 +3487,10 @@ static int inet6_dump_ifinfo(struct sk_b
30180 struct net_device *dev;
30181 struct inet6_dev *idev;
30183 + /* no ipv6 inside a vserver for now */
30184 + if (skb->sk && skb->sk->sk_vx_info)
30187 read_lock(&dev_base_lock);
30188 for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
30190 diff -NurpP --minimal linux-2.6.19.1/net/netlink/af_netlink.c linux-2.6.19.1-vs2.3.0.6/net/netlink/af_netlink.c
30191 --- linux-2.6.19.1/net/netlink/af_netlink.c 2006-11-30 21:19:46 +0100
30192 +++ linux-2.6.19.1-vs2.3.0.6/net/netlink/af_netlink.c 2006-11-08 21:52:09 +0100
30194 #include <linux/types.h>
30195 #include <linux/audit.h>
30196 #include <linux/selinux.h>
30197 +#include <linux/vs_context.h>
30198 +#include <linux/vs_network.h>
30199 +#include <linux/vs_limit.h>
30201 #include <net/sock.h>
30202 #include <net/scm.h>
30203 diff -NurpP --minimal linux-2.6.19.1/net/socket.c linux-2.6.19.1-vs2.3.0.6/net/socket.c
30204 --- linux-2.6.19.1/net/socket.c 2006-11-30 21:19:46 +0100
30205 +++ linux-2.6.19.1-vs2.3.0.6/net/socket.c 2006-12-04 05:08:37 +0100
30208 #include <net/sock.h>
30209 #include <linux/netfilter.h>
30210 +#include <linux/vs_base.h>
30211 +#include <linux/vs_socket.h>
30213 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
30214 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
30215 @@ -540,7 +542,7 @@ static inline int __sock_sendmsg(struct
30216 struct msghdr *msg, size_t size)
30218 struct sock_iocb *si = kiocb_to_siocb(iocb);
30224 @@ -551,7 +553,22 @@ static inline int __sock_sendmsg(struct
30228 - return sock->ops->sendmsg(iocb, sock, msg, size);
30229 + len = sock->ops->sendmsg(iocb, sock, msg, size);
30232 + vx_sock_send(sock->sk, size);
30234 + vx_sock_fail(sock->sk, size);
30236 + vxdprintk(VXD_CBIT(net, 7),
30237 + "__sock_sendmsg: %p[%p,%p,%p;%d/%d]:%d/%d",
30239 + (sock->sk)?sock->sk->sk_nx_info:0,
30240 + (sock->sk)?sock->sk->sk_vx_info:0,
30241 + (sock->sk)?sock->sk->sk_xid:0,
30242 + (sock->sk)?sock->sk->sk_nid:0,
30243 + (unsigned int)size, len);
30247 int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
30248 @@ -589,7 +606,7 @@ int kernel_sendmsg(struct socket *sock,
30249 static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
30250 struct msghdr *msg, size_t size, int flags)
30254 struct sock_iocb *si = kiocb_to_siocb(iocb);
30257 @@ -602,7 +619,18 @@ static inline int __sock_recvmsg(struct
30261 - return sock->ops->recvmsg(iocb, sock, msg, size, flags);
30262 + len = sock->ops->recvmsg(iocb, sock, msg, size, flags);
30263 + if ((len >= 0) && sock->sk)
30264 + vx_sock_recv(sock->sk, len);
30265 + vxdprintk(VXD_CBIT(net, 7),
30266 + "__sock_recvmsg: %p[%p,%p,%p;%d/%d]:%d/%d",
30268 + (sock->sk)?sock->sk->sk_nx_info:0,
30269 + (sock->sk)?sock->sk->sk_vx_info:0,
30270 + (sock->sk)?sock->sk->sk_xid:0,
30271 + (sock->sk)?sock->sk->sk_nid:0,
30272 + (unsigned int)size, len);
30276 int sock_recvmsg(struct socket *sock, struct msghdr *msg,
30277 @@ -1061,6 +1089,10 @@ static int __sock_create(int family, int
30278 if (type < 0 || type >= SOCK_MAX)
30281 + /* disable IPv6 inside vservers for now */
30282 + if (family == PF_INET6 && !vx_check(0, VS_ADMIN))
30283 + return -EAFNOSUPPORT;
30287 This uglymoron is moved from INET layer to here to avoid
30288 @@ -1178,6 +1210,7 @@ asmlinkage long sys_socket(int family, i
30292 + set_bit(SOCK_USER_SOCKET, &sock->flags);
30293 retval = sock_map_fd(sock);
30296 @@ -1209,10 +1242,12 @@ asmlinkage long sys_socketpair(int famil
30297 err = sock_create(family, type, protocol, &sock1);
30300 + set_bit(SOCK_USER_SOCKET, &sock1->flags);
30302 err = sock_create(family, type, protocol, &sock2);
30304 goto out_release_1;
30305 + set_bit(SOCK_USER_SOCKET, &sock2->flags);
30307 err = sock1->ops->socketpair(sock1, sock2);
30309 diff -NurpP --minimal linux-2.6.19.1/net/sunrpc/auth.c linux-2.6.19.1-vs2.3.0.6/net/sunrpc/auth.c
30310 --- linux-2.6.19.1/net/sunrpc/auth.c 2006-11-30 21:19:46 +0100
30311 +++ linux-2.6.19.1-vs2.3.0.6/net/sunrpc/auth.c 2006-11-08 04:57:47 +0100
30313 #include <linux/errno.h>
30314 #include <linux/sunrpc/clnt.h>
30315 #include <linux/spinlock.h>
30316 +#include <linux/vs_tag.h>
30319 # define RPCDBG_FACILITY RPCDBG_AUTH
30320 @@ -263,6 +264,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
30321 struct auth_cred acred = {
30322 .uid = current->fsuid,
30323 .gid = current->fsgid,
30324 + .tag = dx_current_tag(),
30325 .group_info = current->group_info,
30327 struct rpc_cred *ret;
30328 @@ -282,6 +284,7 @@ rpcauth_bindcred(struct rpc_task *task)
30329 struct auth_cred acred = {
30330 .uid = current->fsuid,
30331 .gid = current->fsgid,
30332 + .tag = dx_current_tag(),
30333 .group_info = current->group_info,
30335 struct rpc_cred *ret;
30336 diff -NurpP --minimal linux-2.6.19.1/net/sunrpc/auth_unix.c linux-2.6.19.1-vs2.3.0.6/net/sunrpc/auth_unix.c
30337 --- linux-2.6.19.1/net/sunrpc/auth_unix.c 2006-11-30 21:19:46 +0100
30338 +++ linux-2.6.19.1-vs2.3.0.6/net/sunrpc/auth_unix.c 2006-11-08 04:57:47 +0100
30339 @@ -11,12 +11,14 @@
30340 #include <linux/module.h>
30341 #include <linux/sunrpc/clnt.h>
30342 #include <linux/sunrpc/auth.h>
30343 +#include <linux/vs_tag.h>
30345 #define NFS_NGROUPS 16
30348 struct rpc_cred uc_base;
30351 gid_t uc_gids[NFS_NGROUPS];
30353 #define uc_uid uc_base.cr_uid
30354 @@ -78,6 +80,7 @@ unx_create_cred(struct rpc_auth *auth, s
30355 if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
30358 + cred->uc_tag = dx_current_tag();
30359 cred->uc_gids[0] = NOGROUP;
30361 int groups = acred->group_info->ngroups;
30362 @@ -86,6 +89,7 @@ unx_create_cred(struct rpc_auth *auth, s
30364 cred->uc_uid = acred->uid;
30365 cred->uc_gid = acred->gid;
30366 + cred->uc_tag = acred->tag;
30367 for (i = 0; i < groups; i++)
30368 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
30369 if (i < NFS_NGROUPS)
30370 @@ -117,7 +121,8 @@ unx_match(struct auth_cred *acred, struc
30373 if (cred->uc_uid != acred->uid
30374 - || cred->uc_gid != acred->gid)
30375 + || cred->uc_gid != acred->gid
30376 + || cred->uc_tag != acred->tag)
30379 groups = acred->group_info->ngroups;
30380 @@ -143,7 +148,7 @@ unx_marshal(struct rpc_task *task, __be3
30381 struct rpc_clnt *clnt = task->tk_client;
30382 struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
30383 __be32 *base, *hold;
30387 *p++ = htonl(RPC_AUTH_UNIX);
30389 @@ -153,9 +158,12 @@ unx_marshal(struct rpc_task *task, __be3
30390 * Copy the UTS nodename captured when the client was created.
30392 p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
30393 + tag = task->tk_client->cl_tag;
30395 - *p++ = htonl((u32) cred->uc_uid);
30396 - *p++ = htonl((u32) cred->uc_gid);
30397 + *p++ = htonl((u32) TAGINO_UID(tag,
30398 + cred->uc_uid, cred->uc_tag));
30399 + *p++ = htonl((u32) TAGINO_GID(tag,
30400 + cred->uc_gid, cred->uc_tag));
30402 for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
30403 *p++ = htonl((u32) cred->uc_gids[i]);
30404 diff -NurpP --minimal linux-2.6.19.1/net/sunrpc/clnt.c linux-2.6.19.1-vs2.3.0.6/net/sunrpc/clnt.c
30405 --- linux-2.6.19.1/net/sunrpc/clnt.c 2006-11-30 21:19:46 +0100
30406 +++ linux-2.6.19.1-vs2.3.0.6/net/sunrpc/clnt.c 2006-11-08 04:57:47 +0100
30408 #include <linux/slab.h>
30409 #include <linux/utsname.h>
30410 #include <linux/workqueue.h>
30411 +#include <linux/vs_cvirt.h>
30413 #include <linux/sunrpc/clnt.h>
30414 #include <linux/sunrpc/rpc_pipe_fs.h>
30415 @@ -238,7 +239,9 @@ struct rpc_clnt *rpc_create(struct rpc_c
30416 clnt->cl_autobind = 1;
30417 if (args->flags & RPC_CLNT_CREATE_ONESHOT)
30418 clnt->cl_oneshot = 1;
30420 + /* FIXME: handle RPC_CLNT_CREATE_TAGGED
30421 + if (args->flags & RPC_CLNT_CREATE_TAGGED)
30422 + clnt->cl_tag = 1; */
30425 EXPORT_SYMBOL_GPL(rpc_create);
30426 diff -NurpP --minimal linux-2.6.19.1/net/unix/af_unix.c linux-2.6.19.1-vs2.3.0.6/net/unix/af_unix.c
30427 --- linux-2.6.19.1/net/unix/af_unix.c 2006-11-30 21:19:46 +0100
30428 +++ linux-2.6.19.1-vs2.3.0.6/net/unix/af_unix.c 2006-12-04 05:08:47 +0100
30429 @@ -116,6 +116,8 @@
30430 #include <linux/mount.h>
30431 #include <net/checksum.h>
30432 #include <linux/security.h>
30433 +#include <linux/vs_context.h>
30434 +#include <linux/vs_limit.h>
30436 int sysctl_unix_max_dgram_qlen __read_mostly = 10;
30438 @@ -252,6 +254,8 @@ static struct sock *__unix_find_socket_b
30439 sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
30440 struct unix_sock *u = unix_sk(s);
30442 + if (!nx_check(s->sk_nid, VS_WATCH_P|VS_IDENT))
30444 if (u->addr->len == len &&
30445 !memcmp(u->addr->name, sunname, len))
30447 @@ -807,7 +811,7 @@ static int unix_bind(struct socket *sock
30450 (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
30451 - err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
30452 + err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
30454 goto out_mknod_dput;
30455 mutex_unlock(&nd.dentry->d_inode->i_mutex);
30456 diff -NurpP --minimal linux-2.6.19.1/net/x25/af_x25.c linux-2.6.19.1-vs2.3.0.6/net/x25/af_x25.c
30457 --- linux-2.6.19.1/net/x25/af_x25.c 2006-09-20 16:58:54 +0200
30458 +++ linux-2.6.19.1-vs2.3.0.6/net/x25/af_x25.c 2006-11-08 04:57:42 +0100
30459 @@ -501,7 +501,10 @@ static int x25_create(struct socket *soc
30463 - sock_init_data(sock, sk);
30464 + sk->sk_socket = sock;
30465 + sk->sk_type = sock->type;
30466 + sk->sk_sleep = &sock->wait;
30469 x25_init_timers(sk);
30471 Files linux-2.6.19.1/scripts/kconfig/mconf and linux-2.6.19.1-vs2.3.0.6/scripts/kconfig/mconf differ
30472 diff -NurpP --minimal linux-2.6.19.1/security/commoncap.c linux-2.6.19.1-vs2.3.0.6/security/commoncap.c
30473 --- linux-2.6.19.1/security/commoncap.c 2006-11-30 21:19:47 +0100
30474 +++ linux-2.6.19.1-vs2.3.0.6/security/commoncap.c 2006-11-30 19:54:52 +0100
30475 @@ -23,10 +23,11 @@
30476 #include <linux/ptrace.h>
30477 #include <linux/xattr.h>
30478 #include <linux/hugetlb.h>
30479 +#include <linux/vs_context.h>
30481 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
30483 - NETLINK_CB(skb).eff_cap = current->cap_effective;
30484 + cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
30488 @@ -44,7 +45,7 @@ EXPORT_SYMBOL(cap_netlink_recv);
30489 int cap_capable (struct task_struct *tsk, int cap)
30491 /* Derived from include/linux/sched.h:capable. */
30492 - if (cap_raised(tsk->cap_effective, cap))
30493 + if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
30497 @@ -142,7 +143,8 @@ void cap_bprm_apply_creds (struct linux_
30498 /* Derived from fs/exec.c:compute_creds. */
30499 kernel_cap_t new_permitted, working;
30501 - new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
30502 + new_permitted = cap_intersect (bprm->cap_permitted,
30503 + vx_current_cap_bset());
30504 working = cap_intersect (bprm->cap_inheritable,
30505 current->cap_inheritable);
30506 new_permitted = cap_combine (new_permitted, working);
30507 @@ -311,7 +313,8 @@ void cap_task_reparent_to_init (struct t
30509 int cap_syslog (int type)
30511 - if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
30512 + if ((type != 3 && type != 10) &&
30513 + !vx_capable(CAP_SYS_ADMIN, VXC_SYSLOG))
30517 diff -NurpP --minimal linux-2.6.19.1/security/dummy.c linux-2.6.19.1-vs2.3.0.6/security/dummy.c
30518 --- linux-2.6.19.1/security/dummy.c 2006-11-30 21:19:47 +0100
30519 +++ linux-2.6.19.1-vs2.3.0.6/security/dummy.c 2006-11-30 19:53:55 +0100
30521 #include <linux/hugetlb.h>
30522 #include <linux/ptrace.h>
30523 #include <linux/file.h>
30524 +#include <linux/vs_context.h>
30526 static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
30528 @@ -84,7 +85,7 @@ static int dummy_sysctl (ctl_table * tab
30532 -static int dummy_quotactl (int cmds, int type, int id, struct super_block *sb)
30533 +static int dummy_quotactl (int cmds, int type, int id, struct dqhash *hash)
30537 @@ -678,7 +679,7 @@ static int dummy_sem_semop (struct sem_a
30539 static int dummy_netlink_send (struct sock *sk, struct sk_buff *skb)
30541 - NETLINK_CB(skb).eff_cap = current->cap_effective;
30542 + cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
30546 diff -NurpP --minimal linux-2.6.19.1/security/selinux/hooks.c linux-2.6.19.1-vs2.3.0.6/security/selinux/hooks.c
30547 --- linux-2.6.19.1/security/selinux/hooks.c 2006-11-30 21:19:47 +0100
30548 +++ linux-2.6.19.1-vs2.3.0.6/security/selinux/hooks.c 2006-11-30 20:55:45 +0100
30549 @@ -1461,9 +1461,10 @@ static int selinux_sysctl(ctl_table *tab
30553 -static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
30554 +static int selinux_quotactl(int cmds, int type, int id, struct dqhash *hash)
30557 + struct super_block *sb = hash->dqh_sb;