]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.6-vs2.1.patch
- ppc configs updated, rel 0.7
[packages/kernel.git] / linux-2.6-vs2.1.patch
1 diff -NurpP --minimal linux-2.6.17.11/Documentation/vserver/debug.txt linux-2.6.17.11-vs2.1.1-rc31/Documentation/vserver/debug.txt
2 --- linux-2.6.17.11/Documentation/vserver/debug.txt     1970-01-01 01:00:00 +0100
3 +++ linux-2.6.17.11-vs2.1.1-rc31/Documentation/vserver/debug.txt        2006-07-09 17:06:47 +0200
4 @@ -0,0 +1,108 @@
5 +
6 +debug_cvirt:
7 +
8 + 2   4 "vx_map_tgid: %p/%llx: %d -> %d"
9 +       "vx_rmap_tgid: %p/%llx: %d -> %d"
10 +
11 +debug_dlim:
12 +
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 %d,%d [mult=%d]"
18 + 3   8 "ext3_has_free_blocks(%p): %u<%u+1, %c, %u!=%u r=%d"
19 +       "ext3_has_free_blocks(%p): free=%u, root=%u"
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"
29 +
30 +debug_net:
31 +
32 + 2   4 "nx_addr_conflict(%p,%p) %d.%d,%d.%d"
33 + 3   8 "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d"
34 +       "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d"
35 + 4  10 "ip_route_connect(%p) %p,%p;%lx"
36 + 5  20 "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx"
37 + 6  40 "sk,egf: %p [#%d] (from %d)"
38 +       "sk,egn: %p [#%d] (from %d)"
39 +       "sk,req: %p [#%d] (from %d)"
40 +       "sk: %p [#%d] (from %d)"
41 +       "tw: %p [#%d] (from %d)"
42 + 7  80 "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d"
43 +       "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d"
44 +
45 +debug_nid:
46 +
47 + 0   1 "__lookup_nx_info(#%u): %p[#%u]"
48 +       "alloc_nx_info(%d) = %p"
49 +       "create_nx_info(%d) (dynamic rejected)"
50 +       "create_nx_info(%d) = %p (already there)"
51 +       "create_nx_info(%d) = %p (new)"
52 +       "dealloc_nx_info(%p)"
53 + 1   2 "alloc_nx_info(%d)*"
54 +       "create_nx_info(%d)*"
55 + 2   4 "get_nx_info(%p[#%d.%d])"
56 +       "put_nx_info(%p[#%d.%d])"
57 + 3   8 "claim_nx_info(%p[#%d.%d.%d]) %p"
58 +       "clr_nx_info(%p[#%d.%d])"
59 +       "init_nx_info(%p[#%d.%d])"
60 +       "release_nx_info(%p[#%d.%d.%d]) %p"
61 +       "set_nx_info(%p[#%d.%d])"
62 + 4  10 "__hash_nx_info: %p[#%d]"
63 +       "__nx_dynamic_id: [#%d]"
64 +       "__unhash_nx_info: %p[#%d]"
65 + 5  20 "moved task %p into nxi:%p[#%d]"
66 +       "nx_migrate_task(%p,%p[#%d.%d.%d])"
67 +       "task_get_nx_info(%p)"
68 +
69 +debug_switch:
70 +
71 + 0   1 "vc: VCMD_%02d_%d[%d], %d,%p,%d"
72 + 1   2 "vc: VCMD_%02d_%d[%d] = %08lx(%ld)"
73 + 4  10 "%s: (%s %s) returned %s with %d"
74 +
75 +debug_xid:
76 +
77 + 0   1 "__lookup_vx_info(#%u): %p[#%u]"
78 +       "alloc_vx_info(%d) = %p"
79 +       "alloc_vx_info(%d)*"
80 +       "create_vx_info(%d) (dynamic rejected)"
81 +       "create_vx_info(%d) = %p (already there)"
82 +       "create_vx_info(%d) = %p (new)"
83 +       "dealloc_vx_info(%p)"
84 + 1   2 "create_vx_info(%d)*"
85 + 2   4 "get_vx_info(%p[#%d.%d])"
86 +       "put_vx_info(%p[#%d.%d])"
87 + 3   8 "claim_vx_info(%p[#%d.%d.%d]) %p"
88 +       "clr_vx_info(%p[#%d.%d])"
89 +       "init_vx_info(%p[#%d.%d])"
90 +       "release_vx_info(%p[#%d.%d.%d]) %p"
91 +       "set_vx_info(%p[#%d.%d])"
92 + 4  10 "__hash_vx_info: %p[#%d]"
93 +       "__unhash_vx_info: %p[#%d]"
94 +       "__vx_dynamic_id: [#%d]"
95 + 5  20 "moved task %p into vxi:%p[#%d]"
96 +       "task_get_vx_info(%p)"
97 +       "vx_migrate_task(%p,%p[#%d.%d])"
98 + 6  40 "vx_set_init(%p[#%d],%p[#%d,%d,%d])"
99 +       "vx_exit_init(%p[#%d],%p[#%d,%d,%d])"
100 +       "vx_set_reaper(%p[#%d],%p[#%d,%d])"
101 + 7  80 "vx_parse_xid(»%s«): %d:#%d"
102 +       "vx_propagate_xid(%p[#%lu.%d]): %d,%d"
103 +
104 +
105 +debug_limit:
106 +
107 + n 2^n "vx_acc_cres[%5d,%s,%2d]: %5d%s"
108 +       "vx_cres_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
109 +
110 + m 2^m "vx_acc_page[%5d,%s,%2d]: %5d%s"
111 +       "vx_acc_pages[%5d,%s,%2d]: %5d += %5d"
112 +       "vx_pages_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
113 diff -NurpP --minimal linux-2.6.17.11/arch/alpha/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/Kconfig
114 --- linux-2.6.17.11/arch/alpha/Kconfig  2006-06-18 04:51:38 +0200
115 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/Kconfig     2006-07-09 17:06:47 +0200
116 @@ -632,6 +632,8 @@ source "arch/alpha/oprofile/Kconfig"
117  
118  source "arch/alpha/Kconfig.debug"
119  
120 +source "kernel/vserver/Kconfig"
121 +
122  source "security/Kconfig"
123  
124  source "crypto/Kconfig"
125 diff -NurpP --minimal linux-2.6.17.11/arch/alpha/kernel/asm-offsets.c linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/asm-offsets.c
126 --- linux-2.6.17.11/arch/alpha/kernel/asm-offsets.c     2006-02-15 13:54:10 +0100
127 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/asm-offsets.c        2006-07-09 17:06:47 +0200
128 @@ -36,6 +36,7 @@ void foo(void)
129         DEFINE(PT_PTRACED, PT_PTRACED);
130         DEFINE(CLONE_VM, CLONE_VM);
131         DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
132 +       DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
133         DEFINE(SIGCHLD, SIGCHLD);
134         BLANK();
135  
136 diff -NurpP --minimal linux-2.6.17.11/arch/alpha/kernel/entry.S linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/entry.S
137 --- linux-2.6.17.11/arch/alpha/kernel/entry.S   2006-04-09 13:49:39 +0200
138 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/entry.S      2006-07-09 17:06:47 +0200
139 @@ -645,7 +645,7 @@ kernel_thread:
140         stq     $2, 152($sp)            /* HAE */
141  
142         /* Shuffle FLAGS to the front; add CLONE_VM.  */
143 -       ldi     $1, CLONE_VM|CLONE_UNTRACED
144 +       ldi     $1, CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
145         or      $18, $1, $16
146         bsr     $26, sys_clone
147  
148 @@ -874,24 +874,15 @@ sys_getxgid:
149         .globl  sys_getxpid
150         .ent    sys_getxpid
151  sys_getxpid:
152 +       lda     $sp, -16($sp)
153 +       stq     $26, 0($sp)
154         .prologue 0
155 -       ldq     $2, TI_TASK($8)
156  
157 -       /* See linux/kernel/timer.c sys_getppid for discussion
158 -          about this loop.  */
159 -       ldq     $3, TASK_GROUP_LEADER($2)
160 -       ldq     $4, TASK_REAL_PARENT($3)
161 -       ldl     $0, TASK_TGID($2)
162 -1:     ldl     $1, TASK_TGID($4)
163 -#ifdef CONFIG_SMP
164 -       mov     $4, $5
165 -       mb
166 -       ldq     $3, TASK_GROUP_LEADER($2)
167 -       ldq     $4, TASK_REAL_PARENT($3)
168 -       cmpeq   $4, $5, $5
169 -       beq     $5, 1b
170 -#endif
171 -       stq     $1, 80($sp)
172 +       lda     $16, 96($sp)
173 +       jsr     $26, do_getxpid
174 +       ldq     $26, 0($sp)
175 +
176 +       lda     $sp, 16($sp)
177         ret
178  .end sys_getxpid
179  
180 diff -NurpP --minimal linux-2.6.17.11/arch/alpha/kernel/osf_sys.c linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/osf_sys.c
181 --- linux-2.6.17.11/arch/alpha/kernel/osf_sys.c 2006-06-18 04:51:38 +0200
182 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/osf_sys.c    2006-07-09 17:06:47 +0200
183 @@ -38,6 +38,7 @@
184  #include <linux/uio.h>
185  #include <linux/vfs.h>
186  #include <linux/rcupdate.h>
187 +#include <linux/vs_cvirt.h>
188  
189  #include <asm/fpu.h>
190  #include <asm/io.h>
191 @@ -399,18 +400,20 @@ asmlinkage int
192  osf_utsname(char __user *name)
193  {
194         int error;
195 +       struct new_utsname *ptr;
196  
197         down_read(&uts_sem);
198 +       ptr = vx_new_utsname();
199         error = -EFAULT;
200 -       if (copy_to_user(name + 0, system_utsname.sysname, 32))
201 +       if (copy_to_user(name + 0, ptr->sysname, 32))
202                 goto out;
203 -       if (copy_to_user(name + 32, system_utsname.nodename, 32))
204 +       if (copy_to_user(name + 32, ptr->nodename, 32))
205                 goto out;
206 -       if (copy_to_user(name + 64, system_utsname.release, 32))
207 +       if (copy_to_user(name + 64, ptr->release, 32))
208                 goto out;
209 -       if (copy_to_user(name + 96, system_utsname.version, 32))
210 +       if (copy_to_user(name + 96, ptr->version, 32))
211                 goto out;
212 -       if (copy_to_user(name + 128, system_utsname.machine, 32))
213 +       if (copy_to_user(name + 128, ptr->machine, 32))
214                 goto out;
215  
216         error = 0;
217 @@ -439,6 +442,7 @@ osf_getdomainname(char __user *name, int
218  {
219         unsigned len;
220         int i;
221 +       char *domainname;
222  
223         if (!access_ok(VERIFY_WRITE, name, namelen))
224                 return -EFAULT;
225 @@ -448,9 +452,10 @@ osf_getdomainname(char __user *name, int
226                 len = 32;
227  
228         down_read(&uts_sem);
229 +       domainname = vx_new_uts(domainname);
230         for (i = 0; i < len; ++i) {
231 -               __put_user(system_utsname.domainname[i], name + i);
232 -               if (system_utsname.domainname[i] == '\0')
233 +               __put_user(domainname[i], name + i);
234 +               if (domainname[i] == '\0')
235                         break;
236         }
237         up_read(&uts_sem);
238 @@ -607,30 +612,30 @@ osf_sigstack(struct sigstack __user *uss
239  asmlinkage long
240  osf_sysinfo(int command, char __user *buf, long count)
241  {
242 -       static char * sysinfo_table[] = {
243 -               system_utsname.sysname,
244 -               system_utsname.nodename,
245 -               system_utsname.release,
246 -               system_utsname.version,
247 -               system_utsname.machine,
248 -               "alpha",        /* instruction set architecture */
249 -               "dummy",        /* hardware serial number */
250 -               "dummy",        /* hardware manufacturer */
251 -               "dummy",        /* secure RPC domain */
252 -       };
253         unsigned long offset;
254         char *res;
255         long len, err = -EINVAL;
256  
257         offset = command-1;
258 -       if (offset >= sizeof(sysinfo_table)/sizeof(char *)) {
259 +       if (offset >= 9) {
260                 /* Digital UNIX has a few unpublished interfaces here */
261                 printk("sysinfo(%d)", command);
262                 goto out;
263         }
264         
265         down_read(&uts_sem);
266 -       res = sysinfo_table[offset];
267 +       switch (offset)
268 +       {
269 +       case 0: res = vx_new_uts(sysname);  break;
270 +       case 1: res = vx_new_uts(nodename); break;
271 +       case 2: res = vx_new_uts(release);  break;
272 +       case 3: res = vx_new_uts(version);  break;
273 +       case 4: res = vx_new_uts(machine);  break;
274 +       case 5: res = "alpha";              break;
275 +       default:
276 +               res = "dummy";
277 +               break;
278 +       }
279         len = strlen(res)+1;
280         if (len > count)
281                 len = count;
282 @@ -881,7 +886,7 @@ osf_gettimeofday(struct timeval32 __user
283  {
284         if (tv) {
285                 struct timeval ktv;
286 -               do_gettimeofday(&ktv);
287 +               vx_gettimeofday(&ktv);
288                 if (put_tv32(tv, &ktv))
289                         return -EFAULT;
290         }
291 diff -NurpP --minimal linux-2.6.17.11/arch/alpha/kernel/ptrace.c linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/ptrace.c
292 --- linux-2.6.17.11/arch/alpha/kernel/ptrace.c  2006-04-09 13:49:39 +0200
293 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/ptrace.c     2006-08-06 06:00:35 +0200
294 @@ -15,6 +15,7 @@
295  #include <linux/slab.h>
296  #include <linux/security.h>
297  #include <linux/signal.h>
298 +#include <linux/vs_pid.h>
299  
300  #include <asm/uaccess.h>
301  #include <asm/pgtable.h>
302 @@ -283,6 +284,11 @@ do_sys_ptrace(long request, long pid, lo
303                 goto out_notsk;
304         }
305  
306 +       if (!vx_check(vx_task_xid(child), VX_WATCH_P|VX_IDENT)) {
307 +               ret = -EPERM;
308 +               goto out;
309 +       }
310 +
311         if (request == PTRACE_ATTACH) {
312                 ret = ptrace_attach(child);
313                 goto out;
314 diff -NurpP --minimal linux-2.6.17.11/arch/alpha/kernel/systbls.S linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/systbls.S
315 --- linux-2.6.17.11/arch/alpha/kernel/systbls.S 2005-08-29 22:24:49 +0200
316 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/systbls.S    2006-07-09 17:06:47 +0200
317 @@ -447,7 +447,7 @@ sys_call_table:
318         .quad sys_stat64                        /* 425 */
319         .quad sys_lstat64
320         .quad sys_fstat64
321 -       .quad sys_ni_syscall                    /* sys_vserver */
322 +       .quad sys_vserver                       /* sys_vserver */
323         .quad sys_ni_syscall                    /* sys_mbind */
324         .quad sys_ni_syscall                    /* sys_get_mempolicy */
325         .quad sys_ni_syscall                    /* sys_set_mempolicy */
326 diff -NurpP --minimal linux-2.6.17.11/arch/alpha/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/traps.c
327 --- linux-2.6.17.11/arch/alpha/kernel/traps.c   2005-10-28 20:49:08 +0200
328 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/kernel/traps.c      2006-07-09 17:06:47 +0200
329 @@ -183,7 +183,8 @@ die_if_kernel(char * str, struct pt_regs
330  #ifdef CONFIG_SMP
331         printk("CPU %d ", hard_smp_processor_id());
332  #endif
333 -       printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
334 +       printk("%s(%d[#%u]): %s %ld\n", current->comm,
335 +               current->pid, current->xid, str, err);
336         dik_show_regs(regs, r9_15);
337         dik_show_trace((unsigned long *)(regs+1));
338         dik_show_code((unsigned int *)regs->pc);
339 diff -NurpP --minimal linux-2.6.17.11/arch/alpha/mm/init.c linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/mm/init.c
340 --- linux-2.6.17.11/arch/alpha/mm/init.c        2006-06-18 04:51:38 +0200
341 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/alpha/mm/init.c   2006-07-09 17:06:47 +0200
342 @@ -21,6 +21,7 @@
343  #include <linux/init.h>
344  #include <linux/bootmem.h> /* max_low_pfn */
345  #include <linux/vmalloc.h>
346 +#include <linux/pagemap.h>
347  
348  #include <asm/system.h>
349  #include <asm/uaccess.h>
350 diff -NurpP --minimal linux-2.6.17.11/arch/arm/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/arm/Kconfig
351 --- linux-2.6.17.11/arch/arm/Kconfig    2006-06-18 04:51:38 +0200
352 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/arm/Kconfig       2006-07-09 17:06:47 +0200
353 @@ -873,6 +873,8 @@ source "arch/arm/oprofile/Kconfig"
354  
355  source "arch/arm/Kconfig.debug"
356  
357 +source "kernel/vserver/Kconfig"
358 +
359  source "security/Kconfig"
360  
361  source "crypto/Kconfig"
362 diff -NurpP --minimal linux-2.6.17.11/arch/arm/kernel/calls.S linux-2.6.17.11-vs2.1.1-rc31/arch/arm/kernel/calls.S
363 --- linux-2.6.17.11/arch/arm/kernel/calls.S     2006-02-18 14:39:40 +0100
364 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/arm/kernel/calls.S        2006-07-09 17:06:47 +0200
365 @@ -322,7 +322,7 @@
366  /* 310 */      CALL(sys_request_key)
367                 CALL(sys_keyctl)
368                 CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
369 -/* vserver */  CALL(sys_ni_syscall)
370 +               CALL(sys_vserver)
371                 CALL(sys_ioprio_set)
372  /* 315 */      CALL(sys_ioprio_get)
373                 CALL(sys_inotify_init)
374 diff -NurpP --minimal linux-2.6.17.11/arch/arm/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/arm/kernel/process.c
375 --- linux-2.6.17.11/arch/arm/kernel/process.c   2006-06-18 04:51:42 +0200
376 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/arm/kernel/process.c      2006-07-09 17:06:47 +0200
377 @@ -227,7 +227,8 @@ void __show_regs(struct pt_regs *regs)
378  void show_regs(struct pt_regs * regs)
379  {
380         printk("\n");
381 -       printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
382 +       printk("Pid: %d[#%u], comm: %20s\n",
383 +               current->pid, current->xid, current->comm);
384         __show_regs(regs);
385         __backtrace();
386  }
387 @@ -461,7 +462,8 @@ pid_t kernel_thread(int (*fn)(void *), v
388         regs.ARM_pc = (unsigned long)kernel_thread_helper;
389         regs.ARM_cpsr = SVC_MODE;
390  
391 -       return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
392 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
393 +               0, &regs, 0, NULL, NULL);
394  }
395  EXPORT_SYMBOL(kernel_thread);
396  
397 diff -NurpP --minimal linux-2.6.17.11/arch/arm26/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/arm26/Kconfig
398 --- linux-2.6.17.11/arch/arm26/Kconfig  2006-06-18 04:51:48 +0200
399 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/arm26/Kconfig     2006-07-09 17:06:47 +0200
400 @@ -234,6 +234,8 @@ source "drivers/usb/Kconfig"
401  
402  source "arch/arm26/Kconfig.debug"
403  
404 +source "kernel/vserver/Kconfig"
405 +
406  source "security/Kconfig"
407  
408  source "crypto/Kconfig"
409 diff -NurpP --minimal linux-2.6.17.11/arch/arm26/kernel/calls.S linux-2.6.17.11-vs2.1.1-rc31/arch/arm26/kernel/calls.S
410 --- linux-2.6.17.11/arch/arm26/kernel/calls.S   2005-03-02 12:38:19 +0100
411 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/arm26/kernel/calls.S      2006-07-09 17:06:47 +0200
412 @@ -257,6 +257,11 @@ __syscall_start:
413                 .long   sys_lremovexattr
414                 .long   sys_fremovexattr
415                 .long   sys_tkill
416 +
417 +               .rept   313 - (. - __syscall_start) / 4
418 +                       .long   sys_ni_syscall
419 +               .endr
420 +               .long   sys_vserver     /* 313 */
421  __syscall_end:
422  
423                 .rept   NR_syscalls - (__syscall_end - __syscall_start) / 4
424 diff -NurpP --minimal linux-2.6.17.11/arch/arm26/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/arm26/kernel/process.c
425 --- linux-2.6.17.11/arch/arm26/kernel/process.c 2006-01-18 06:07:51 +0100
426 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/arm26/kernel/process.c    2006-07-09 17:06:47 +0200
427 @@ -366,7 +366,8 @@ pid_t kernel_thread(int (*fn)(void *), v
428          regs.ARM_r3 = (unsigned long)do_exit;
429          regs.ARM_pc = (unsigned long)kernel_thread_helper | MODE_SVC26;
430  
431 -        return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
432 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
433 +               0, &regs, 0, NULL, NULL);
434  }
435  EXPORT_SYMBOL(kernel_thread);
436  
437 diff -NurpP --minimal linux-2.6.17.11/arch/arm26/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/arm26/kernel/traps.c
438 --- linux-2.6.17.11/arch/arm26/kernel/traps.c   2006-06-18 04:51:48 +0200
439 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/arm26/kernel/traps.c      2006-07-09 17:06:47 +0200
440 @@ -186,8 +186,9 @@ NORET_TYPE void die(const char *str, str
441         printk("Internal error: %s: %x\n", str, err);
442         printk("CPU: %d\n", smp_processor_id());
443         show_regs(regs);
444 -       printk("Process %s (pid: %d, stack limit = 0x%p)\n",
445 -               current->comm, current->pid, end_of_stack(tsk));
446 +       printk("Process %s (pid: %d[#%u], stack limit = 0x%p)\n",
447 +               current->comm, current->pid,
448 +               current->xid, end_of_stack(tsk));
449  
450         if (!user_mode(regs) || in_interrupt()) {
451                 __dump_stack(tsk, (unsigned long)(regs + 1));
452 diff -NurpP --minimal linux-2.6.17.11/arch/cris/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/cris/Kconfig
453 --- linux-2.6.17.11/arch/cris/Kconfig   2006-06-18 04:51:48 +0200
454 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/cris/Kconfig      2006-07-09 17:06:47 +0200
455 @@ -181,6 +181,8 @@ source "drivers/usb/Kconfig"
456  
457  source "arch/cris/Kconfig.debug"
458  
459 +source "kernel/vserver/Kconfig"
460 +
461  source "security/Kconfig"
462  
463  source "crypto/Kconfig"
464 diff -NurpP --minimal linux-2.6.17.11/arch/cris/arch-v10/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/cris/arch-v10/kernel/process.c
465 --- linux-2.6.17.11/arch/cris/arch-v10/kernel/process.c 2006-01-18 06:07:51 +0100
466 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/cris/arch-v10/kernel/process.c    2006-07-09 17:06:47 +0200
467 @@ -104,7 +104,8 @@ int kernel_thread(int (*fn)(void *), voi
468         regs.dccr = 1 << I_DCCR_BITNR;
469  
470         /* Ok, create the new process.. */
471 -        return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
472 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
473 +               0, &regs, 0, NULL, NULL);
474  }
475  
476  /* setup the child's kernel stack with a pt_regs and switch_stack on it.
477 diff -NurpP --minimal linux-2.6.17.11/arch/cris/arch-v32/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/cris/arch-v32/kernel/process.c
478 --- linux-2.6.17.11/arch/cris/arch-v32/kernel/process.c 2006-01-18 06:07:51 +0100
479 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/cris/arch-v32/kernel/process.c    2006-07-09 17:06:47 +0200
480 @@ -121,7 +121,8 @@ kernel_thread(int (*fn)(void *), void * 
481         regs.ccs = 1 << (I_CCS_BITNR + CCS_SHIFT);
482  
483         /* Create the new process. */
484 -        return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
485 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
486 +               0, &regs, 0, NULL, NULL);
487  }
488  
489  /*
490 diff -NurpP --minimal linux-2.6.17.11/arch/frv/kernel/kernel_thread.S linux-2.6.17.11-vs2.1.1-rc31/arch/frv/kernel/kernel_thread.S
491 --- linux-2.6.17.11/arch/frv/kernel/kernel_thread.S     2005-03-02 12:38:20 +0100
492 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/frv/kernel/kernel_thread.S        2006-07-09 17:06:47 +0200
493 @@ -13,6 +13,8 @@
494  #include <asm/unistd.h>
495  
496  #define CLONE_VM       0x00000100      /* set if VM shared between processes */
497 +#define CLONE_KTHREAD  0x10000000      /* kernel thread */
498 +#define CLONE_KT       (CLONE_VM | CLONE_KTHREAD)      /* kernel thread flags */
499  #define        KERN_ERR        "<3>"
500  
501         .section .rodata
502 @@ -37,7 +39,7 @@ kernel_thread:
503  
504         # start by forking the current process, but with shared VM
505         setlos.p        #__NR_clone,gr7         ; syscall number
506 -       ori             gr10,#CLONE_VM,gr8      ; first syscall arg     [clone_flags]
507 +       ori             gr10,#CLONE_KT,gr8      ; first syscall arg     [clone_flags]
508         sethi.p         #0xe4e4,gr9             ; second syscall arg    [newsp]
509         setlo           #0xe4e4,gr9
510         setlos.p        #0,gr10                 ; third syscall arg     [parent_tidptr]
511 diff -NurpP --minimal linux-2.6.17.11/arch/frv/mm/mmu-context.c linux-2.6.17.11-vs2.1.1-rc31/arch/frv/mm/mmu-context.c
512 --- linux-2.6.17.11/arch/frv/mm/mmu-context.c   2006-06-18 04:51:49 +0200
513 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/frv/mm/mmu-context.c      2006-07-09 17:06:47 +0200
514 @@ -11,6 +11,7 @@
515  
516  #include <linux/sched.h>
517  #include <linux/mm.h>
518 +#include <linux/vs_pid.h>
519  #include <asm/tlbflush.h>
520  
521  #define NR_CXN 4096
522 diff -NurpP --minimal linux-2.6.17.11/arch/h8300/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/h8300/Kconfig
523 --- linux-2.6.17.11/arch/h8300/Kconfig  2006-06-18 04:51:49 +0200
524 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/h8300/Kconfig     2006-07-09 17:06:47 +0200
525 @@ -199,6 +199,8 @@ source "fs/Kconfig"
526  
527  source "arch/h8300/Kconfig.debug"
528  
529 +source "kernel/vserver/Kconfig"
530 +
531  source "security/Kconfig"
532  
533  source "crypto/Kconfig"
534 diff -NurpP --minimal linux-2.6.17.11/arch/h8300/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/h8300/kernel/process.c
535 --- linux-2.6.17.11/arch/h8300/kernel/process.c 2006-06-18 04:51:49 +0200
536 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/h8300/kernel/process.c    2006-07-09 17:06:47 +0200
537 @@ -135,7 +135,7 @@ int kernel_thread(int (*fn)(void *), voi
538  
539         fs = get_fs();
540         set_fs (KERNEL_DS);
541 -       clone_arg = flags | CLONE_VM;
542 +       clone_arg = flags | CLONE_VM | CLONE_KTHREAD;
543         __asm__("mov.l sp,er3\n\t"
544                 "sub.l er2,er2\n\t"
545                 "mov.l %2,er1\n\t"
546 diff -NurpP --minimal linux-2.6.17.11/arch/i386/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/i386/Kconfig
547 --- linux-2.6.17.11/arch/i386/Kconfig   2006-08-25 00:25:37 +0200
548 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/i386/Kconfig      2006-07-26 21:36:47 +0200
549 @@ -1088,6 +1088,8 @@ endmenu
550  
551  source "arch/i386/Kconfig.debug"
552  
553 +source "kernel/vserver/Kconfig"
554 +
555  source "security/Kconfig"
556  
557  source "crypto/Kconfig"
558 diff -NurpP --minimal linux-2.6.17.11/arch/i386/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/i386/kernel/process.c
559 --- linux-2.6.17.11/arch/i386/kernel/process.c  2006-06-18 04:51:53 +0200
560 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/i386/kernel/process.c     2006-07-09 17:06:47 +0200
561 @@ -290,8 +290,10 @@ void show_regs(struct pt_regs * regs)
562         unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
563  
564         printk("\n");
565 -       printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
566 -       printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
567 +       printk("Pid: %d[#%u], comm: %20s\n",
568 +               current->pid, current->xid, current->comm);
569 +       printk("EIP: %04x:[<%08lx>] CPU: %d\n",
570 +               0xffff & regs->xcs,regs->eip, smp_processor_id());
571         print_symbol("EIP is at %s\n", regs->eip);
572  
573         if (user_mode_vm(regs))
574 @@ -351,7 +353,8 @@ int kernel_thread(int (*fn)(void *), voi
575         regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
576  
577         /* Ok, create the new process.. */
578 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
579 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
580 +               0, &regs, 0, NULL, NULL);
581  }
582  EXPORT_SYMBOL(kernel_thread);
583  
584 diff -NurpP --minimal linux-2.6.17.11/arch/i386/kernel/sys_i386.c linux-2.6.17.11-vs2.1.1-rc31/arch/i386/kernel/sys_i386.c
585 --- linux-2.6.17.11/arch/i386/kernel/sys_i386.c 2006-06-18 04:51:53 +0200
586 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/i386/kernel/sys_i386.c    2006-07-09 17:06:47 +0200
587 @@ -19,6 +19,7 @@
588  #include <linux/mman.h>
589  #include <linux/file.h>
590  #include <linux/utsname.h>
591 +#include <linux/vs_cvirt.h>
592  
593  #include <asm/uaccess.h>
594  #include <asm/ipc.h>
595 @@ -210,7 +211,7 @@ asmlinkage int sys_uname(struct old_utsn
596         if (!name)
597                 return -EFAULT;
598         down_read(&uts_sem);
599 -       err=copy_to_user(name, &system_utsname, sizeof (*name));
600 +       err=copy_to_user(name, vx_new_utsname(), sizeof (*name));
601         up_read(&uts_sem);
602         return err?-EFAULT:0;
603  }
604 @@ -218,6 +219,7 @@ asmlinkage int sys_uname(struct old_utsn
605  asmlinkage int sys_olduname(struct oldold_utsname __user * name)
606  {
607         int error;
608 +       struct new_utsname *ptr;
609  
610         if (!name)
611                 return -EFAULT;
612 @@ -226,15 +228,16 @@ asmlinkage int sys_olduname(struct oldol
613    
614         down_read(&uts_sem);
615         
616 -       error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
617 +       ptr = vx_new_utsname();
618 +       error = __copy_to_user(&name->sysname,ptr->sysname,__OLD_UTS_LEN);
619         error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
620 -       error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
621 +       error |= __copy_to_user(&name->nodename,ptr->nodename,__OLD_UTS_LEN);
622         error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
623 -       error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
624 +       error |= __copy_to_user(&name->release,ptr->release,__OLD_UTS_LEN);
625         error |= __put_user(0,name->release+__OLD_UTS_LEN);
626 -       error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
627 +       error |= __copy_to_user(&name->version,ptr->version,__OLD_UTS_LEN);
628         error |= __put_user(0,name->version+__OLD_UTS_LEN);
629 -       error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
630 +       error |= __copy_to_user(&name->machine,ptr->machine,__OLD_UTS_LEN);
631         error |= __put_user(0,name->machine+__OLD_UTS_LEN);
632         
633         up_read(&uts_sem);
634 diff -NurpP --minimal linux-2.6.17.11/arch/i386/kernel/syscall_table.S linux-2.6.17.11-vs2.1.1-rc31/arch/i386/kernel/syscall_table.S
635 --- linux-2.6.17.11/arch/i386/kernel/syscall_table.S    2006-06-18 04:51:53 +0200
636 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/i386/kernel/syscall_table.S       2006-07-09 17:06:47 +0200
637 @@ -272,7 +272,7 @@ ENTRY(sys_call_table)
638         .long sys_tgkill        /* 270 */
639         .long sys_utimes
640         .long sys_fadvise64_64
641 -       .long sys_ni_syscall    /* sys_vserver */
642 +       .long sys_vserver
643         .long sys_mbind
644         .long sys_get_mempolicy
645         .long sys_set_mempolicy
646 diff -NurpP --minimal linux-2.6.17.11/arch/i386/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/i386/kernel/traps.c
647 --- linux-2.6.17.11/arch/i386/kernel/traps.c    2006-06-18 04:51:53 +0200
648 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/i386/kernel/traps.c       2006-08-17 01:24:55 +0200
649 @@ -53,6 +53,8 @@
650  #include <asm/kdebug.h>
651  
652  #include <linux/module.h>
653 +#include <linux/vserver/debug.h>
654 +#include <linux/vserver/history.h>
655  
656  #include "mach_traps.h"
657  
658 @@ -268,8 +270,9 @@ void show_registers(struct pt_regs *regs
659                 regs->esi, regs->edi, regs->ebp, esp);
660         printk(KERN_EMERG "ds: %04x   es: %04x   ss: %04x\n",
661                 regs->xds & 0xffff, regs->xes & 0xffff, ss);
662 -       printk(KERN_EMERG "Process %s (pid: %d, threadinfo=%p task=%p)",
663 -               current->comm, current->pid, current_thread_info(), current);
664 +       printk(KERN_EMERG "Process %s (pid: %d[#%u], threadinfo=%p task=%p)",
665 +               current->comm, current->pid, current->xid,
666 +               current_thread_info(), current);
667         /*
668          * When in-kernel, we also print out the stack and code at the
669          * time of the fault..
670 @@ -351,6 +354,8 @@ void die(const char * str, struct pt_reg
671  
672         oops_enter();
673  
674 +       vxh_throw_oops();
675 +
676         if (die.lock_owner != raw_smp_processor_id()) {
677                 console_verbose();
678                 spin_lock_irqsave(&die.lock, flags);
679 @@ -387,9 +392,9 @@ void die(const char * str, struct pt_reg
680                 if (nl)
681                         printk("\n");
682                 if (notify_die(DIE_OOPS, str, regs, err,
683 -                                       current->thread.trap_no, SIGSEGV) !=
684 -                               NOTIFY_STOP) {
685 +                       current->thread.trap_no, SIGSEGV) != NOTIFY_STOP) {
686                         show_registers(regs);
687 +                       vxh_dump_history();
688                         /* Executive summary in case the oops scrolled away */
689                         esp = (unsigned long) (&regs->esp);
690                         savesegment(ss, ss);
691 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/Kconfig
692 --- linux-2.6.17.11/arch/ia64/Kconfig   2006-08-25 00:25:37 +0200
693 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/Kconfig      2006-07-26 21:36:47 +0200
694 @@ -506,6 +506,8 @@ endmenu
695  
696  source "arch/ia64/Kconfig.debug"
697  
698 +source "kernel/vserver/Kconfig"
699 +
700  source "security/Kconfig"
701  
702  source "crypto/Kconfig"
703 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/ia32/binfmt_elf32.c linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/ia32/binfmt_elf32.c
704 --- linux-2.6.17.11/arch/ia64/ia32/binfmt_elf32.c       2006-06-18 04:51:55 +0200
705 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/ia32/binfmt_elf32.c  2006-07-09 17:06:47 +0200
706 @@ -239,7 +239,8 @@ ia32_setup_arg_pages (struct linux_binpr
707                         kmem_cache_free(vm_area_cachep, mpnt);
708                         return ret;
709                 }
710 -               current->mm->stack_vm = current->mm->total_vm = vma_pages(mpnt);
711 +               vx_vmpages_sub(current->mm, current->mm->total_vm - vma_pages(mpnt));
712 +               current->mm->stack_vm = current->mm->total_vm;
713         }
714  
715         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
716 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/ia32/ia32_entry.S linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/ia32/ia32_entry.S
717 --- linux-2.6.17.11/arch/ia64/ia32/ia32_entry.S 2006-06-18 04:51:55 +0200
718 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/ia32/ia32_entry.S    2006-07-09 17:06:47 +0200
719 @@ -483,7 +483,7 @@ ia32_syscall_table:
720         data8 sys_tgkill        /* 270 */
721         data8 compat_sys_utimes
722         data8 sys32_fadvise64_64
723 -       data8 sys_ni_syscall
724 +       data8 sys32_vserver
725         data8 sys_ni_syscall
726         data8 sys_ni_syscall    /* 275 */
727         data8 sys_ni_syscall
728 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/ia32/sys_ia32.c linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/ia32/sys_ia32.c
729 --- linux-2.6.17.11/arch/ia64/ia32/sys_ia32.c   2006-06-18 04:51:55 +0200
730 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/ia32/sys_ia32.c      2006-07-09 17:06:47 +0200
731 @@ -51,6 +51,7 @@
732  #include <linux/compat.h>
733  #include <linux/vfs.h>
734  #include <linux/mman.h>
735 +#include <linux/vs_pid.h>
736  #include <linux/mutex.h>
737  
738  #include <asm/intrinsics.h>
739 @@ -1178,7 +1179,7 @@ sys32_gettimeofday (struct compat_timeva
740  {
741         if (tv) {
742                 struct timeval ktv;
743 -               do_gettimeofday(&ktv);
744 +               vx_gettimeofday(&ktv);
745                 if (put_tv32(tv, &ktv))
746                         return -EFAULT;
747         }
748 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/kernel/asm-offsets.c linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/asm-offsets.c
749 --- linux-2.6.17.11/arch/ia64/kernel/asm-offsets.c      2005-10-28 20:49:10 +0200
750 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/asm-offsets.c 2006-07-09 17:06:47 +0200
751 @@ -192,6 +192,7 @@ void foo(void)
752      /* for assembly files which can't include sched.h: */
753         DEFINE(IA64_CLONE_VFORK, CLONE_VFORK);
754         DEFINE(IA64_CLONE_VM, CLONE_VM);
755 +       DEFINE(IA64_CLONE_KTHREAD, CLONE_KTHREAD);
756  
757         BLANK();
758         DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET,
759 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/kernel/entry.S linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/entry.S
760 --- linux-2.6.17.11/arch/ia64/kernel/entry.S    2006-06-18 04:51:55 +0200
761 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/entry.S       2006-07-09 17:06:47 +0200
762 @@ -1577,7 +1577,7 @@ sys_call_table:
763         data8 sys_mq_notify
764         data8 sys_mq_getsetattr
765         data8 sys_ni_syscall                    // reserved for kexec_load
766 -       data8 sys_ni_syscall                    // reserved for vserver
767 +       data8 sys_vserver
768         data8 sys_waitid                        // 1270
769         data8 sys_add_key
770         data8 sys_request_key
771 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/kernel/perfmon.c linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/perfmon.c
772 --- linux-2.6.17.11/arch/ia64/kernel/perfmon.c  2006-06-18 04:51:56 +0200
773 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/perfmon.c     2006-07-09 17:06:47 +0200
774 @@ -41,6 +41,8 @@
775  #include <linux/capability.h>
776  #include <linux/rcupdate.h>
777  #include <linux/completion.h>
778 +#include <linux/vs_memory.h>
779 +#include <linux/vs_pid.h>
780  
781  #include <asm/errno.h>
782  #include <asm/intrinsics.h>
783 @@ -2355,7 +2357,7 @@ pfm_smpl_buffer_alloc(struct task_struct
784          */
785         insert_vm_struct(mm, vma);
786  
787 -       mm->total_vm  += size >> PAGE_SHIFT;
788 +       vx_vmpages_add(mm, size >> PAGE_SHIFT);
789         vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
790                                                         vma_pages(vma));
791         up_write(&task->mm->mmap_sem);
792 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/process.c
793 --- linux-2.6.17.11/arch/ia64/kernel/process.c  2006-06-18 04:51:56 +0200
794 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/process.c     2006-07-09 17:06:47 +0200
795 @@ -108,7 +108,8 @@ show_regs (struct pt_regs *regs)
796         unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
797  
798         print_modules();
799 -       printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
800 +       printk("\nPid: %d[#%u], CPU %d, comm: %20s\n",
801 +               current->pid, current->xid, smp_processor_id(), current->comm);
802         printk("psr : %016lx ifs : %016lx ip  : [<%016lx>]    %s\n",
803                regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
804         print_symbol("ip is at %s\n", ip);
805 @@ -691,7 +692,8 @@ kernel_thread (int (*fn)(void *), void *
806         regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR);
807         regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET;
808         regs.sw.pr = (1 << PRED_KERNEL_STACK);
809 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs.pt, 0, NULL, NULL);
810 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
811 +               0, &regs.pt, 0, NULL, NULL);
812  }
813  EXPORT_SYMBOL(kernel_thread);
814  
815 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/kernel/ptrace.c linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/ptrace.c
816 --- linux-2.6.17.11/arch/ia64/kernel/ptrace.c   2006-06-18 04:51:56 +0200
817 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/ptrace.c      2006-08-06 06:00:44 +0200
818 @@ -18,6 +18,7 @@
819  #include <linux/security.h>
820  #include <linux/audit.h>
821  #include <linux/signal.h>
822 +#include <linux/vs_pid.h>
823  
824  #include <asm/pgtable.h>
825  #include <asm/processor.h>
826 @@ -1443,6 +1444,9 @@ sys_ptrace (long request, pid_t pid, uns
827         read_unlock(&tasklist_lock);
828         if (!child)
829                 goto out;
830 +       if (!vx_check(vx_task_xid(child), VX_WATCH_P|VX_IDENT))
831 +               goto out_tsk;
832 +
833         ret = -EPERM;
834         if (pid == 1)           /* no messing around with init! */
835                 goto out_tsk;
836 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/kernel/signal.c linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/signal.c
837 --- linux-2.6.17.11/arch/ia64/kernel/signal.c   2006-06-18 04:51:56 +0200
838 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/signal.c      2006-07-09 17:06:47 +0200
839 @@ -21,6 +21,7 @@
840  #include <linux/binfmts.h>
841  #include <linux/unistd.h>
842  #include <linux/wait.h>
843 +#include <linux/vs_pid.h>
844  
845  #include <asm/ia32.h>
846  #include <asm/intrinsics.h>
847 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/traps.c
848 --- linux-2.6.17.11/arch/ia64/kernel/traps.c    2006-06-18 04:51:56 +0200
849 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/kernel/traps.c       2006-07-09 17:06:47 +0200
850 @@ -107,8 +107,9 @@ die (const char *str, struct pt_regs *re
851         put_cpu();
852  
853         if (++die.lock_owner_depth < 3) {
854 -               printk("%s[%d]: %s %ld [%d]\n",
855 -                       current->comm, current->pid, str, err, ++die_counter);
856 +               printk("%s[%d[#%u]]: %s %ld [%d]\n",
857 +                       current->comm, current->pid, current->xid,
858 +                       str, err, ++die_counter);
859                 (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
860                 show_regs(regs);
861         } else
862 @@ -335,8 +336,9 @@ handle_fpu_swa (int fp_fault, struct pt_
863                 last_time = jiffies;
864                 ++fpu_swa_count;
865                 printk(KERN_WARNING
866 -                      "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
867 -                      current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
868 +                      "%s(%d[#%u]): floating-point assist fault at ip %016lx, isr %016lx\n",
869 +                      current->comm, current->pid, current->xid,
870 +                      regs->cr_iip + ia64_psr(regs)->ri, isr);
871         }
872  
873         exception = fp_emulate(fp_fault, bundle, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr,
874 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/mm/fault.c linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/mm/fault.c
875 --- linux-2.6.17.11/arch/ia64/mm/fault.c        2006-06-18 04:51:56 +0200
876 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/mm/fault.c   2006-07-09 17:06:47 +0200
877 @@ -10,6 +10,7 @@
878  #include <linux/smp_lock.h>
879  #include <linux/interrupt.h>
880  #include <linux/kprobes.h>
881 +#include <linux/vs_memory.h>
882  
883  #include <asm/pgtable.h>
884  #include <asm/processor.h>
885 diff -NurpP --minimal linux-2.6.17.11/arch/ia64/sn/kernel/xpc_main.c linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/sn/kernel/xpc_main.c
886 --- linux-2.6.17.11/arch/ia64/sn/kernel/xpc_main.c      2006-06-18 04:51:57 +0200
887 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ia64/sn/kernel/xpc_main.c 2006-07-09 17:06:47 +0200
888 @@ -108,6 +108,7 @@ static ctl_table xpc_sys_xpc_hb_dir[] = 
889                 0644,
890                 NULL,
891                 &proc_dointvec_minmax,
892 +               NULL,
893                 &sysctl_intvec,
894                 NULL,
895                 &xpc_hb_min_interval,
896 @@ -121,6 +122,7 @@ static ctl_table xpc_sys_xpc_hb_dir[] = 
897                 0644,
898                 NULL,
899                 &proc_dointvec_minmax,
900 +               NULL,
901                 &sysctl_intvec,
902                 NULL,
903                 &xpc_hb_check_min_interval,
904 @@ -145,6 +147,7 @@ static ctl_table xpc_sys_xpc_dir[] = {
905                 0644,
906                 NULL,
907                 &proc_dointvec_minmax,
908 +               NULL,
909                 &sysctl_intvec,
910                 NULL,
911                 &xpc_disengage_request_min_timelimit,
912 diff -NurpP --minimal linux-2.6.17.11/arch/m32r/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/m32r/kernel/process.c
913 --- linux-2.6.17.11/arch/m32r/kernel/process.c  2006-06-18 04:51:57 +0200
914 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/m32r/kernel/process.c     2006-07-09 17:06:47 +0200
915 @@ -212,8 +212,8 @@ int kernel_thread(int (*fn)(void *), voi
916         regs.psw = M32R_PSW_BIE;
917  
918         /* Ok, create the new process. */
919 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL,
920 -               NULL);
921 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
922 +               0, &regs, 0, NULL, NULL);
923  }
924  
925  /*
926 diff -NurpP --minimal linux-2.6.17.11/arch/m32r/kernel/sys_m32r.c linux-2.6.17.11-vs2.1.1-rc31/arch/m32r/kernel/sys_m32r.c
927 --- linux-2.6.17.11/arch/m32r/kernel/sys_m32r.c 2006-04-09 13:49:43 +0200
928 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/m32r/kernel/sys_m32r.c    2006-07-09 17:06:47 +0200
929 @@ -21,6 +21,7 @@
930  #include <linux/mman.h>
931  #include <linux/file.h>
932  #include <linux/utsname.h>
933 +#include <linux/vs_cvirt.h>
934  
935  #include <asm/uaccess.h>
936  #include <asm/cachectl.h>
937 @@ -206,7 +207,7 @@ asmlinkage int sys_uname(struct old_utsn
938         if (!name)
939                 return -EFAULT;
940         down_read(&uts_sem);
941 -       err=copy_to_user(name, &system_utsname, sizeof (*name));
942 +       err=copy_to_user(name, vx_new_utsname(), sizeof (*name));
943         up_read(&uts_sem);
944         return err?-EFAULT:0;
945  }
946 diff -NurpP --minimal linux-2.6.17.11/arch/m32r/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/m32r/kernel/traps.c
947 --- linux-2.6.17.11/arch/m32r/kernel/traps.c    2005-10-28 20:49:11 +0200
948 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/m32r/kernel/traps.c       2006-07-09 17:06:47 +0200
949 @@ -196,8 +196,9 @@ static void show_registers(struct pt_reg
950         } else {
951                 printk("SPI: %08lx\n", sp);
952         }
953 -       printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
954 -               current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current);
955 +       printk("Process %s (pid: %d[#%u], process nr: %d, stackpage=%08lx)",
956 +               current->comm, current->pid, current->xid,
957 +               0xffff & i, 4096+(unsigned long)current);
958  
959         /*
960          * When in-kernel, we also print out the stack and code at the
961 diff -NurpP --minimal linux-2.6.17.11/arch/m68k/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/m68k/Kconfig
962 --- linux-2.6.17.11/arch/m68k/Kconfig   2006-06-18 04:51:57 +0200
963 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/m68k/Kconfig      2006-07-09 17:06:47 +0200
964 @@ -654,6 +654,8 @@ source "fs/Kconfig"
965  
966  source "arch/m68k/Kconfig.debug"
967  
968 +source "kernel/vserver/Kconfig"
969 +
970  source "security/Kconfig"
971  
972  source "crypto/Kconfig"
973 diff -NurpP --minimal linux-2.6.17.11/arch/m68k/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/m68k/kernel/process.c
974 --- linux-2.6.17.11/arch/m68k/kernel/process.c  2006-06-18 04:51:57 +0200
975 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/m68k/kernel/process.c     2006-07-09 17:06:47 +0200
976 @@ -160,7 +160,8 @@ int kernel_thread(int (*fn)(void *), voi
977  
978         {
979         register long retval __asm__ ("d0");
980 -       register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
981 +       register long clone_arg __asm__ ("d1") =
982 +               flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
983  
984         retval = __NR_clone;
985         __asm__ __volatile__
986 diff -NurpP --minimal linux-2.6.17.11/arch/m68k/kernel/ptrace.c linux-2.6.17.11-vs2.1.1-rc31/arch/m68k/kernel/ptrace.c
987 --- linux-2.6.17.11/arch/m68k/kernel/ptrace.c   2006-01-03 17:29:10 +0100
988 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/m68k/kernel/ptrace.c      2006-08-06 06:00:54 +0200
989 @@ -280,6 +280,8 @@ long arch_ptrace(struct task_struct *chi
990                 ret = ptrace_request(child, request, addr, data);
991                 break;
992         }
993 +       if (!vx_check(vx_task_xid(child), VX_WATCH_P|VX_IDENT))
994 +               goto out_tsk;
995  
996         return ret;
997  out_eio:
998 diff -NurpP --minimal linux-2.6.17.11/arch/m68k/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/m68k/kernel/traps.c
999 --- linux-2.6.17.11/arch/m68k/kernel/traps.c    2006-01-18 06:07:53 +0100
1000 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/m68k/kernel/traps.c       2006-07-09 17:06:47 +0200
1001 @@ -1198,8 +1198,9 @@ void die_if_kernel (char *str, struct pt
1002         printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
1003                fp->d4, fp->d5, fp->a0, fp->a1);
1004  
1005 -       printk("Process %s (pid: %d, stackpage=%08lx)\n",
1006 -               current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
1007 +       printk("Process %s (pid: %d[#%u], stackpage=%08lx)\n",
1008 +               current->comm, current->pid, current->xid,
1009 +               PAGE_SIZE+(unsigned long)current);
1010         show_stack(NULL, (unsigned long *)fp);
1011         do_exit(SIGSEGV);
1012  }
1013 diff -NurpP --minimal linux-2.6.17.11/arch/m68knommu/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/m68knommu/Kconfig
1014 --- linux-2.6.17.11/arch/m68knommu/Kconfig      2006-06-18 04:51:58 +0200
1015 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/m68knommu/Kconfig 2006-07-09 17:06:47 +0200
1016 @@ -654,6 +654,8 @@ source "fs/Kconfig"
1017  
1018  source "arch/m68knommu/Kconfig.debug"
1019  
1020 +source "kernel/vserver/Kconfig"
1021 +
1022  source "security/Kconfig"
1023  
1024  source "crypto/Kconfig"
1025 diff -NurpP --minimal linux-2.6.17.11/arch/m68knommu/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/m68knommu/kernel/process.c
1026 --- linux-2.6.17.11/arch/m68knommu/kernel/process.c     2006-06-18 04:51:58 +0200
1027 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/m68knommu/kernel/process.c        2006-07-09 17:06:47 +0200
1028 @@ -123,7 +123,7 @@ void show_regs(struct pt_regs * regs)
1029  int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
1030  {
1031         int retval;
1032 -       long clone_arg = flags | CLONE_VM;
1033 +       long clone_arg = flags | CLONE_VM | CLONE_KTHREAD;
1034         mm_segment_t fs;
1035  
1036         fs = get_fs();
1037 diff -NurpP --minimal linux-2.6.17.11/arch/m68knommu/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/m68knommu/kernel/traps.c
1038 --- linux-2.6.17.11/arch/m68knommu/kernel/traps.c       2005-10-28 20:49:11 +0200
1039 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/m68knommu/kernel/traps.c  2006-07-09 17:06:47 +0200
1040 @@ -81,8 +81,9 @@ void die_if_kernel(char *str, struct pt_
1041         printk(KERN_EMERG "d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
1042                fp->d4, fp->d5, fp->a0, fp->a1);
1043  
1044 -       printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n",
1045 -               current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
1046 +       printk(KERN_EMERG "Process %s (pid: %d[#%u], stackpage=%08lx)\n",
1047 +               current->comm, current->pid, current->xid,
1048 +               PAGE_SIZE+(unsigned long)current);
1049         show_stack(NULL, (unsigned long *)fp);
1050         do_exit(SIGSEGV);
1051  }
1052 diff -NurpP --minimal linux-2.6.17.11/arch/mips/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/mips/Kconfig
1053 --- linux-2.6.17.11/arch/mips/Kconfig   2006-06-18 04:51:58 +0200
1054 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/mips/Kconfig      2006-07-09 17:06:47 +0200
1055 @@ -1852,6 +1852,8 @@ source "arch/mips/oprofile/Kconfig"
1056  
1057  source "arch/mips/Kconfig.debug"
1058  
1059 +source "kernel/vserver/Kconfig"
1060 +
1061  source "security/Kconfig"
1062  
1063  source "crypto/Kconfig"
1064 diff -NurpP --minimal linux-2.6.17.11/arch/mips/kernel/linux32.c linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/linux32.c
1065 --- linux-2.6.17.11/arch/mips/kernel/linux32.c  2006-06-18 04:52:06 +0200
1066 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/linux32.c     2006-07-09 17:06:47 +0200
1067 @@ -36,6 +36,7 @@
1068  #include <linux/security.h>
1069  #include <linux/compat.h>
1070  #include <linux/vfs.h>
1071 +#include <linux/vs_cvirt.h>
1072  
1073  #include <net/sock.h>
1074  #include <net/scm.h>
1075 @@ -299,7 +300,7 @@ sys32_gettimeofday(struct compat_timeval
1076  {
1077         if (tv) {
1078                 struct timeval ktv;
1079 -               do_gettimeofday(&ktv);
1080 +               vx_gettimeofday(&ktv);
1081                 if (put_tv32(tv, &ktv))
1082                         return -EFAULT;
1083         }
1084 @@ -1040,7 +1041,7 @@ asmlinkage long sys32_newuname(struct ne
1085         int ret = 0;
1086  
1087         down_read(&uts_sem);
1088 -       if (copy_to_user(name,&system_utsname,sizeof *name))
1089 +       if (copy_to_user(name, vx_new_utsname(), sizeof *name))
1090                 ret = -EFAULT;
1091         up_read(&uts_sem);
1092  
1093 diff -NurpP --minimal linux-2.6.17.11/arch/mips/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/process.c
1094 --- linux-2.6.17.11/arch/mips/kernel/process.c  2006-06-18 04:52:06 +0200
1095 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/process.c     2006-07-09 17:06:47 +0200
1096 @@ -271,7 +271,8 @@ long kernel_thread(int (*fn)(void *), vo
1097  #endif
1098  
1099         /* Ok, create the new process.. */
1100 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
1101 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
1102 +               0, &regs, 0, NULL, NULL);
1103  }
1104  
1105  static struct mips_frame_info {
1106 diff -NurpP --minimal linux-2.6.17.11/arch/mips/kernel/ptrace.c linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/ptrace.c
1107 --- linux-2.6.17.11/arch/mips/kernel/ptrace.c   2006-06-18 04:52:06 +0200
1108 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/ptrace.c      2006-08-06 06:01:04 +0200
1109 @@ -490,6 +490,8 @@ asmlinkage void do_syscall_trace(struct 
1110                 goto out;
1111         if (!test_thread_flag(TIF_SYSCALL_TRACE))
1112                 goto out;
1113 +       if (!vx_check(vx_task_xid(child), VX_WATCH_P|VX_IDENT))
1114 +               goto out_tsk;
1115  
1116         /* The 0x80 provides a way for the tracing parent to distinguish
1117            between a syscall stop and SIGTRAP delivery */
1118 diff -NurpP --minimal linux-2.6.17.11/arch/mips/kernel/scall32-o32.S linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/scall32-o32.S
1119 --- linux-2.6.17.11/arch/mips/kernel/scall32-o32.S      2006-06-18 04:52:06 +0200
1120 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/scall32-o32.S 2006-07-09 17:06:47 +0200
1121 @@ -618,7 +618,7 @@ einval:     li      v0, -EINVAL
1122         sys     sys_mq_timedreceive     5
1123         sys     sys_mq_notify           2       /* 4275 */
1124         sys     sys_mq_getsetattr       3
1125 -       sys     sys_ni_syscall          0       /* sys_vserver */
1126 +       sys     sys_vserver             3
1127         sys     sys_waitid              5
1128         sys     sys_ni_syscall          0       /* available, was setaltroot */
1129         sys     sys_add_key             5       /* 4280 */
1130 diff -NurpP --minimal linux-2.6.17.11/arch/mips/kernel/scall64-64.S linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/scall64-64.S
1131 --- linux-2.6.17.11/arch/mips/kernel/scall64-64.S       2006-06-18 04:52:06 +0200
1132 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/scall64-64.S  2006-07-09 17:06:47 +0200
1133 @@ -433,7 +433,7 @@ sys_call_table:
1134         PTR     sys_mq_timedreceive
1135         PTR     sys_mq_notify
1136         PTR     sys_mq_getsetattr               /* 5235 */
1137 -       PTR     sys_ni_syscall                  /* sys_vserver */
1138 +       PTR     sys_vserver
1139         PTR     sys_waitid
1140         PTR     sys_ni_syscall                  /* available, was setaltroot */
1141         PTR     sys_add_key
1142 diff -NurpP --minimal linux-2.6.17.11/arch/mips/kernel/scall64-n32.S linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/scall64-n32.S
1143 --- linux-2.6.17.11/arch/mips/kernel/scall64-n32.S      2006-06-18 04:52:06 +0200
1144 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/scall64-n32.S 2006-07-09 17:06:47 +0200
1145 @@ -359,7 +359,7 @@ EXPORT(sysn32_call_table)
1146         PTR     compat_sys_mq_timedreceive
1147         PTR     compat_sys_mq_notify
1148         PTR     compat_sys_mq_getsetattr
1149 -       PTR     sys_ni_syscall                  /* 6240, sys_vserver */
1150 +       PTR     sys32_vserver                   /* 6240 */
1151         PTR     sysn32_waitid
1152         PTR     sys_ni_syscall                  /* available, was setaltroot */
1153         PTR     sys_add_key
1154 diff -NurpP --minimal linux-2.6.17.11/arch/mips/kernel/scall64-o32.S linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/scall64-o32.S
1155 --- linux-2.6.17.11/arch/mips/kernel/scall64-o32.S      2006-06-18 04:52:06 +0200
1156 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/scall64-o32.S 2006-07-09 17:06:47 +0200
1157 @@ -481,7 +481,7 @@ sys_call_table:
1158         PTR     compat_sys_mq_timedreceive
1159         PTR     compat_sys_mq_notify            /* 4275 */
1160         PTR     compat_sys_mq_getsetattr
1161 -       PTR     sys_ni_syscall                  /* sys_vserver */
1162 +       PTR     sys32_vserver
1163         PTR     sys32_waitid
1164         PTR     sys_ni_syscall                  /* available, was setaltroot */
1165         PTR     sys_add_key                     /* 4280 */
1166 diff -NurpP --minimal linux-2.6.17.11/arch/mips/kernel/syscall.c linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/syscall.c
1167 --- linux-2.6.17.11/arch/mips/kernel/syscall.c  2006-06-18 04:52:06 +0200
1168 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/syscall.c     2006-07-09 17:06:47 +0200
1169 @@ -29,6 +29,7 @@
1170  #include <linux/shm.h>
1171  #include <linux/compiler.h>
1172  #include <linux/module.h>
1173 +#include <linux/vs_cvirt.h>
1174  
1175  #include <asm/branch.h>
1176  #include <asm/cachectl.h>
1177 @@ -232,7 +233,7 @@ out:
1178   */
1179  asmlinkage int sys_uname(struct old_utsname __user * name)
1180  {
1181 -       if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
1182 +       if (name && !copy_to_user(name, vx_new_utsname(), sizeof (*name)))
1183                 return 0;
1184         return -EFAULT;
1185  }
1186 @@ -243,21 +244,23 @@ asmlinkage int sys_uname(struct old_utsn
1187  asmlinkage int sys_olduname(struct oldold_utsname __user * name)
1188  {
1189         int error;
1190 +       struct new_utsname *ptr;
1191  
1192         if (!name)
1193                 return -EFAULT;
1194         if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
1195                 return -EFAULT;
1196  
1197 -       error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
1198 +       ptr = vx_new_utsname();
1199 +       error = __copy_to_user(&name->sysname,ptr->sysname,__OLD_UTS_LEN);
1200         error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
1201 -       error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
1202 +       error -= __copy_to_user(&name->nodename,ptr->nodename,__OLD_UTS_LEN);
1203         error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
1204 -       error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
1205 +       error -= __copy_to_user(&name->release,ptr->release,__OLD_UTS_LEN);
1206         error -= __put_user(0,name->release+__OLD_UTS_LEN);
1207 -       error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
1208 +       error -= __copy_to_user(&name->version,ptr->version,__OLD_UTS_LEN);
1209         error -= __put_user(0,name->version+__OLD_UTS_LEN);
1210 -       error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
1211 +       error -= __copy_to_user(&name->machine,ptr->machine,__OLD_UTS_LEN);
1212         error = __put_user(0,name->machine+__OLD_UTS_LEN);
1213         error = error ? -EFAULT : 0;
1214  
1215 diff -NurpP --minimal linux-2.6.17.11/arch/mips/kernel/sysirix.c linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/sysirix.c
1216 --- linux-2.6.17.11/arch/mips/kernel/sysirix.c  2006-06-18 04:52:06 +0200
1217 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/sysirix.c     2006-07-09 17:06:47 +0200
1218 @@ -31,6 +31,8 @@
1219  #include <linux/socket.h>
1220  #include <linux/security.h>
1221  #include <linux/syscalls.h>
1222 +#include <linux/vs_cvirt.h>
1223 +#include <linux/vs_pid.h>
1224  
1225  #include <asm/ptrace.h>
1226  #include <asm/page.h>
1227 @@ -884,7 +886,7 @@ asmlinkage int irix_getdomainname(char _
1228         down_read(&uts_sem);
1229         if (len > __NEW_UTS_LEN)
1230                 len = __NEW_UTS_LEN;
1231 -       err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0;
1232 +       err = copy_to_user(name, vx_new_uts(domainname), len) ? -EFAULT : 0;
1233         up_read(&uts_sem);
1234  
1235         return err;
1236 @@ -1127,11 +1129,11 @@ struct iuname {
1237  asmlinkage int irix_uname(struct iuname __user *buf)
1238  {
1239         down_read(&uts_sem);
1240 -       if (copy_from_user(system_utsname.sysname, buf->sysname, 65)
1241 -           || copy_from_user(system_utsname.nodename, buf->nodename, 65)
1242 -           || copy_from_user(system_utsname.release, buf->release, 65)
1243 -           || copy_from_user(system_utsname.version, buf->version, 65)
1244 -           || copy_from_user(system_utsname.machine, buf->machine, 65)) {
1245 +       if (copy_from_user(vx_new_uts(sysname), buf->sysname, 65)
1246 +           || copy_from_user(vx_new_uts(nodename), buf->nodename, 65)
1247 +           || copy_from_user(vx_new_uts(release), buf->release, 65)
1248 +           || copy_from_user(vx_new_uts(version), buf->version, 65)
1249 +           || copy_from_user(vx_new_uts(machine), buf->machine, 65)) {
1250                 return -EFAULT;
1251         }
1252         up_read(&uts_sem);
1253 diff -NurpP --minimal linux-2.6.17.11/arch/mips/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/traps.c
1254 --- linux-2.6.17.11/arch/mips/kernel/traps.c    2006-06-18 04:52:06 +0200
1255 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/mips/kernel/traps.c       2006-07-09 17:06:47 +0200
1256 @@ -267,8 +267,9 @@ void show_registers(struct pt_regs *regs
1257  {
1258         show_regs(regs);
1259         print_modules();
1260 -       printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
1261 -               current->comm, current->pid, current_thread_info(), current);
1262 +       printk("Process %s (pid: %d[#%u], threadinfo=%p, task=%p)\n",
1263 +               current->comm, current->pid, current->xid,
1264 +               current_thread_info(), current);
1265         show_stack(current, (long *) regs->regs[29]);
1266         show_trace(current, (long *) regs->regs[29]);
1267         show_code((unsigned int *) regs->cp0_epc);
1268 diff -NurpP --minimal linux-2.6.17.11/arch/parisc/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/Kconfig
1269 --- linux-2.6.17.11/arch/parisc/Kconfig 2006-06-18 04:52:14 +0200
1270 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/Kconfig    2006-07-09 17:06:48 +0200
1271 @@ -253,6 +253,8 @@ source "arch/parisc/oprofile/Kconfig"
1272  
1273  source "arch/parisc/Kconfig.debug"
1274  
1275 +source "kernel/vserver/Kconfig"
1276 +
1277  source "security/Kconfig"
1278  
1279  source "crypto/Kconfig"
1280 diff -NurpP --minimal linux-2.6.17.11/arch/parisc/hpux/sys_hpux.c linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/hpux/sys_hpux.c
1281 --- linux-2.6.17.11/arch/parisc/hpux/sys_hpux.c 2006-02-15 13:54:11 +0100
1282 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/hpux/sys_hpux.c    2006-07-09 17:06:48 +0200
1283 @@ -33,6 +33,7 @@
1284  #include <linux/utsname.h>
1285  #include <linux/vfs.h>
1286  #include <linux/vmalloc.h>
1287 +#include <linux/vs_cvirt.h>
1288  
1289  #include <asm/errno.h>
1290  #include <asm/pgalloc.h>
1291 @@ -266,15 +267,15 @@ static int hpux_uname(struct hpux_utsnam
1292  
1293         down_read(&uts_sem);
1294  
1295 -       error = __copy_to_user(&name->sysname,&system_utsname.sysname,HPUX_UTSLEN-1);
1296 +       error = __copy_to_user(&name->sysname,vx_new_uts(sysname),HPUX_UTSLEN-1);
1297         error |= __put_user(0,name->sysname+HPUX_UTSLEN-1);
1298 -       error |= __copy_to_user(&name->nodename,&system_utsname.nodename,HPUX_UTSLEN-1);
1299 +       error |= __copy_to_user(&name->nodename,vx_new_uts(nodename),HPUX_UTSLEN-1);
1300         error |= __put_user(0,name->nodename+HPUX_UTSLEN-1);
1301 -       error |= __copy_to_user(&name->release,&system_utsname.release,HPUX_UTSLEN-1);
1302 +       error |= __copy_to_user(&name->release,vx_new_uts(release),HPUX_UTSLEN-1);
1303         error |= __put_user(0,name->release+HPUX_UTSLEN-1);
1304 -       error |= __copy_to_user(&name->version,&system_utsname.version,HPUX_UTSLEN-1);
1305 +       error |= __copy_to_user(&name->version,vx_new_uts(version),HPUX_UTSLEN-1);
1306         error |= __put_user(0,name->version+HPUX_UTSLEN-1);
1307 -       error |= __copy_to_user(&name->machine,&system_utsname.machine,HPUX_UTSLEN-1);
1308 +       error |= __copy_to_user(&name->machine,vx_new_uts(machine),HPUX_UTSLEN-1);
1309         error |= __put_user(0,name->machine+HPUX_UTSLEN-1);
1310  
1311         up_read(&uts_sem);
1312 @@ -373,8 +374,8 @@ int hpux_utssys(char *ubuf, int n, int t
1313                 /*  TODO:  print a warning about using this?  */
1314                 down_write(&uts_sem);
1315                 error = -EFAULT;
1316 -               if (!copy_from_user(system_utsname.sysname, ubuf, len)) {
1317 -                       system_utsname.sysname[len] = 0;
1318 +               if (!copy_from_user(vx_new_uts(sysname), ubuf, len)) {
1319 +                       vx_new_uts(sysname)[len] = 0;
1320                         error = 0;
1321                 }
1322                 up_write(&uts_sem);
1323 @@ -400,8 +401,8 @@ int hpux_utssys(char *ubuf, int n, int t
1324                 /*  TODO:  print a warning about this?  */
1325                 down_write(&uts_sem);
1326                 error = -EFAULT;
1327 -               if (!copy_from_user(system_utsname.release, ubuf, len)) {
1328 -                       system_utsname.release[len] = 0;
1329 +               if (!copy_from_user(vx_new_uts(release), ubuf, len)) {
1330 +                       vx_new_uts(release)[len] = 0;
1331                         error = 0;
1332                 }
1333                 up_write(&uts_sem);
1334 @@ -422,13 +423,13 @@ int hpux_getdomainname(char *name, int l
1335         
1336         down_read(&uts_sem);
1337         
1338 -       nlen = strlen(system_utsname.domainname) + 1;
1339 +       nlen = strlen(vx_new_uts(domainname)) + 1;
1340  
1341         if (nlen < len)
1342                 len = nlen;
1343         if(len > __NEW_UTS_LEN)
1344                 goto done;
1345 -       if(copy_to_user(name, system_utsname.domainname, len))
1346 +       if(copy_to_user(name, vx_new_uts(domainname), len))
1347                 goto done;
1348         err = 0;
1349  done:
1350 diff -NurpP --minimal linux-2.6.17.11/arch/parisc/kernel/entry.S linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/kernel/entry.S
1351 --- linux-2.6.17.11/arch/parisc/kernel/entry.S  2006-06-18 04:52:14 +0200
1352 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/kernel/entry.S     2006-07-09 17:06:48 +0200
1353 @@ -765,6 +765,7 @@ fault_vector_11:
1354  
1355  #define CLONE_VM 0x100 /* Must agree with <linux/sched.h> */
1356  #define CLONE_UNTRACED 0x00800000
1357 +#define CLONE_KTHREAD 0x10000000
1358  
1359         .export __kernel_thread, code
1360         .import do_fork
1361 diff -NurpP --minimal linux-2.6.17.11/arch/parisc/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/kernel/process.c
1362 --- linux-2.6.17.11/arch/parisc/kernel/process.c        2006-06-18 04:52:15 +0200
1363 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/kernel/process.c   2006-07-09 17:06:48 +0200
1364 @@ -173,7 +173,7 @@ pid_t kernel_thread(int (*fn)(void *), v
1365          *        kernel_thread can become a #define.
1366          */
1367  
1368 -       return __kernel_thread(fn, arg, flags);
1369 +       return __kernel_thread(fn, arg, flags | CLONE_KTHREAD);
1370  }
1371  EXPORT_SYMBOL(kernel_thread);
1372  
1373 diff -NurpP --minimal linux-2.6.17.11/arch/parisc/kernel/sys_parisc32.c linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/kernel/sys_parisc32.c
1374 --- linux-2.6.17.11/arch/parisc/kernel/sys_parisc32.c   2006-06-18 04:52:15 +0200
1375 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/kernel/sys_parisc32.c      2006-07-09 17:06:48 +0200
1376 @@ -202,11 +202,11 @@ static inline long get_ts32(struct times
1377  asmlinkage int
1378  sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
1379  {
1380 -    extern void do_gettimeofday(struct timeval *tv);
1381 +    extern void vx_gettimeofday(struct timeval *tv);
1382  
1383      if (tv) {
1384             struct timeval ktv;
1385 -           do_gettimeofday(&ktv);
1386 +           vx_gettimeofday(&ktv);
1387             if (put_compat_timeval(tv, &ktv))
1388                     return -EFAULT;
1389      }
1390 @@ -599,6 +599,7 @@ asmlinkage int sys32_sysinfo(struct sysi
1391  
1392         do {
1393                 seq = read_seqbegin(&xtime_lock);
1394 +               /* FIXME: requires vx virtualization */
1395                 val.uptime = jiffies / HZ;
1396  
1397                 val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
1398 diff -NurpP --minimal linux-2.6.17.11/arch/parisc/kernel/syscall_table.S linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/kernel/syscall_table.S
1399 --- linux-2.6.17.11/arch/parisc/kernel/syscall_table.S  2006-06-18 04:52:15 +0200
1400 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/kernel/syscall_table.S     2006-07-09 17:06:48 +0200
1401 @@ -368,7 +368,7 @@
1402         ENTRY_COMP(mbind)               /* 260 */
1403         ENTRY_COMP(get_mempolicy)
1404         ENTRY_COMP(set_mempolicy)
1405 -       ENTRY_SAME(ni_syscall)  /* 263: reserved for vserver */
1406 +       ENTRY_DIFF(vserver)
1407         ENTRY_SAME(add_key)
1408         ENTRY_SAME(request_key)         /* 265 */
1409         ENTRY_SAME(keyctl)
1410 diff -NurpP --minimal linux-2.6.17.11/arch/parisc/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/kernel/traps.c
1411 --- linux-2.6.17.11/arch/parisc/kernel/traps.c  2006-02-15 13:54:11 +0100
1412 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/parisc/kernel/traps.c     2006-07-09 17:06:48 +0200
1413 @@ -214,8 +214,9 @@ void die_if_kernel(char *str, struct pt_
1414                 if (err == 0)
1415                         return; /* STFU */
1416  
1417 -               printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
1418 -                       current->comm, current->pid, str, err, regs->iaoq[0]);
1419 +               printk(KERN_CRIT "%s (pid %d[#%u]): %s (code %ld) at " RFMT "\n",
1420 +                       current->comm, current->pid, current->xid,
1421 +                       str, err, regs->iaoq[0]);
1422  #ifdef PRINT_USER_FAULTS
1423                 /* XXX for debugging only */
1424                 show_regs(regs);
1425 @@ -246,8 +247,8 @@ void die_if_kernel(char *str, struct pt_
1426         if (!console_drivers)
1427                 pdc_console_restart();
1428         
1429 -       printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
1430 -               current->comm, current->pid, str, err);
1431 +       printk(KERN_CRIT "%s (pid %d[#%u]): %s (code %ld)\n",
1432 +               current->comm, current->pid, current->xid, str, err);
1433         show_regs(regs);
1434  
1435         /* Wot's wrong wif bein' racy? */
1436 diff -NurpP --minimal linux-2.6.17.11/arch/powerpc/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/Kconfig
1437 --- linux-2.6.17.11/arch/powerpc/Kconfig        2006-08-25 00:25:37 +0200
1438 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/Kconfig   2006-07-26 21:36:47 +0200
1439 @@ -1018,6 +1018,8 @@ endmenu
1440  
1441  source "arch/powerpc/Kconfig.debug"
1442  
1443 +source "kernel/vserver/Kconfig"
1444 +
1445  source "security/Kconfig"
1446  
1447  config KEYS_COMPAT
1448 diff -NurpP --minimal linux-2.6.17.11/arch/powerpc/kernel/asm-offsets.c linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/asm-offsets.c
1449 --- linux-2.6.17.11/arch/powerpc/kernel/asm-offsets.c   2006-06-18 04:52:16 +0200
1450 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/asm-offsets.c      2006-07-09 17:06:48 +0200
1451 @@ -231,6 +231,7 @@ int main(void)
1452  
1453         DEFINE(CLONE_VM, CLONE_VM);
1454         DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
1455 +       DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
1456  
1457  #ifndef CONFIG_PPC64
1458         DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
1459 diff -NurpP --minimal linux-2.6.17.11/arch/powerpc/kernel/misc_32.S linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/misc_32.S
1460 --- linux-2.6.17.11/arch/powerpc/kernel/misc_32.S       2006-01-18 06:07:55 +0100
1461 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/misc_32.S  2006-07-09 17:06:48 +0200
1462 @@ -980,7 +980,7 @@ _GLOBAL(kernel_thread)
1463         mr      r30,r3          /* function */
1464         mr      r31,r4          /* argument */
1465         ori     r3,r5,CLONE_VM  /* flags */
1466 -       oris    r3,r3,CLONE_UNTRACED>>16
1467 +       oris    r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
1468         li      r4,0            /* new sp (unused) */
1469         li      r0,__NR_clone
1470         sc
1471 diff -NurpP --minimal linux-2.6.17.11/arch/powerpc/kernel/misc_64.S linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/misc_64.S
1472 --- linux-2.6.17.11/arch/powerpc/kernel/misc_64.S       2006-01-18 06:07:55 +0100
1473 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/misc_64.S  2006-07-09 17:06:48 +0200
1474 @@ -684,7 +684,7 @@ _GLOBAL(kernel_thread)
1475         mr      r29,r3
1476         mr      r30,r4
1477         ori     r3,r5,CLONE_VM  /* flags */
1478 -       oris    r3,r3,(CLONE_UNTRACED>>16)
1479 +       oris    r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
1480         li      r4,0            /* new sp (unused) */
1481         li      r0,__NR_clone
1482         sc
1483 diff -NurpP --minimal linux-2.6.17.11/arch/powerpc/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/process.c
1484 --- linux-2.6.17.11/arch/powerpc/kernel/process.c       2006-06-18 04:52:16 +0200
1485 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/process.c  2006-07-09 17:06:48 +0200
1486 @@ -432,8 +432,9 @@ void show_regs(struct pt_regs * regs)
1487         trap = TRAP(regs);
1488         if (trap == 0x300 || trap == 0x600)
1489                 printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
1490 -       printk("TASK = %p[%d] '%s' THREAD: %p",
1491 -              current, current->pid, current->comm, task_thread_info(current));
1492 +       printk("TASK = %p[%d,#%u] '%s' THREAD: %p",
1493 +              current, current->pid, current->xid,
1494 +              current->comm, task_thread_info(current));
1495  
1496  #ifdef CONFIG_SMP
1497         printk(" CPU: %d", smp_processor_id());
1498 diff -NurpP --minimal linux-2.6.17.11/arch/powerpc/kernel/sys_ppc32.c linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/sys_ppc32.c
1499 --- linux-2.6.17.11/arch/powerpc/kernel/sys_ppc32.c     2006-06-18 04:52:17 +0200
1500 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/sys_ppc32.c        2006-07-09 17:06:48 +0200
1501 @@ -267,7 +267,7 @@ asmlinkage long compat_sys_gettimeofday(
1502  {
1503         if (tv) {
1504                 struct timeval ktv;
1505 -               do_gettimeofday(&ktv);
1506 +               vx_gettimeofday(&ktv);
1507                 if (put_tv32(tv, &ktv))
1508                         return -EFAULT;
1509         }
1510 diff -NurpP --minimal linux-2.6.17.11/arch/powerpc/kernel/syscalls.c linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/syscalls.c
1511 --- linux-2.6.17.11/arch/powerpc/kernel/syscalls.c      2006-06-18 04:52:17 +0200
1512 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/syscalls.c 2006-07-09 17:06:48 +0200
1513 @@ -36,6 +36,7 @@
1514  #include <linux/file.h>
1515  #include <linux/init.h>
1516  #include <linux/personality.h>
1517 +#include <linux/vs_cvirt.h>
1518  
1519  #include <asm/uaccess.h>
1520  #include <asm/ipc.h>
1521 @@ -260,7 +261,7 @@ long ppc_newuname(struct new_utsname __u
1522         int err = 0;
1523  
1524         down_read(&uts_sem);
1525 -       if (copy_to_user(name, &system_utsname, sizeof(*name)))
1526 +       if (copy_to_user(name, vx_new_utsname(), sizeof(*name)))
1527                 err = -EFAULT;
1528         up_read(&uts_sem);
1529         if (!err)
1530 @@ -273,7 +274,7 @@ int sys_uname(struct old_utsname __user 
1531         int err = 0;
1532         
1533         down_read(&uts_sem);
1534 -       if (copy_to_user(name, &system_utsname, sizeof(*name)))
1535 +       if (copy_to_user(name, vx_new_utsname(), sizeof(*name)))
1536                 err = -EFAULT;
1537         up_read(&uts_sem);
1538         if (!err)
1539 @@ -284,25 +285,22 @@ int sys_uname(struct old_utsname __user 
1540  int sys_olduname(struct oldold_utsname __user *name)
1541  {
1542         int error;
1543 +       struct new_utsname *ptr;
1544  
1545         if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
1546                 return -EFAULT;
1547    
1548         down_read(&uts_sem);
1549 -       error = __copy_to_user(&name->sysname, &system_utsname.sysname,
1550 -                              __OLD_UTS_LEN);
1551 +       ptr = vx_new_utsname();
1552 +       error = __copy_to_user(&name->sysname, ptr->sysname, __OLD_UTS_LEN);
1553         error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
1554 -       error |= __copy_to_user(&name->nodename, &system_utsname.nodename,
1555 -                               __OLD_UTS_LEN);
1556 +       error |= __copy_to_user(&name->nodename, ptr->nodename, __OLD_UTS_LEN);
1557         error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
1558 -       error |= __copy_to_user(&name->release, &system_utsname.release,
1559 -                               __OLD_UTS_LEN);
1560 +       error |= __copy_to_user(&name->release, ptr->release, __OLD_UTS_LEN);
1561         error |= __put_user(0, name->release + __OLD_UTS_LEN);
1562 -       error |= __copy_to_user(&name->version, &system_utsname.version,
1563 -                               __OLD_UTS_LEN);
1564 +       error |= __copy_to_user(&name->version, ptr->version, __OLD_UTS_LEN);
1565         error |= __put_user(0, name->version + __OLD_UTS_LEN);
1566 -       error |= __copy_to_user(&name->machine, &system_utsname.machine,
1567 -                               __OLD_UTS_LEN);
1568 +       error |= __copy_to_user(&name->machine, ptr->machine, __OLD_UTS_LEN);
1569         error |= override_machine(name->machine);
1570         up_read(&uts_sem);
1571  
1572 diff -NurpP --minimal linux-2.6.17.11/arch/powerpc/kernel/systbl.S linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/systbl.S
1573 --- linux-2.6.17.11/arch/powerpc/kernel/systbl.S        2006-06-18 04:52:17 +0200
1574 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/systbl.S   2006-07-09 17:06:48 +0200
1575 @@ -296,7 +296,7 @@ COMPAT_SYS(fstatfs64)
1576  SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64)
1577  PPC_SYS(rtas)
1578  OLDSYS(debug_setcontext)
1579 -SYSCALL(ni_syscall)
1580 +SYSX(sys_vserver, sys32_vserver, sys_vserver)
1581  SYSCALL(ni_syscall)
1582  COMPAT_SYS(mbind)
1583  COMPAT_SYS(get_mempolicy)
1584 diff -NurpP --minimal linux-2.6.17.11/arch/powerpc/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/traps.c
1585 --- linux-2.6.17.11/arch/powerpc/kernel/traps.c 2006-06-18 04:52:17 +0200
1586 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/traps.c    2006-07-09 17:06:48 +0200
1587 @@ -846,8 +846,9 @@ void nonrecoverable_exception(struct pt_
1588  
1589  void trace_syscall(struct pt_regs *regs)
1590  {
1591 -       printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
1592 -              current, current->pid, regs->nip, regs->link, regs->gpr[0],
1593 +       printk("Task: %p(%d[#%u]), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
1594 +              current, current->pid, current->xid,
1595 +              regs->nip, regs->link, regs->gpr[0],
1596                regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
1597  }
1598  
1599 diff -NurpP --minimal linux-2.6.17.11/arch/powerpc/kernel/vdso.c linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/vdso.c
1600 --- linux-2.6.17.11/arch/powerpc/kernel/vdso.c  2006-06-18 04:52:17 +0200
1601 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/powerpc/kernel/vdso.c     2006-07-09 17:06:48 +0200
1602 @@ -23,6 +23,7 @@
1603  #include <linux/elf.h>
1604  #include <linux/security.h>
1605  #include <linux/bootmem.h>
1606 +#include <linux/vs_memory.h>
1607  
1608  #include <asm/pgtable.h>
1609  #include <asm/system.h>
1610 @@ -293,7 +294,7 @@ int arch_setup_additional_pages(struct l
1611                 kmem_cache_free(vm_area_cachep, vma);
1612                 return -ENOMEM;
1613         }
1614 -       mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
1615 +       vx_vmpages_add(mm, (vma->vm_end - vma->vm_start) >> PAGE_SHIFT);
1616         up_write(&mm->mmap_sem);
1617  
1618         return 0;
1619 diff -NurpP --minimal linux-2.6.17.11/arch/ppc/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/ppc/Kconfig
1620 --- linux-2.6.17.11/arch/ppc/Kconfig    2006-06-18 04:52:22 +0200
1621 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ppc/Kconfig       2006-07-09 17:06:48 +0200
1622 @@ -1414,6 +1414,8 @@ source "arch/powerpc/oprofile/Kconfig"
1623  
1624  source "arch/ppc/Kconfig.debug"
1625  
1626 +source "kernel/vserver/Kconfig"
1627 +
1628  source "security/Kconfig"
1629  
1630  source "crypto/Kconfig"
1631 diff -NurpP --minimal linux-2.6.17.11/arch/ppc/kernel/asm-offsets.c linux-2.6.17.11-vs2.1.1-rc31/arch/ppc/kernel/asm-offsets.c
1632 --- linux-2.6.17.11/arch/ppc/kernel/asm-offsets.c       2006-06-18 04:52:24 +0200
1633 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ppc/kernel/asm-offsets.c  2006-07-09 17:06:48 +0200
1634 @@ -122,6 +122,7 @@ main(void)
1635         DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
1636         DEFINE(CLONE_VM, CLONE_VM);
1637         DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
1638 +       DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
1639         DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
1640  
1641         /* About the CPU features table */
1642 diff -NurpP --minimal linux-2.6.17.11/arch/ppc/kernel/misc.S linux-2.6.17.11-vs2.1.1-rc31/arch/ppc/kernel/misc.S
1643 --- linux-2.6.17.11/arch/ppc/kernel/misc.S      2006-02-17 22:18:50 +0100
1644 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ppc/kernel/misc.S 2006-07-09 17:06:48 +0200
1645 @@ -1011,7 +1011,7 @@ _GLOBAL(kernel_thread)
1646         mr      r30,r3          /* function */
1647         mr      r31,r4          /* argument */
1648         ori     r3,r5,CLONE_VM  /* flags */
1649 -       oris    r3,r3,CLONE_UNTRACED>>16
1650 +       oris    r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
1651         li      r4,0            /* new sp (unused) */
1652         li      r0,__NR_clone
1653         sc
1654 diff -NurpP --minimal linux-2.6.17.11/arch/ppc/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/ppc/kernel/traps.c
1655 --- linux-2.6.17.11/arch/ppc/kernel/traps.c     2006-06-18 04:52:25 +0200
1656 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/ppc/kernel/traps.c        2006-07-09 17:06:48 +0200
1657 @@ -747,8 +747,9 @@ void nonrecoverable_exception(struct pt_
1658  
1659  void trace_syscall(struct pt_regs *regs)
1660  {
1661 -       printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
1662 -              current, current->pid, regs->nip, regs->link, regs->gpr[0],
1663 +       printk("Task: %p(%d[#%u]), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
1664 +              current, current->pid, current->xid,
1665 +              regs->nip, regs->link, regs->gpr[0],
1666                regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
1667  }
1668  
1669 diff -NurpP --minimal linux-2.6.17.11/arch/s390/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/s390/Kconfig
1670 --- linux-2.6.17.11/arch/s390/Kconfig   2006-06-18 04:52:32 +0200
1671 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/s390/Kconfig      2006-07-09 17:06:48 +0200
1672 @@ -478,6 +478,8 @@ source "arch/s390/oprofile/Kconfig"
1673  
1674  source "arch/s390/Kconfig.debug"
1675  
1676 +source "kernel/vserver/Kconfig"
1677 +
1678  source "security/Kconfig"
1679  
1680  source "crypto/Kconfig"
1681 diff -NurpP --minimal linux-2.6.17.11/arch/s390/kernel/compat_linux.c linux-2.6.17.11-vs2.1.1-rc31/arch/s390/kernel/compat_linux.c
1682 --- linux-2.6.17.11/arch/s390/kernel/compat_linux.c     2006-06-18 04:52:32 +0200
1683 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/s390/kernel/compat_linux.c        2006-07-09 17:06:48 +0200
1684 @@ -594,7 +594,7 @@ asmlinkage long sys32_gettimeofday(struc
1685  {
1686         if (tv) {
1687                 struct timeval ktv;
1688 -               do_gettimeofday(&ktv);
1689 +               vx_gettimeofday(&ktv);
1690                 if (put_tv32(tv, &ktv))
1691                         return -EFAULT;
1692         }
1693 diff -NurpP --minimal linux-2.6.17.11/arch/s390/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/s390/kernel/process.c
1694 --- linux-2.6.17.11/arch/s390/kernel/process.c  2006-06-18 04:52:33 +0200
1695 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/s390/kernel/process.c     2006-07-09 17:06:48 +0200
1696 @@ -165,9 +165,9 @@ void show_regs(struct pt_regs *regs)
1697         struct task_struct *tsk = current;
1698  
1699          printk("CPU:    %d    %s\n", task_thread_info(tsk)->cpu, print_tainted());
1700 -        printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
1701 -              current->comm, current->pid, (void *) tsk,
1702 -              (void *) tsk->thread.ksp);
1703 +       printk("Process %s (pid: %d[#%u], task: %p, ksp: %p)\n",
1704 +              current->comm, current->pid, current->xid,
1705 +              (void *) tsk, (void *) tsk->thread.ksp);
1706  
1707         show_registers(regs);
1708         /* Show stack backtrace if pt_regs is from kernel mode */
1709 @@ -197,7 +197,7 @@ int kernel_thread(int (*fn)(void *), voi
1710         regs.orig_gpr2 = -1;
1711  
1712         /* Ok, create the new process.. */
1713 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
1714 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
1715                        0, &regs, 0, NULL, NULL);
1716  }
1717  
1718 diff -NurpP --minimal linux-2.6.17.11/arch/s390/kernel/ptrace.c linux-2.6.17.11-vs2.1.1-rc31/arch/s390/kernel/ptrace.c
1719 --- linux-2.6.17.11/arch/s390/kernel/ptrace.c   2006-06-18 04:52:33 +0200
1720 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/s390/kernel/ptrace.c      2006-08-06 06:01:15 +0200
1721 @@ -723,7 +723,13 @@ sys_ptrace(long request, long pid, long 
1722                 goto out;
1723         }
1724  
1725 +       if (!vx_check(vx_task_xid(child), VX_WATCH_P|VX_IDENT)) {
1726 +               ret = -EPERM;
1727 +               goto out_tsk;
1728 +       }
1729 +
1730         ret = do_ptrace(child, request, addr, data);
1731 +out_tsk:
1732         put_task_struct(child);
1733  out:
1734         unlock_kernel();
1735 diff -NurpP --minimal linux-2.6.17.11/arch/s390/kernel/syscalls.S linux-2.6.17.11-vs2.1.1-rc31/arch/s390/kernel/syscalls.S
1736 --- linux-2.6.17.11/arch/s390/kernel/syscalls.S 2006-06-18 04:52:33 +0200
1737 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/s390/kernel/syscalls.S    2006-07-09 17:06:48 +0200
1738 @@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,sys_clock_sett
1739  SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper)       /* 260 */
1740  SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper)
1741  SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper)
1742 -NI_SYSCALL                                                     /* reserved for vserver */
1743 +SYSCALL(sys_vserver,sys_vserver,sys32_vserver)
1744  SYSCALL(s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper)
1745  SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper)
1746  SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper)
1747 diff -NurpP --minimal linux-2.6.17.11/arch/sh/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/sh/Kconfig
1748 --- linux-2.6.17.11/arch/sh/Kconfig     2006-06-18 04:52:33 +0200
1749 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sh/Kconfig        2006-07-09 17:06:48 +0200
1750 @@ -646,6 +646,8 @@ source "arch/sh/oprofile/Kconfig"
1751  
1752  source "arch/sh/Kconfig.debug"
1753  
1754 +source "kernel/vserver/Kconfig"
1755 +
1756  source "security/Kconfig"
1757  
1758  source "crypto/Kconfig"
1759 diff -NurpP --minimal linux-2.6.17.11/arch/sh/kernel/kgdb_stub.c linux-2.6.17.11-vs2.1.1-rc31/arch/sh/kernel/kgdb_stub.c
1760 --- linux-2.6.17.11/arch/sh/kernel/kgdb_stub.c  2004-08-14 12:54:51 +0200
1761 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sh/kernel/kgdb_stub.c     2006-07-09 17:06:48 +0200
1762 @@ -412,7 +412,7 @@ static struct task_struct *get_thread(in
1763         if (pid == PID_MAX) pid = 0;
1764  
1765         /* First check via PID */
1766 -       thread = find_task_by_pid(pid);
1767 +       thread = find_task_by_real_pid(pid);
1768  
1769         if (thread)
1770                 return thread;
1771 diff -NurpP --minimal linux-2.6.17.11/arch/sh/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/sh/kernel/process.c
1772 --- linux-2.6.17.11/arch/sh/kernel/process.c    2006-06-18 04:52:33 +0200
1773 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sh/kernel/process.c       2006-07-09 17:06:48 +0200
1774 @@ -112,7 +112,8 @@ void machine_power_off(void)
1775  void show_regs(struct pt_regs * regs)
1776  {
1777         printk("\n");
1778 -       printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
1779 +       printk("Pid : %d[#%u], Comm: %20s\n",
1780 +               current->pid, current->xid, current->comm);
1781         print_symbol("PC is at %s\n", regs->pc);
1782         printk("PC  : %08lx SP  : %08lx SR  : %08lx ",
1783                regs->pc, regs->regs[15], regs->sr);
1784 @@ -180,7 +181,8 @@ int kernel_thread(int (*fn)(void *), voi
1785         regs.sr = (1 << 30);
1786  
1787         /* Ok, create the new process.. */
1788 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
1789 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
1790 +               0, &regs, 0, NULL, NULL);
1791  }
1792  
1793  /*
1794 diff -NurpP --minimal linux-2.6.17.11/arch/sh/kernel/setup.c linux-2.6.17.11-vs2.1.1-rc31/arch/sh/kernel/setup.c
1795 --- linux-2.6.17.11/arch/sh/kernel/setup.c      2006-06-18 04:52:33 +0200
1796 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sh/kernel/setup.c 2006-07-09 17:06:48 +0200
1797 @@ -21,6 +21,7 @@
1798  #include <linux/utsname.h>
1799  #include <linux/cpu.h>
1800  #include <linux/pfn.h>
1801 +#include <linux/vs_cvirt.h>
1802  #include <asm/uaccess.h>
1803  #include <asm/io.h>
1804  #include <asm/sections.h>
1805 @@ -481,7 +482,7 @@ static int show_cpuinfo(struct seq_file 
1806                 seq_printf(m, "machine\t\t: %s\n", get_system_type());
1807  
1808         seq_printf(m, "processor\t: %d\n", cpu);
1809 -       seq_printf(m, "cpu family\t: %s\n", system_utsname.machine);
1810 +       seq_printf(m, "cpu family\t: %s\n", vx_new_uts(machine));
1811         seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype());
1812  
1813         show_cpuflags(m);
1814 diff -NurpP --minimal linux-2.6.17.11/arch/sh/kernel/sys_sh.c linux-2.6.17.11-vs2.1.1-rc31/arch/sh/kernel/sys_sh.c
1815 --- linux-2.6.17.11/arch/sh/kernel/sys_sh.c     2005-08-29 22:24:55 +0200
1816 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sh/kernel/sys_sh.c        2006-07-09 17:06:48 +0200
1817 @@ -21,6 +21,7 @@
1818  #include <linux/mman.h>
1819  #include <linux/file.h>
1820  #include <linux/utsname.h>
1821 +#include <linux/vs_cvirt.h>
1822  
1823  #include <asm/uaccess.h>
1824  #include <asm/ipc.h>
1825 @@ -267,7 +268,7 @@ asmlinkage int sys_uname(struct old_utsn
1826         if (!name)
1827                 return -EFAULT;
1828         down_read(&uts_sem);
1829 -       err=copy_to_user(name, &system_utsname, sizeof (*name));
1830 +       err=copy_to_user(name, vx_new_utsname(), sizeof (*name));
1831         up_read(&uts_sem);
1832         return err?-EFAULT:0;
1833  }
1834 diff -NurpP --minimal linux-2.6.17.11/arch/sh64/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/sh64/kernel/process.c
1835 --- linux-2.6.17.11/arch/sh64/kernel/process.c  2006-01-18 06:07:57 +0100
1836 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sh64/kernel/process.c     2006-07-09 17:06:48 +0200
1837 @@ -637,7 +637,7 @@ int kernel_thread(int (*fn)(void *), voi
1838  static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp)
1839  static __inline__ _syscall1(int,exit,int,ret)
1840  
1841 -       reply = clone(flags | CLONE_VM, 0);
1842 +       reply = clone(flags | CLONE_VM | CLONE_KTHREAD, 0);
1843         if (!reply) {
1844                 /* Child */
1845                 reply = exit(fn(arg));
1846 diff -NurpP --minimal linux-2.6.17.11/arch/sh64/kernel/sys_sh64.c linux-2.6.17.11-vs2.1.1-rc31/arch/sh64/kernel/sys_sh64.c
1847 --- linux-2.6.17.11/arch/sh64/kernel/sys_sh64.c 2005-06-22 02:37:59 +0200
1848 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sh64/kernel/sys_sh64.c    2006-07-09 17:06:48 +0200
1849 @@ -29,6 +29,7 @@
1850  #include <linux/file.h>
1851  #include <linux/utsname.h>
1852  #include <linux/syscalls.h>
1853 +#include <linux/vs_cvirt.h>
1854  #include <asm/uaccess.h>
1855  #include <asm/ipc.h>
1856  #include <asm/ptrace.h>
1857 @@ -279,7 +280,7 @@ asmlinkage int sys_uname(struct old_utsn
1858         if (!name)
1859                 return -EFAULT;
1860         down_read(&uts_sem);
1861 -       err=copy_to_user(name, &system_utsname, sizeof (*name));
1862 +       err=copy_to_user(name, vx_new_utsname(), sizeof (*name));
1863         up_read(&uts_sem);
1864         return err?-EFAULT:0;
1865  }
1866 diff -NurpP --minimal linux-2.6.17.11/arch/sparc/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/Kconfig
1867 --- linux-2.6.17.11/arch/sparc/Kconfig  2006-06-18 04:52:33 +0200
1868 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/Kconfig     2006-07-09 17:06:48 +0200
1869 @@ -291,6 +291,8 @@ source "fs/Kconfig"
1870  
1871  source "arch/sparc/Kconfig.debug"
1872  
1873 +source "kernel/vserver/Kconfig"
1874 +
1875  source "security/Kconfig"
1876  
1877  source "crypto/Kconfig"
1878 diff -NurpP --minimal linux-2.6.17.11/arch/sparc/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/process.c
1879 --- linux-2.6.17.11/arch/sparc/kernel/process.c 2006-02-15 13:54:13 +0100
1880 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/process.c    2006-07-09 17:06:48 +0200
1881 @@ -706,7 +706,8 @@ pid_t kernel_thread(int (*fn)(void *), v
1882                              /* Notreached by child. */
1883                              "1: mov %%o0, %0\n\t" :
1884                              "=r" (retval) :
1885 -                            "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED),
1886 +                            "i" (__NR_clone), "r" (flags |
1887 +                                       CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD),
1888                              "i" (__NR_exit),  "r" (fn), "r" (arg) :
1889                              "g1", "g2", "g3", "o0", "o1", "memory", "cc");
1890         return retval;
1891 diff -NurpP --minimal linux-2.6.17.11/arch/sparc/kernel/ptrace.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/ptrace.c
1892 --- linux-2.6.17.11/arch/sparc/kernel/ptrace.c  2006-04-09 13:49:44 +0200
1893 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/ptrace.c     2006-08-06 06:01:25 +0200
1894 @@ -19,6 +19,7 @@
1895  #include <linux/smp_lock.h>
1896  #include <linux/security.h>
1897  #include <linux/signal.h>
1898 +#include <linux/vs_pid.h>
1899  
1900  #include <asm/pgtable.h>
1901  #include <asm/system.h>
1902 @@ -299,6 +300,10 @@ asmlinkage void do_ptrace(struct pt_regs
1903                 pt_error_return(regs, -ret);
1904                 goto out;
1905         }
1906 +       if (!vx_check(vx_task_xid(child), VX_WATCH_P|VX_IDENT)) {
1907 +               pt_error_return(regs, ESRCH);
1908 +               goto out_tsk;
1909 +       }
1910  
1911         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
1912             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
1913 diff -NurpP --minimal linux-2.6.17.11/arch/sparc/kernel/sys_sparc.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/sys_sparc.c
1914 --- linux-2.6.17.11/arch/sparc/kernel/sys_sparc.c       2006-08-25 00:25:37 +0200
1915 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/sys_sparc.c  2006-08-25 00:12:52 +0200
1916 @@ -21,6 +21,7 @@
1917  #include <linux/utsname.h>
1918  #include <linux/smp.h>
1919  #include <linux/smp_lock.h>
1920 +#include <linux/vs_cvirt.h>
1921  
1922  #include <asm/uaccess.h>
1923  #include <asm/ipc.h>
1924 @@ -473,13 +474,13 @@ asmlinkage int sys_getdomainname(char __
1925         
1926         down_read(&uts_sem);
1927         
1928 -       nlen = strlen(system_utsname.domainname) + 1;
1929 +       nlen = strlen(vx_new_uts(domainname)) + 1;
1930  
1931         if (nlen < len)
1932                 len = nlen;
1933         if (len > __NEW_UTS_LEN)
1934                 goto done;
1935 -       if (copy_to_user(name, system_utsname.domainname, len))
1936 +       if (copy_to_user(name, vx_new_uts(domainname), len))
1937                 goto done;
1938         err = 0;
1939  done:
1940 diff -NurpP --minimal linux-2.6.17.11/arch/sparc/kernel/sys_sunos.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/sys_sunos.c
1941 --- linux-2.6.17.11/arch/sparc/kernel/sys_sunos.c       2006-02-15 13:54:13 +0100
1942 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/sys_sunos.c  2006-07-09 17:06:48 +0200
1943 @@ -35,6 +35,7 @@
1944  #include <linux/smp.h>
1945  #include <linux/smp_lock.h>
1946  #include <linux/syscalls.h>
1947 +#include <linux/vs_cvirt.h>
1948  
1949  #include <net/sock.h>
1950  
1951 @@ -482,14 +483,16 @@ struct sunos_utsname {
1952  asmlinkage int sunos_uname(struct sunos_utsname __user *name)
1953  {
1954         int ret;
1955 +       struct new_utsname *ptr;
1956         down_read(&uts_sem);
1957 -       ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1);
1958 +       ptr = vx_new_utsname();
1959 +       ret = copy_to_user(&name->sname[0], ptr->sysname, sizeof(name->sname) - 1);
1960         if (!ret) {
1961 -               ret |= __copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1);
1962 +               ret |= __copy_to_user(&name->nname[0], ptr->nodename, sizeof(name->nname) - 1);
1963                 ret |= __put_user('\0', &name->nname[8]);
1964 -               ret |= __copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1);
1965 -               ret |= __copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1);
1966 -               ret |= __copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1);
1967 +               ret |= __copy_to_user(&name->rel[0], ptr->release, sizeof(name->rel) - 1);
1968 +               ret |= __copy_to_user(&name->ver[0], ptr->version, sizeof(name->ver) - 1);
1969 +               ret |= __copy_to_user(&name->mach[0], ptr->machine, sizeof(name->mach) - 1);
1970         }
1971         up_read(&uts_sem);
1972         return ret ? -EFAULT : 0;
1973 diff -NurpP --minimal linux-2.6.17.11/arch/sparc/kernel/systbls.S linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/systbls.S
1974 --- linux-2.6.17.11/arch/sparc/kernel/systbls.S 2006-06-18 04:52:34 +0200
1975 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/systbls.S    2006-07-09 17:06:48 +0200
1976 @@ -72,7 +72,7 @@ sys_call_table:
1977  /*250*/        .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
1978  /*255*/        .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
1979  /*260*/        .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
1980 -/*265*/        .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
1981 +/*265*/        .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
1982  /*270*/        .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
1983  /*275*/        .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
1984  /*280*/        .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
1985 diff -NurpP --minimal linux-2.6.17.11/arch/sparc/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/traps.c
1986 --- linux-2.6.17.11/arch/sparc/kernel/traps.c   2006-01-18 06:07:57 +0100
1987 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc/kernel/traps.c      2006-07-09 17:06:48 +0200
1988 @@ -100,7 +100,8 @@ void die_if_kernel(char *str, struct pt_
1989  "              /_| \\__/ |_\\\n"
1990  "                 \\__U_/\n");
1991  
1992 -       printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
1993 +       printk("%s(%d[#%u]): %s [#%d]\n", current->comm,
1994 +               current->pid, current->xid, str, ++die_counter);
1995         show_regs(regs);
1996  
1997         __SAVE; __SAVE; __SAVE; __SAVE;
1998 diff -NurpP --minimal linux-2.6.17.11/arch/sparc64/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/Kconfig
1999 --- linux-2.6.17.11/arch/sparc64/Kconfig        2006-06-18 04:52:34 +0200
2000 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/Kconfig   2006-07-09 17:06:48 +0200
2001 @@ -423,6 +423,8 @@ endmenu
2002  
2003  source "arch/sparc64/Kconfig.debug"
2004  
2005 +source "kernel/vserver/Kconfig"
2006 +
2007  source "security/Kconfig"
2008  
2009  source "crypto/Kconfig"
2010 diff -NurpP --minimal linux-2.6.17.11/arch/sparc64/kernel/binfmt_aout32.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/binfmt_aout32.c
2011 --- linux-2.6.17.11/arch/sparc64/kernel/binfmt_aout32.c 2006-06-18 04:52:34 +0200
2012 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/binfmt_aout32.c    2006-07-09 17:06:48 +0200
2013 @@ -27,6 +27,7 @@
2014  #include <linux/binfmts.h>
2015  #include <linux/personality.h>
2016  #include <linux/init.h>
2017 +#include <linux/vs_memory.h>
2018  
2019  #include <asm/system.h>
2020  #include <asm/uaccess.h>
2021 diff -NurpP --minimal linux-2.6.17.11/arch/sparc64/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/process.c
2022 --- linux-2.6.17.11/arch/sparc64/kernel/process.c       2006-06-18 04:52:35 +0200
2023 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/process.c  2006-07-09 17:06:48 +0200
2024 @@ -698,7 +698,8 @@ pid_t kernel_thread(int (*fn)(void *), v
2025                              /* Notreached by child. */
2026                              "1:" :
2027                              "=r" (retval) :
2028 -                            "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED),
2029 +                            "i" (__NR_clone), "r" (flags |
2030 +                               CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD),
2031                              "i" (__NR_exit),  "r" (fn), "r" (arg) :
2032                              "g1", "g2", "g3", "o0", "o1", "memory", "cc");
2033         return retval;
2034 diff -NurpP --minimal linux-2.6.17.11/arch/sparc64/kernel/ptrace.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/ptrace.c
2035 --- linux-2.6.17.11/arch/sparc64/kernel/ptrace.c        2006-06-18 04:52:35 +0200
2036 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/ptrace.c   2006-08-06 06:01:34 +0200
2037 @@ -22,6 +22,7 @@
2038  #include <linux/seccomp.h>
2039  #include <linux/audit.h>
2040  #include <linux/signal.h>
2041 +#include <linux/vs_pid.h>
2042  
2043  #include <asm/asi.h>
2044  #include <asm/pgtable.h>
2045 @@ -212,6 +213,10 @@ asmlinkage void do_ptrace(struct pt_regs
2046                 pt_error_return(regs, -ret);
2047                 goto out;
2048         }
2049 +       if (!vx_check(vx_task_xid(child), VX_WATCH_P|VX_IDENT)) {
2050 +               pt_error_return(regs, ESRCH);
2051 +               goto out_tsk;
2052 +       }
2053  
2054         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
2055             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
2056 diff -NurpP --minimal linux-2.6.17.11/arch/sparc64/kernel/sys_sparc.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/sys_sparc.c
2057 --- linux-2.6.17.11/arch/sparc64/kernel/sys_sparc.c     2006-08-25 00:25:37 +0200
2058 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/sys_sparc.c        2006-08-25 00:12:52 +0200
2059 @@ -26,6 +26,7 @@
2060  #include <linux/ipc.h>
2061  #include <linux/personality.h>
2062  #include <linux/random.h>
2063 +#include <linux/vs_cvirt.h>
2064  
2065  #include <asm/uaccess.h>
2066  #include <asm/ipc.h>
2067 @@ -711,13 +712,13 @@ asmlinkage long sys_getdomainname(char _
2068  
2069         down_read(&uts_sem);
2070         
2071 -       nlen = strlen(system_utsname.domainname) + 1;
2072 +       nlen = strlen(vx_new_uts(domainname)) + 1;
2073  
2074          if (nlen < len)
2075                  len = nlen;
2076         if (len > __NEW_UTS_LEN)
2077                 goto done;
2078 -       if (copy_to_user(name, system_utsname.domainname, len))
2079 +       if (copy_to_user(name, vx_new_uts(domainname), len))
2080                 goto done;
2081         err = 0;
2082  done:
2083 diff -NurpP --minimal linux-2.6.17.11/arch/sparc64/kernel/sys_sparc32.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/sys_sparc32.c
2084 --- linux-2.6.17.11/arch/sparc64/kernel/sys_sparc32.c   2006-06-18 04:52:35 +0200
2085 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/sys_sparc32.c      2006-07-09 17:06:48 +0200
2086 @@ -788,7 +788,7 @@ asmlinkage long sys32_gettimeofday(struc
2087  {
2088         if (tv) {
2089                 struct timeval ktv;
2090 -               do_gettimeofday(&ktv);
2091 +               vx_gettimeofday(&ktv);
2092                 if (put_tv32(tv, &ktv))
2093                         return -EFAULT;
2094         }
2095 diff -NurpP --minimal linux-2.6.17.11/arch/sparc64/kernel/sys_sunos32.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/sys_sunos32.c
2096 --- linux-2.6.17.11/arch/sparc64/kernel/sys_sunos32.c   2006-02-15 13:54:13 +0100
2097 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/sys_sunos32.c      2006-07-09 17:06:48 +0200
2098 @@ -35,6 +35,7 @@
2099  #include <linux/smp.h>
2100  #include <linux/smp_lock.h>
2101  #include <linux/syscalls.h>
2102 +#include <linux/vs_cvirt.h>
2103  
2104  #include <asm/uaccess.h>
2105  #include <asm/page.h>
2106 @@ -437,18 +438,20 @@ struct sunos_utsname {
2107  asmlinkage int sunos_uname(struct sunos_utsname __user *name)
2108  {
2109         int ret;
2110 +       struct new_utsname *ptr;
2111  
2112         down_read(&uts_sem);
2113 -       ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0],
2114 +       ptr = vx_new_utsname();
2115 +       ret = copy_to_user(&name->sname[0], ptr->sysname,
2116                            sizeof(name->sname) - 1);
2117 -       ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0],
2118 +       ret |= copy_to_user(&name->nname[0], ptr->nodename,
2119                             sizeof(name->nname) - 1);
2120         ret |= put_user('\0', &name->nname[8]);
2121 -       ret |= copy_to_user(&name->rel[0], &system_utsname.release[0],
2122 +       ret |= copy_to_user(&name->rel[0], ptr->release,
2123                             sizeof(name->rel) - 1);
2124 -       ret |= copy_to_user(&name->ver[0], &system_utsname.version[0],
2125 +       ret |= copy_to_user(&name->ver[0], ptr->version,
2126                             sizeof(name->ver) - 1);
2127 -       ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0],
2128 +       ret |= copy_to_user(&name->mach[0], ptr->machine,
2129                             sizeof(name->mach) - 1);
2130         up_read(&uts_sem);
2131         return (ret ? -EFAULT : 0);
2132 diff -NurpP --minimal linux-2.6.17.11/arch/sparc64/kernel/systbls.S linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/systbls.S
2133 --- linux-2.6.17.11/arch/sparc64/kernel/systbls.S       2006-06-18 04:52:35 +0200
2134 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/systbls.S  2006-07-09 17:06:48 +0200
2135 @@ -73,7 +73,7 @@ sys_call_table32:
2136  /*250*/        .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
2137         .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
2138  /*260*/        .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
2139 -       .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
2140 +       .word sys_timer_delete, compat_sys_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy
2141  /*270*/        .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
2142         .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
2143  /*280*/        .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
2144 @@ -143,7 +143,7 @@ sys_call_table:
2145  /*250*/        .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
2146         .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
2147  /*260*/        .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
2148 -       .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
2149 +       .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
2150  /*270*/        .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
2151         .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
2152  /*280*/        .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
2153 diff -NurpP --minimal linux-2.6.17.11/arch/sparc64/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/traps.c
2154 --- linux-2.6.17.11/arch/sparc64/kernel/traps.c 2006-06-18 04:52:36 +0200
2155 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/kernel/traps.c    2006-07-09 17:06:48 +0200
2156 @@ -2214,7 +2214,8 @@ void die_if_kernel(char *str, struct pt_
2157  "              /_| \\__/ |_\\\n"
2158  "                 \\__U_/\n");
2159  
2160 -       printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
2161 +       printk("%s(%d[#%u]): %s [#%d]\n", current->comm,
2162 +               current->pid, current->xid, str, ++die_counter);
2163         notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
2164         __asm__ __volatile__("flushw");
2165         __show_regs(regs);
2166 diff -NurpP --minimal linux-2.6.17.11/arch/sparc64/solaris/fs.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/solaris/fs.c
2167 --- linux-2.6.17.11/arch/sparc64/solaris/fs.c   2006-04-09 13:49:44 +0200
2168 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/solaris/fs.c      2006-07-09 17:06:48 +0200
2169 @@ -363,7 +363,7 @@ static int report_statvfs(struct vfsmoun
2170                 int j = strlen (p);
2171                 
2172                 if (j > 15) j = 15;
2173 -               if (IS_RDONLY(inode)) i = 1;
2174 +               if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
2175                 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
2176                 if (!sysv_valid_dev(inode->i_sb->s_dev))
2177                         return -EOVERFLOW;
2178 @@ -399,7 +399,7 @@ static int report_statvfs64(struct vfsmo
2179                 int j = strlen (p);
2180                 
2181                 if (j > 15) j = 15;
2182 -               if (IS_RDONLY(inode)) i = 1;
2183 +               if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
2184                 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
2185                 if (!sysv_valid_dev(inode->i_sb->s_dev))
2186                         return -EOVERFLOW;
2187 diff -NurpP --minimal linux-2.6.17.11/arch/sparc64/solaris/misc.c linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/solaris/misc.c
2188 --- linux-2.6.17.11/arch/sparc64/solaris/misc.c 2006-06-18 04:52:36 +0200
2189 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/sparc64/solaris/misc.c    2006-07-09 17:06:48 +0200
2190 @@ -17,6 +17,7 @@
2191  #include <linux/timex.h>
2192  #include <linux/major.h>
2193  #include <linux/compat.h>
2194 +#include <linux/vs_cvirt.h>
2195  
2196  #include <asm/uaccess.h>
2197  #include <asm/string.h>
2198 @@ -239,7 +240,7 @@ asmlinkage int solaris_utssys(u32 buf, u
2199                 /* Let's cheat */
2200                 err  = set_utsfield(v->sysname, "SunOS", 1, 0);
2201                 down_read(&uts_sem);
2202 -               err |= set_utsfield(v->nodename, system_utsname.nodename,
2203 +               err |= set_utsfield(v->nodename, vx_new_uts(nodename),
2204                                     1, 1);
2205                 up_read(&uts_sem);
2206                 err |= set_utsfield(v->release, "2.6", 0, 0);
2207 @@ -263,7 +264,7 @@ asmlinkage int solaris_utsname(u32 buf)
2208         /* Why should we not lie a bit? */
2209         down_read(&uts_sem);
2210         err  = set_utsfield(v->sysname, "SunOS", 0, 0);
2211 -       err |= set_utsfield(v->nodename, system_utsname.nodename, 1, 1);
2212 +       err |= set_utsfield(v->nodename, vx_new_uts(nodename), 1, 1);
2213         err |= set_utsfield(v->release, "5.6", 0, 0);
2214         err |= set_utsfield(v->version, "Generic", 0, 0);
2215         err |= set_utsfield(v->machine, machine(), 0, 0);
2216 @@ -295,7 +296,7 @@ asmlinkage int solaris_sysinfo(int cmd, 
2217         case SI_HOSTNAME:
2218                 r = buffer + 256;
2219                 down_read(&uts_sem);
2220 -               for (p = system_utsname.nodename, q = buffer; 
2221 +               for (p = vx_new_uts(nodename), q = buffer;
2222                      q < r && *p && *p != '.'; *q++ = *p++);
2223                 up_read(&uts_sem);
2224                 *q = 0;
2225 diff -NurpP --minimal linux-2.6.17.11/arch/um/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/um/Kconfig
2226 --- linux-2.6.17.11/arch/um/Kconfig     2006-06-18 04:52:36 +0200
2227 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/um/Kconfig        2006-07-09 17:06:48 +0200
2228 @@ -279,6 +279,8 @@ source "drivers/connector/Kconfig"
2229  
2230  source "fs/Kconfig"
2231  
2232 +source "kernel/vserver/Kconfig"
2233 +
2234  source "security/Kconfig"
2235  
2236  source "crypto/Kconfig"
2237 diff -NurpP --minimal linux-2.6.17.11/arch/um/drivers/mconsole_kern.c linux-2.6.17.11-vs2.1.1-rc31/arch/um/drivers/mconsole_kern.c
2238 --- linux-2.6.17.11/arch/um/drivers/mconsole_kern.c     2006-06-18 04:52:37 +0200
2239 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/um/drivers/mconsole_kern.c        2006-07-09 17:06:48 +0200
2240 @@ -23,6 +23,7 @@
2241  #include "linux/list.h"
2242  #include "linux/mm.h"
2243  #include "linux/console.h"
2244 +#include "linux/vs_pid.h"
2245  #include "asm/irq.h"
2246  #include "asm/uaccess.h"
2247  #include "user_util.h"
2248 diff -NurpP --minimal linux-2.6.17.11/arch/um/kernel/process_kern.c linux-2.6.17.11-vs2.1.1-rc31/arch/um/kernel/process_kern.c
2249 --- linux-2.6.17.11/arch/um/kernel/process_kern.c       2006-06-18 04:52:38 +0200
2250 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/um/kernel/process_kern.c  2006-08-17 01:24:55 +0200
2251 @@ -23,6 +23,8 @@
2252  #include "linux/proc_fs.h"
2253  #include "linux/ptrace.h"
2254  #include "linux/random.h"
2255 +#include "linux/vs_pid.h"
2256 +
2257  #include "asm/unistd.h"
2258  #include "asm/mman.h"
2259  #include "asm/segment.h"
2260 @@ -95,7 +97,7 @@ int kernel_thread(int (*fn)(void *), voi
2261  
2262         current->thread.request.u.thread.proc = fn;
2263         current->thread.request.u.thread.arg = arg;
2264 -       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
2265 +       pid = do_fork(CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD | flags, 0,
2266                       &current->thread.regs, 0, NULL, NULL);
2267         if(pid < 0)
2268                 panic("do_fork failed in kernel_thread, errno = %d", pid);
2269 diff -NurpP --minimal linux-2.6.17.11/arch/um/kernel/syscall_kern.c linux-2.6.17.11-vs2.1.1-rc31/arch/um/kernel/syscall_kern.c
2270 --- linux-2.6.17.11/arch/um/kernel/syscall_kern.c       2006-06-18 04:52:38 +0200
2271 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/um/kernel/syscall_kern.c  2006-07-09 17:06:48 +0200
2272 @@ -15,6 +15,8 @@
2273  #include "linux/unistd.h"
2274  #include "linux/slab.h"
2275  #include "linux/utime.h"
2276 +#include <linux/vs_cvirt.h>
2277 +
2278  #include "asm/mman.h"
2279  #include "asm/uaccess.h"
2280  #include "kern_util.h"
2281 @@ -110,7 +112,7 @@ long sys_uname(struct old_utsname __user
2282         if (!name)
2283                 return -EFAULT;
2284         down_read(&uts_sem);
2285 -       err=copy_to_user(name, &system_utsname, sizeof (*name));
2286 +       err=copy_to_user(name, vx_new_utsname(), sizeof (*name));
2287         up_read(&uts_sem);
2288         return err?-EFAULT:0;
2289  }
2290 @@ -118,6 +120,7 @@ long sys_uname(struct old_utsname __user
2291  long sys_olduname(struct oldold_utsname __user * name)
2292  {
2293         long error;
2294 +       struct new_utsname *ptr;
2295  
2296         if (!name)
2297                 return -EFAULT;
2298 @@ -126,19 +129,20 @@ long sys_olduname(struct oldold_utsname 
2299    
2300         down_read(&uts_sem);
2301         
2302 -       error = __copy_to_user(&name->sysname,&system_utsname.sysname,
2303 +       ptr = vx_new_utsname();
2304 +       error = __copy_to_user(&name->sysname,ptr->sysname,
2305                                __OLD_UTS_LEN);
2306         error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
2307 -       error |= __copy_to_user(&name->nodename,&system_utsname.nodename,
2308 +       error |= __copy_to_user(&name->nodename,ptr->nodename,
2309                                 __OLD_UTS_LEN);
2310         error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
2311 -       error |= __copy_to_user(&name->release,&system_utsname.release,
2312 +       error |= __copy_to_user(&name->release,ptr->release,
2313                                 __OLD_UTS_LEN);
2314         error |= __put_user(0,name->release+__OLD_UTS_LEN);
2315 -       error |= __copy_to_user(&name->version,&system_utsname.version,
2316 +       error |= __copy_to_user(&name->version,ptr->version,
2317                                 __OLD_UTS_LEN);
2318         error |= __put_user(0,name->version+__OLD_UTS_LEN);
2319 -       error |= __copy_to_user(&name->machine,&system_utsname.machine,
2320 +       error |= __copy_to_user(&name->machine,ptr->machine,
2321                                 __OLD_UTS_LEN);
2322         error |= __put_user(0,name->machine+__OLD_UTS_LEN);
2323         
2324 diff -NurpP --minimal linux-2.6.17.11/arch/um/sys-x86_64/syscalls.c linux-2.6.17.11-vs2.1.1-rc31/arch/um/sys-x86_64/syscalls.c
2325 --- linux-2.6.17.11/arch/um/sys-x86_64/syscalls.c       2006-06-18 04:52:42 +0200
2326 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/um/sys-x86_64/syscalls.c  2006-07-09 17:06:48 +0200
2327 @@ -9,6 +9,7 @@
2328  #include "linux/shm.h"
2329  #include "linux/utsname.h"
2330  #include "linux/personality.h"
2331 +#include "linux/vs_cvirt.h"
2332  #include "asm/uaccess.h"
2333  #define __FRAME_OFFSETS
2334  #include "asm/ptrace.h"
2335 @@ -21,7 +22,7 @@ asmlinkage long sys_uname64(struct new_u
2336  {
2337         int err;
2338         down_read(&uts_sem);
2339 -       err = copy_to_user(name, &system_utsname, sizeof (*name));
2340 +       err = copy_to_user(name, vx_new_utsname(), sizeof (*name));
2341         up_read(&uts_sem);
2342         if (personality(current->personality) == PER_LINUX32)
2343                 err |= copy_to_user(&name->machine, "i686", 5);
2344 diff -NurpP --minimal linux-2.6.17.11/arch/v850/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/v850/Kconfig
2345 --- linux-2.6.17.11/arch/v850/Kconfig   2006-06-18 04:52:42 +0200
2346 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/v850/Kconfig      2006-07-09 17:06:48 +0200
2347 @@ -326,6 +326,8 @@ source "drivers/usb/Kconfig"
2348  
2349  source "arch/v850/Kconfig.debug"
2350  
2351 +source "kernel/vserver/Kconfig"
2352 +
2353  source "security/Kconfig"
2354  
2355  source "crypto/Kconfig"
2356 diff -NurpP --minimal linux-2.6.17.11/arch/v850/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/v850/kernel/process.c
2357 --- linux-2.6.17.11/arch/v850/kernel/process.c  2006-06-18 04:52:43 +0200
2358 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/v850/kernel/process.c     2006-07-09 17:06:48 +0200
2359 @@ -84,7 +84,7 @@ int kernel_thread (int (*fn)(void *), vo
2360         /* Clone this thread.  Note that we don't pass the clone syscall's
2361            second argument -- it's ignored for calls from kernel mode (the
2362            child's SP is always set to the top of the kernel stack).  */
2363 -       arg0 = flags | CLONE_VM;
2364 +       arg0 = flags | CLONE_VM | CLONE_KTHREAD;
2365         syscall = __NR_clone;
2366         asm volatile ("trap " SYSCALL_SHORT_TRAP
2367                       : "=r" (ret), "=r" (syscall)
2368 diff -NurpP --minimal linux-2.6.17.11/arch/v850/kernel/ptrace.c linux-2.6.17.11-vs2.1.1-rc31/arch/v850/kernel/ptrace.c
2369 --- linux-2.6.17.11/arch/v850/kernel/ptrace.c   2006-04-09 13:49:44 +0200
2370 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/v850/kernel/ptrace.c      2006-08-06 06:01:44 +0200
2371 @@ -117,6 +117,9 @@ long arch_ptrace(struct task_struct *chi
2372  {
2373         int rval;
2374  
2375 +       if (!vx_check(vx_task_xid(child), VX_WATCH_P|VX_IDENT))
2376 +               goto out;
2377 +
2378         switch (request) {
2379                 unsigned long val, copied;
2380  
2381 diff -NurpP --minimal linux-2.6.17.11/arch/x86_64/Kconfig linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/Kconfig
2382 --- linux-2.6.17.11/arch/x86_64/Kconfig 2006-08-25 00:25:37 +0200
2383 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/Kconfig    2006-07-26 21:36:47 +0200
2384 @@ -617,6 +617,8 @@ endmenu
2385  
2386  source "arch/x86_64/Kconfig.debug"
2387  
2388 +source "kernel/vserver/Kconfig"
2389 +
2390  source "security/Kconfig"
2391  
2392  source "crypto/Kconfig"
2393 diff -NurpP --minimal linux-2.6.17.11/arch/x86_64/ia32/ia32_aout.c linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/ia32_aout.c
2394 --- linux-2.6.17.11/arch/x86_64/ia32/ia32_aout.c        2006-01-03 17:29:20 +0100
2395 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/ia32_aout.c   2006-07-09 17:06:48 +0200
2396 @@ -25,6 +25,7 @@
2397  #include <linux/binfmts.h>
2398  #include <linux/personality.h>
2399  #include <linux/init.h>
2400 +#include <linux/vs_memory.h>
2401  
2402  #include <asm/system.h>
2403  #include <asm/uaccess.h>
2404 diff -NurpP --minimal linux-2.6.17.11/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/ia32_binfmt.c
2405 --- linux-2.6.17.11/arch/x86_64/ia32/ia32_binfmt.c      2006-06-18 04:52:43 +0200
2406 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/ia32_binfmt.c 2006-07-09 17:06:48 +0200
2407 @@ -371,7 +371,8 @@ int ia32_setup_arg_pages(struct linux_bi
2408                         kmem_cache_free(vm_area_cachep, mpnt);
2409                         return ret;
2410                 }
2411 -               mm->stack_vm = mm->total_vm = vma_pages(mpnt);
2412 +               vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
2413 +               mm->stack_vm = mm->total_vm;
2414         } 
2415  
2416         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
2417 diff -NurpP --minimal linux-2.6.17.11/arch/x86_64/ia32/ia32entry.S linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/ia32entry.S
2418 --- linux-2.6.17.11/arch/x86_64/ia32/ia32entry.S        2006-06-18 04:52:43 +0200
2419 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/ia32entry.S   2006-07-09 17:06:48 +0200
2420 @@ -652,7 +652,7 @@ ia32_sys_call_table:
2421         .quad sys_tgkill                /* 270 */
2422         .quad compat_sys_utimes
2423         .quad sys32_fadvise64_64
2424 -       .quad quiet_ni_syscall  /* sys_vserver */
2425 +       .quad sys32_vserver
2426         .quad sys_mbind
2427         .quad compat_sys_get_mempolicy  /* 275 */
2428         .quad sys_set_mempolicy
2429 diff -NurpP --minimal linux-2.6.17.11/arch/x86_64/ia32/ptrace32.c linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/ptrace32.c
2430 --- linux-2.6.17.11/arch/x86_64/ia32/ptrace32.c 2006-01-18 06:07:58 +0100
2431 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/ptrace32.c    2006-07-09 17:06:48 +0200
2432 @@ -18,6 +18,7 @@
2433  #include <linux/unistd.h>
2434  #include <linux/mm.h>
2435  #include <linux/ptrace.h>
2436 +#include <linux/vs_pid.h>
2437  #include <asm/ptrace.h>
2438  #include <asm/compat.h>
2439  #include <asm/uaccess.h>
2440 diff -NurpP --minimal linux-2.6.17.11/arch/x86_64/ia32/sys_ia32.c linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/sys_ia32.c
2441 --- linux-2.6.17.11/arch/x86_64/ia32/sys_ia32.c 2006-06-18 04:52:43 +0200
2442 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/sys_ia32.c    2006-07-09 17:06:48 +0200
2443 @@ -61,6 +61,7 @@
2444  #include <linux/highuid.h>
2445  #include <linux/vmalloc.h>
2446  #include <linux/fsnotify.h>
2447 +#include <linux/vs_cvirt.h>
2448  #include <asm/mman.h>
2449  #include <asm/types.h>
2450  #include <asm/uaccess.h>
2451 @@ -447,7 +448,7 @@ sys32_gettimeofday(struct compat_timeval
2452  {
2453         if (tv) {
2454                 struct timeval ktv;
2455 -               do_gettimeofday(&ktv);
2456 +               vx_gettimeofday(&ktv);
2457                 if (put_tv32(tv, &ktv))
2458                         return -EFAULT;
2459         }
2460 @@ -793,6 +794,7 @@ asmlinkage long sys32_mmap2(unsigned lon
2461  asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
2462  {
2463         int error;
2464 +       struct new_utsname *ptr;
2465  
2466         if (!name)
2467                 return -EFAULT;
2468 @@ -801,13 +803,14 @@ asmlinkage long sys32_olduname(struct ol
2469    
2470         down_read(&uts_sem);
2471         
2472 -       error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
2473 +       ptr = vx_new_utsname();
2474 +       error = __copy_to_user(&name->sysname,ptr->sysname,__OLD_UTS_LEN);
2475          __put_user(0,name->sysname+__OLD_UTS_LEN);
2476 -        __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
2477 +        __copy_to_user(&name->nodename,ptr->nodename,__OLD_UTS_LEN);
2478          __put_user(0,name->nodename+__OLD_UTS_LEN);
2479 -        __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
2480 +        __copy_to_user(&name->release,ptr->release,__OLD_UTS_LEN);
2481          __put_user(0,name->release+__OLD_UTS_LEN);
2482 -        __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
2483 +        __copy_to_user(&name->version,ptr->version,__OLD_UTS_LEN);
2484          __put_user(0,name->version+__OLD_UTS_LEN);
2485          { 
2486                  char *arch = "x86_64";
2487 @@ -830,7 +833,7 @@ long sys32_uname(struct old_utsname __us
2488         if (!name)
2489                 return -EFAULT;
2490         down_read(&uts_sem);
2491 -       err=copy_to_user(name, &system_utsname, sizeof (*name));
2492 +       err=copy_to_user(name, vx_new_utsname(), sizeof (*name));
2493         up_read(&uts_sem);
2494         if (personality(current->personality) == PER_LINUX32) 
2495                 err |= copy_to_user(&name->machine, "i686", 5);
2496 diff -NurpP --minimal linux-2.6.17.11/arch/x86_64/ia32/syscall32.c linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/syscall32.c
2497 --- linux-2.6.17.11/arch/x86_64/ia32/syscall32.c        2005-10-28 20:49:18 +0200
2498 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/ia32/syscall32.c   2006-07-09 17:06:48 +0200
2499 @@ -10,6 +10,7 @@
2500  #include <linux/init.h>
2501  #include <linux/stringify.h>
2502  #include <linux/security.h>
2503 +#include <linux/vs_memory.h>
2504  #include <asm/proto.h>
2505  #include <asm/tlbflush.h>
2506  #include <asm/ia32_unistd.h>
2507 @@ -70,7 +71,7 @@ int syscall32_setup_pages(struct linux_b
2508                 kmem_cache_free(vm_area_cachep, vma);
2509                 return ret;
2510         }
2511 -       mm->total_vm += npages;
2512 +       vx_vmpages_add(mm, npages);
2513         up_write(&mm->mmap_sem);
2514         return 0;
2515  }
2516 diff -NurpP --minimal linux-2.6.17.11/arch/x86_64/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/kernel/process.c
2517 --- linux-2.6.17.11/arch/x86_64/kernel/process.c        2006-06-18 04:52:44 +0200
2518 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/kernel/process.c   2006-07-09 17:06:48 +0200
2519 @@ -55,7 +55,8 @@
2520  
2521  asmlinkage extern void ret_from_fork(void);
2522  
2523 -unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
2524 +unsigned long kernel_thread_flags =
2525 +       CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
2526  
2527  unsigned long boot_option_idle_override = 0;
2528  EXPORT_SYMBOL(boot_option_idle_override);
2529 @@ -290,8 +291,8 @@ void __show_regs(struct pt_regs * regs)
2530  
2531         printk("\n");
2532         print_modules();
2533 -       printk("Pid: %d, comm: %.20s %s %s %.*s\n",
2534 -               current->pid, current->comm, print_tainted(),
2535 +       printk("Pid: %d[#%u], comm: %.20s %s %s %.*s\n",
2536 +               current->pid, current->xid, current->comm, print_tainted(),
2537                 system_utsname.release,
2538                 (int)strcspn(system_utsname.version, " "),
2539                 system_utsname.version);
2540 diff -NurpP --minimal linux-2.6.17.11/arch/x86_64/kernel/sys_x86_64.c linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/kernel/sys_x86_64.c
2541 --- linux-2.6.17.11/arch/x86_64/kernel/sys_x86_64.c     2006-01-03 17:29:20 +0100
2542 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/kernel/sys_x86_64.c        2006-07-09 17:06:48 +0200
2543 @@ -16,6 +16,7 @@
2544  #include <linux/file.h>
2545  #include <linux/utsname.h>
2546  #include <linux/personality.h>
2547 +#include <linux/vs_cvirt.h>
2548  
2549  #include <asm/uaccess.h>
2550  #include <asm/ia32.h>
2551 @@ -148,7 +149,7 @@ asmlinkage long sys_uname(struct new_uts
2552  {
2553         int err;
2554         down_read(&uts_sem);
2555 -       err = copy_to_user(name, &system_utsname, sizeof (*name));
2556 +       err = copy_to_user(name, vx_new_utsname(), sizeof (*name));
2557         up_read(&uts_sem);
2558         if (personality(current->personality) == PER_LINUX32) 
2559                 err |= copy_to_user(&name->machine, "i686", 5);                 
2560 diff -NurpP --minimal linux-2.6.17.11/arch/x86_64/kernel/traps.c linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/kernel/traps.c
2561 --- linux-2.6.17.11/arch/x86_64/kernel/traps.c  2006-06-18 04:52:44 +0200
2562 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/x86_64/kernel/traps.c     2006-07-09 17:06:48 +0200
2563 @@ -324,8 +324,9 @@ void show_registers(struct pt_regs *regs
2564  
2565         printk("CPU %d ", cpu);
2566         __show_regs(regs);
2567 -       printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
2568 -               cur->comm, cur->pid, task_thread_info(cur), cur);
2569 +       printk("Process %s (pid: %d[#%u], threadinfo %p, task %p)\n",
2570 +               cur->comm, cur->pid, cur->xid,
2571 +               task_thread_info(cur), cur);
2572  
2573         /*
2574          * When in-kernel, we also print out the stack and code at the
2575 diff -NurpP --minimal linux-2.6.17.11/arch/xtensa/kernel/process.c linux-2.6.17.11-vs2.1.1-rc31/arch/xtensa/kernel/process.c
2576 --- linux-2.6.17.11/arch/xtensa/kernel/process.c        2006-04-09 13:49:44 +0200
2577 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/xtensa/kernel/process.c   2006-07-09 17:06:48 +0200
2578 @@ -207,7 +207,7 @@ int kernel_thread(int (*fn)(void *), voi
2579                  :"=r" (retval)
2580                  :"i" (__NR_clone), "i" (__NR_exit),
2581                  "r" (arg), "r" (fn),
2582 -                "r" (flags | CLONE_VM)
2583 +                "r" (flags | CLONE_VM | CLONE_KTHREAD)
2584                  : "a2", "a3", "a4", "a5", "a6" );
2585         return retval;
2586  }
2587 diff -NurpP --minimal linux-2.6.17.11/arch/xtensa/kernel/syscalls.c linux-2.6.17.11-vs2.1.1-rc31/arch/xtensa/kernel/syscalls.c
2588 --- linux-2.6.17.11/arch/xtensa/kernel/syscalls.c       2005-08-29 22:24:57 +0200
2589 +++ linux-2.6.17.11-vs2.1.1-rc31/arch/xtensa/kernel/syscalls.c  2006-07-09 17:06:48 +0200
2590 @@ -35,6 +35,7 @@
2591  #include <linux/msg.h>
2592  #include <linux/shm.h>
2593  #include <linux/errno.h>
2594 +#include <linux/vs_cvirt.h>
2595  #include <asm/ptrace.h>
2596  #include <asm/signal.h>
2597  #include <asm/uaccess.h>
2598 @@ -129,7 +130,7 @@ out:
2599  
2600  int sys_uname(struct old_utsname * name)
2601  {
2602 -       if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
2603 +       if (name && !copy_to_user(name, vx_new_utsname(), sizeof (*name)))
2604                 return 0;
2605         return -EFAULT;
2606  }
2607 diff -NurpP --minimal linux-2.6.17.11/block/cfq-iosched.c linux-2.6.17.11-vs2.1.1-rc31/block/cfq-iosched.c
2608 --- linux-2.6.17.11/block/cfq-iosched.c 2006-06-18 04:52:44 +0200
2609 +++ linux-2.6.17.11-vs2.1.1-rc31/block/cfq-iosched.c    2006-07-09 17:06:48 +0200
2610 @@ -341,6 +341,8 @@ static int cfq_queue_empty(request_queue
2611  
2612  static inline pid_t cfq_queue_pid(struct task_struct *task, int rw)
2613  {
2614 +       if (task->xid)
2615 +               return task->xid + (1 << 16);
2616         if (rw == READ || process_sync(task))
2617                 return task->pid;
2618  
2619 diff -NurpP --minimal linux-2.6.17.11/drivers/block/Kconfig linux-2.6.17.11-vs2.1.1-rc31/drivers/block/Kconfig
2620 --- linux-2.6.17.11/drivers/block/Kconfig       2006-06-18 04:52:46 +0200
2621 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/block/Kconfig  2006-07-09 17:06:48 +0200
2622 @@ -315,6 +315,13 @@ config BLK_DEV_CRYPTOLOOP
2623           instead, which can be configured to be on-disk compatible with the
2624           cryptoloop device.
2625  
2626 +config BLK_DEV_VROOT
2627 +       tristate "Virtual Root device support"
2628 +       depends on QUOTACTL
2629 +       ---help---
2630 +         Saying Y here will allow you to use quota/fs ioctls on a shared
2631 +         partition within a virtual server without compromising security.
2632 +
2633  config BLK_DEV_NBD
2634         tristate "Network block device support"
2635         depends on NET
2636 diff -NurpP --minimal linux-2.6.17.11/drivers/block/Makefile linux-2.6.17.11-vs2.1.1-rc31/drivers/block/Makefile
2637 --- linux-2.6.17.11/drivers/block/Makefile      2006-06-18 04:52:46 +0200
2638 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/block/Makefile 2006-07-09 17:06:48 +0200
2639 @@ -29,4 +29,5 @@ obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryp
2640  obj-$(CONFIG_VIODASD)          += viodasd.o
2641  obj-$(CONFIG_BLK_DEV_SX8)      += sx8.o
2642  obj-$(CONFIG_BLK_DEV_UB)       += ub.o
2643 +obj-$(CONFIG_BLK_DEV_VROOT)    += vroot.o
2644  
2645 diff -NurpP --minimal linux-2.6.17.11/drivers/block/loop.c linux-2.6.17.11-vs2.1.1-rc31/drivers/block/loop.c
2646 --- linux-2.6.17.11/drivers/block/loop.c        2006-06-18 04:52:47 +0200
2647 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/block/loop.c   2006-08-06 06:56:07 +0200
2648 @@ -74,6 +74,7 @@
2649  #include <linux/completion.h>
2650  #include <linux/highmem.h>
2651  #include <linux/gfp.h>
2652 +#include <linux/vs_context.h>
2653  
2654  #include <asm/uaccess.h>
2655  
2656 @@ -743,6 +744,7 @@ static int loop_set_fd(struct loop_devic
2657         struct file     *file, *f;
2658         struct inode    *inode;
2659         struct address_space *mapping;
2660 +       struct vx_info_save vxis;
2661         unsigned lo_blocksize;
2662         int             lo_flags = 0;
2663         int             error;
2664 @@ -817,6 +819,7 @@ static int loop_set_fd(struct loop_devic
2665         lo->lo_blocksize = lo_blocksize;
2666         lo->lo_device = bdev;
2667         lo->lo_flags = lo_flags;
2668 +       lo->lo_xid = vx_current_xid();
2669         lo->lo_backing_file = file;
2670         lo->transfer = NULL;
2671         lo->ioctl = NULL;
2672 @@ -839,7 +842,9 @@ static int loop_set_fd(struct loop_devic
2673  
2674         set_blocksize(bdev, lo_blocksize);
2675  
2676 +       __enter_vx_admin(&vxis);
2677         error = kernel_thread(loop_thread, lo, CLONE_KERNEL);
2678 +       __leave_vx_admin(&vxis);
2679         if (error < 0)
2680                 goto out_putf;
2681         wait_for_completion(&lo->lo_done);
2682 @@ -924,6 +929,7 @@ static int loop_clr_fd(struct loop_devic
2683         lo->lo_sizelimit = 0;
2684         lo->lo_encrypt_key_size = 0;
2685         lo->lo_flags = 0;
2686 +       lo->lo_xid = 0;
2687         memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
2688         memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
2689         memset(lo->lo_file_name, 0, LO_NAME_SIZE);
2690 @@ -945,7 +951,7 @@ loop_set_status(struct loop_device *lo, 
2691         struct loop_func_table *xfer;
2692  
2693         if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
2694 -           !capable(CAP_SYS_ADMIN))
2695 +           !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP))
2696                 return -EPERM;
2697         if (lo->lo_state != Lo_bound)
2698                 return -ENXIO;
2699 @@ -1025,7 +1031,8 @@ loop_get_status(struct loop_device *lo, 
2700         memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
2701         info->lo_encrypt_type =
2702                 lo->lo_encryption ? lo->lo_encryption->number : 0;
2703 -       if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
2704 +       if (lo->lo_encrypt_key_size &&
2705 +               vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) {
2706                 info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
2707                 memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
2708                        lo->lo_encrypt_key_size);
2709 @@ -1180,6 +1187,9 @@ static int lo_open(struct inode *inode, 
2710  {
2711         struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
2712  
2713 +       if (!vx_check(lo->lo_xid, VX_WATCH_P|VX_IDENT))
2714 +               return -EACCES;
2715 +
2716         mutex_lock(&lo->lo_ctl_mutex);
2717         lo->lo_refcnt++;
2718         mutex_unlock(&lo->lo_ctl_mutex);
2719 diff -NurpP --minimal linux-2.6.17.11/drivers/block/vroot.c linux-2.6.17.11-vs2.1.1-rc31/drivers/block/vroot.c
2720 --- linux-2.6.17.11/drivers/block/vroot.c       1970-01-01 01:00:00 +0100
2721 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/block/vroot.c  2006-07-09 17:06:48 +0200
2722 @@ -0,0 +1,288 @@
2723 +/*
2724 + *  linux/drivers/block/vroot.c
2725 + *
2726 + *  written by Herbert Pötzl, 9/11/2002
2727 + *  ported to 2.6.10 by Herbert Pötzl, 30/12/2004
2728 + *
2729 + *  based on the loop.c code by Theodore Ts'o.
2730 + *
2731 + * Copyright (C) 2002-2005 by Herbert Pötzl.
2732 + * Redistribution of this file is permitted under the
2733 + * GNU General Public License.
2734 + *
2735 + */
2736 +
2737 +#include <linux/module.h>
2738 +#include <linux/moduleparam.h>
2739 +#include <linux/file.h>
2740 +#include <linux/major.h>
2741 +#include <linux/blkdev.h>
2742 +#include <linux/devfs_fs_kernel.h>
2743 +
2744 +#include <linux/vroot.h>
2745 +#include <linux/vserver/debug.h>
2746 +
2747 +
2748 +static int max_vroot = 8;
2749 +
2750 +static struct vroot_device *vroot_dev;
2751 +static struct gendisk **disks;
2752 +
2753 +
2754 +static int vroot_set_dev(
2755 +       struct vroot_device *vr,
2756 +       struct file *vr_file,
2757 +       struct block_device *bdev,
2758 +       unsigned int arg)
2759 +{
2760 +       struct block_device *real_bdev;
2761 +       struct file *file;
2762 +       struct inode *inode;
2763 +       int error;
2764 +
2765 +       error = -EBUSY;
2766 +       if (vr->vr_state != Vr_unbound)
2767 +               goto out;
2768 +
2769 +       error = -EBADF;
2770 +       file = fget(arg);
2771 +       if (!file)
2772 +               goto out;
2773 +
2774 +       error = -EINVAL;
2775 +       inode = file->f_dentry->d_inode;
2776 +
2777 +
2778 +       if (S_ISBLK(inode->i_mode)) {
2779 +               real_bdev = inode->i_bdev;
2780 +               vr->vr_device = real_bdev;
2781 +               __iget(real_bdev->bd_inode);
2782 +       } else
2783 +               goto out_fput;
2784 +
2785 +       vxdprintk(VXD_CBIT(misc, 0),
2786 +               "vroot[%d]_set_dev: dev=" VXF_DEV,
2787 +               vr->vr_number, VXD_DEV(real_bdev));
2788 +
2789 +       vr->vr_state = Vr_bound;
2790 +       error = 0;
2791 +
2792 + out_fput:
2793 +       fput(file);
2794 + out:
2795 +       return error;
2796 +}
2797 +
2798 +static int vroot_clr_dev(
2799 +       struct vroot_device *vr,
2800 +       struct file *vr_file,
2801 +       struct block_device *bdev)
2802 +{
2803 +       struct block_device *real_bdev;
2804 +
2805 +       if (vr->vr_state != Vr_bound)
2806 +               return -ENXIO;
2807 +       if (vr->vr_refcnt > 1)  /* we needed one fd for the ioctl */
2808 +               return -EBUSY;
2809 +
2810 +       real_bdev = vr->vr_device;
2811 +
2812 +       vxdprintk(VXD_CBIT(misc, 0),
2813 +               "vroot[%d]_clr_dev: dev=" VXF_DEV,
2814 +               vr->vr_number, VXD_DEV(real_bdev));
2815 +
2816 +       bdput(real_bdev);
2817 +       vr->vr_state = Vr_unbound;
2818 +       vr->vr_device = NULL;
2819 +       return 0;
2820 +}
2821 +
2822 +
2823 +static int vr_ioctl(struct inode * inode, struct file * file,
2824 +       unsigned int cmd, unsigned long arg)
2825 +{
2826 +       struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
2827 +       int err;
2828 +
2829 +       down(&vr->vr_ctl_mutex);
2830 +       switch (cmd) {
2831 +       case VROOT_SET_DEV:
2832 +               err = vroot_set_dev(vr, file, inode->i_bdev, arg);
2833 +               break;
2834 +       case VROOT_CLR_DEV:
2835 +               err = vroot_clr_dev(vr, file, inode->i_bdev);
2836 +               break;
2837 +       default:
2838 +               err = -EINVAL;
2839 +               break;
2840 +       }
2841 +       up(&vr->vr_ctl_mutex);
2842 +       return err;
2843 +}
2844 +
2845 +static int vr_open(struct inode *inode, struct file *file)
2846 +{
2847 +       struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
2848 +
2849 +       down(&vr->vr_ctl_mutex);
2850 +       vr->vr_refcnt++;
2851 +       up(&vr->vr_ctl_mutex);
2852 +       return 0;
2853 +}
2854 +
2855 +static int vr_release(struct inode *inode, struct file *file)
2856 +{
2857 +       struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
2858 +
2859 +       down(&vr->vr_ctl_mutex);
2860 +       --vr->vr_refcnt;
2861 +       up(&vr->vr_ctl_mutex);
2862 +       return 0;
2863 +}
2864 +
2865 +static struct block_device_operations vr_fops = {
2866 +       .owner =        THIS_MODULE,
2867 +       .open =         vr_open,
2868 +       .release =      vr_release,
2869 +       .ioctl =        vr_ioctl,
2870 +};
2871 +
2872 +struct block_device *__vroot_get_real_bdev(struct block_device *bdev)
2873 +{
2874 +       struct inode *inode = bdev->bd_inode;
2875 +       struct vroot_device *vr;
2876 +       struct block_device *real_bdev;
2877 +       int minor = iminor(inode);
2878 +
2879 +       vr = &vroot_dev[minor];
2880 +       real_bdev = vr->vr_device;
2881 +
2882 +       vxdprintk(VXD_CBIT(misc, 0),
2883 +               "vroot[%d]_get_real_bdev: dev=" VXF_DEV,
2884 +               vr->vr_number, VXD_DEV(real_bdev));
2885 +
2886 +       if (vr->vr_state != Vr_bound)
2887 +               return ERR_PTR(-ENXIO);
2888 +
2889 +       __iget(real_bdev->bd_inode);
2890 +       return real_bdev;
2891 +}
2892 +
2893 +/*
2894 + * And now the modules code and kernel interface.
2895 + */
2896 +
2897 +module_param(max_vroot, int, 0);
2898 +
2899 +MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)");
2900 +MODULE_LICENSE("GPL");
2901 +MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR);
2902 +
2903 +MODULE_AUTHOR ("Herbert Pötzl");
2904 +MODULE_DESCRIPTION ("Virtual Root Device Mapper");
2905 +
2906 +
2907 +int __init vroot_init(void)
2908 +{
2909 +       int err, i;
2910 +
2911 +       if (max_vroot < 1 || max_vroot > 256) {
2912 +               max_vroot = MAX_VROOT_DEFAULT;
2913 +               printk(KERN_WARNING "vroot: invalid max_vroot "
2914 +                       "(must be between 1 and 256), "
2915 +                       "using default (%d)\n", max_vroot);
2916 +       }
2917 +
2918 +       if (register_blkdev(VROOT_MAJOR, "vroot"))
2919 +               return -EIO;
2920 +
2921 +       err = -ENOMEM;
2922 +       vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL);
2923 +       if (!vroot_dev)
2924 +               goto out_mem1;
2925 +       memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device));
2926 +
2927 +       disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL);
2928 +       if (!disks)
2929 +               goto out_mem2;
2930 +
2931 +       for (i = 0; i < max_vroot; i++) {
2932 +               disks[i] = alloc_disk(1);
2933 +               if (!disks[i])
2934 +                       goto out_mem3;
2935 +       }
2936 +
2937 +       devfs_mk_dir("vroot");
2938 +
2939 +       for (i = 0; i < max_vroot; i++) {
2940 +               struct vroot_device *vr = &vroot_dev[i];
2941 +               struct gendisk *disk = disks[i];
2942 +
2943 +               memset(vr, 0, sizeof(*vr));
2944 +               init_MUTEX(&vr->vr_ctl_mutex);
2945 +               vr->vr_number = i;
2946 +               disk->major = VROOT_MAJOR;
2947 +               disk->first_minor = i;
2948 +               disk->fops = &vr_fops;
2949 +               sprintf(disk->disk_name, "vroot%d", i);
2950 +               sprintf(disk->devfs_name, "vroot/%d", i);
2951 +               disk->private_data = vr;
2952 +       }
2953 +
2954 +       err = register_vroot_grb(&__vroot_get_real_bdev);
2955 +       if (err)
2956 +               goto out_reg;
2957 +
2958 +       for (i = 0; i < max_vroot; i++)
2959 +               add_disk(disks[i]);
2960 +       printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot);
2961 +       return 0;
2962 +
2963 +out_reg:
2964 +       devfs_remove("vroot");
2965 +out_mem3:
2966 +       while (i--)
2967 +               put_disk(disks[i]);
2968 +       kfree(disks);
2969 +out_mem2:
2970 +       kfree(vroot_dev);
2971 +out_mem1:
2972 +       unregister_blkdev(VROOT_MAJOR, "vroot");
2973 +       printk(KERN_ERR "vroot: ran out of memory\n");
2974 +       return err;
2975 +}
2976 +
2977 +void vroot_exit(void)
2978 +{
2979 +       int i;
2980 +
2981 +       if (unregister_vroot_grb(&__vroot_get_real_bdev))
2982 +               printk(KERN_WARNING "vroot: cannot unregister grb\n");
2983 +
2984 +       for (i = 0; i < max_vroot; i++) {
2985 +               del_gendisk(disks[i]);
2986 +               put_disk(disks[i]);
2987 +       }
2988 +       devfs_remove("vroot");
2989 +       if (unregister_blkdev(VROOT_MAJOR, "vroot"))
2990 +               printk(KERN_WARNING "vroot: cannot unregister blkdev\n");
2991 +
2992 +       kfree(disks);
2993 +       kfree(vroot_dev);
2994 +}
2995 +
2996 +module_init(vroot_init);
2997 +module_exit(vroot_exit);
2998 +
2999 +#ifndef MODULE
3000 +
3001 +static int __init max_vroot_setup(char *str)
3002 +{
3003 +       max_vroot = simple_strtol(str, NULL, 0);
3004 +       return 1;
3005 +}
3006 +
3007 +__setup("max_vroot=", max_vroot_setup);
3008 +
3009 +#endif
3010 +
3011 diff -NurpP --minimal linux-2.6.17.11/drivers/char/random.c linux-2.6.17.11-vs2.1.1-rc31/drivers/char/random.c
3012 --- linux-2.6.17.11/drivers/char/random.c       2006-06-18 04:52:53 +0200
3013 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/char/random.c  2006-07-09 17:06:48 +0200
3014 @@ -1174,7 +1174,7 @@ static char sysctl_bootid[16];
3015  static int proc_do_uuid(ctl_table *table, int write, struct file *filp,
3016                         void __user *buffer, size_t *lenp, loff_t *ppos)
3017  {
3018 -       ctl_table fake_table;
3019 +       ctl_table fake_table = {0};
3020         unsigned char buf[64], tmp_uuid[16], *uuid;
3021  
3022         uuid = table->data;
3023 diff -NurpP --minimal linux-2.6.17.11/drivers/char/sysrq.c linux-2.6.17.11-vs2.1.1-rc31/drivers/char/sysrq.c
3024 --- linux-2.6.17.11/drivers/char/sysrq.c        2006-06-18 04:52:57 +0200
3025 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/char/sysrq.c   2006-07-09 17:06:48 +0200
3026 @@ -36,6 +36,7 @@
3027  #include <linux/vt_kern.h>
3028  #include <linux/workqueue.h>
3029  #include <linux/kexec.h>
3030 +#include <linux/vserver/debug.h>
3031  
3032  #include <asm/ptrace.h>
3033  
3034 @@ -271,6 +272,21 @@ static struct sysrq_key_op sysrq_unrt_op
3035         .enable_mask    = SYSRQ_ENABLE_RTNICE,
3036  };
3037  
3038 +
3039 +#ifdef CONFIG_VSERVER_DEBUG
3040 +static void sysrq_handle_vxinfo(int key, struct pt_regs *pt_regs,
3041 +                                struct tty_struct *tty)
3042 +{
3043 +       dump_vx_info_inactive((key == 'x')?0:1);
3044 +}
3045 +static struct sysrq_key_op sysrq_showvxinfo_op = {
3046 +       .handler        = sysrq_handle_vxinfo,
3047 +       .help_msg       = "conteXt",
3048 +       .action_msg     = "Show Context Info",
3049 +       .enable_mask    = SYSRQ_ENABLE_DUMP,
3050 +};
3051 +#endif
3052 +
3053  /* Key Operations table and lock */
3054  static DEFINE_SPINLOCK(sysrq_key_table_lock);
3055  
3056 @@ -315,7 +331,11 @@ static struct sysrq_key_op *sysrq_key_ta
3057         /* May be assigned at init time by SMP VOYAGER */
3058         NULL,                           /* v */
3059         NULL,                           /* w */
3060 +#ifdef CONFIG_VSERVER_DEBUG
3061 +       &sysrq_showvxinfo_op,           /* x */
3062 +#else
3063         NULL,                           /* x */
3064 +#endif
3065         NULL,                           /* y */
3066         NULL                            /* z */
3067  };
3068 @@ -329,6 +349,8 @@ static int sysrq_key_table_key2index(int
3069                 retval = key - '0';
3070         else if ((key >= 'a') && (key <= 'z'))
3071                 retval = key + 10 - 'a';
3072 +       else if ((key >= 'A') && (key <= 'Z'))
3073 +               retval = key + 10 - 'A';
3074         else
3075                 retval = -1;
3076         return retval;
3077 diff -NurpP --minimal linux-2.6.17.11/drivers/char/tty_io.c linux-2.6.17.11-vs2.1.1-rc31/drivers/char/tty_io.c
3078 --- linux-2.6.17.11/drivers/char/tty_io.c       2006-08-25 00:25:37 +0200
3079 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/char/tty_io.c  2006-08-17 00:42:17 +0200
3080 @@ -103,6 +103,7 @@
3081  #include <linux/vt_kern.h>
3082  #include <linux/selection.h>
3083  #include <linux/devfs_fs_kernel.h>
3084 +#include <linux/vs_pid.h>
3085  
3086  #include <linux/kmod.h>
3087  
3088 @@ -2388,13 +2389,16 @@ static int tiocsctty(struct tty_struct *
3089  
3090  static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
3091  {
3092 +       pid_t pgrp;
3093         /*
3094          * (tty == real_tty) is a cheap way of
3095          * testing if the tty is NOT a master pty.
3096          */
3097         if (tty == real_tty && current->signal->tty != real_tty)
3098                 return -ENOTTY;
3099 -       return put_user(real_tty->pgrp, p);
3100 +
3101 +       pgrp = vx_map_pid(real_tty->pgrp);
3102 +       return put_user(pgrp, p);
3103  }
3104  
3105  static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
3106 @@ -2412,6 +2416,8 @@ static int tiocspgrp(struct tty_struct *
3107                 return -ENOTTY;
3108         if (get_user(pgrp, p))
3109                 return -EFAULT;
3110 +
3111 +       pgrp = vx_rmap_pid(pgrp);
3112         if (pgrp < 0)
3113                 return -EINVAL;
3114         if (session_of_pgrp(pgrp) != current->signal->session)
3115 diff -NurpP --minimal linux-2.6.17.11/drivers/infiniband/core/uverbs_mem.c linux-2.6.17.11-vs2.1.1-rc31/drivers/infiniband/core/uverbs_mem.c
3116 --- linux-2.6.17.11/drivers/infiniband/core/uverbs_mem.c        2006-06-18 04:53:04 +0200
3117 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/infiniband/core/uverbs_mem.c   2006-07-09 17:06:48 +0200
3118 @@ -36,6 +36,7 @@
3119  
3120  #include <linux/mm.h>
3121  #include <linux/dma-mapping.h>
3122 +#include <linux/vs_memory.h>
3123  
3124  #include "uverbs.h"
3125  
3126 @@ -161,7 +162,7 @@ out:
3127         if (ret < 0)
3128                 __ib_umem_release(dev, mem, 0);
3129         else
3130 -               current->mm->locked_vm = locked;
3131 +               vx_vmlocked_sub(current->mm, current->mm->locked_vm - locked);
3132  
3133         up_write(&current->mm->mmap_sem);
3134         free_page((unsigned long) page_list);
3135 @@ -174,8 +175,8 @@ void ib_umem_release(struct ib_device *d
3136         __ib_umem_release(dev, umem, 1);
3137  
3138         down_write(&current->mm->mmap_sem);
3139 -       current->mm->locked_vm -=
3140 -               PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
3141 +       vx_vmlocked_sub(current->mm,
3142 +               PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT);
3143         up_write(&current->mm->mmap_sem);
3144  }
3145  
3146 @@ -184,7 +185,7 @@ static void ib_umem_account(void *work_p
3147         struct ib_umem_account_work *work = work_ptr;
3148  
3149         down_write(&work->mm->mmap_sem);
3150 -       work->mm->locked_vm -= work->diff;
3151 +       vx_vmlocked_sub(work->mm, work->diff);
3152         up_write(&work->mm->mmap_sem);
3153         mmput(work->mm);
3154         kfree(work);
3155 diff -NurpP --minimal linux-2.6.17.11/drivers/infiniband/hw/ipath/ipath_user_pages.c linux-2.6.17.11-vs2.1.1-rc31/drivers/infiniband/hw/ipath/ipath_user_pages.c
3156 --- linux-2.6.17.11/drivers/infiniband/hw/ipath/ipath_user_pages.c      2006-06-18 04:53:04 +0200
3157 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/infiniband/hw/ipath/ipath_user_pages.c 2006-07-09 17:06:49 +0200
3158 @@ -32,6 +32,7 @@
3159  
3160  #include <linux/mm.h>
3161  #include <linux/device.h>
3162 +#include <linux/vs_memory.h>
3163  
3164  #include "ipath_kernel.h"
3165  
3166 @@ -71,7 +72,8 @@ static int __get_user_pages(unsigned lon
3167         lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
3168                 PAGE_SHIFT;
3169  
3170 -       if (num_pages > lock_limit) {
3171 +       if (num_pages > lock_limit ||
3172 +               !vx_vmlocked_avail(current->mm, num_pages)) {
3173                 ret = -ENOMEM;
3174                 goto bail;
3175         }
3176 @@ -88,7 +90,7 @@ static int __get_user_pages(unsigned lon
3177                         goto bail_release;
3178         }
3179  
3180 -       current->mm->locked_vm += num_pages;
3181 +       vx_vmlocked_add(current->mm, num_pages);
3182  
3183         ret = 0;
3184         goto bail;
3185 @@ -157,7 +159,7 @@ void ipath_release_user_pages(struct pag
3186  
3187         __ipath_release_user_pages(p, num_pages, 1);
3188  
3189 -       current->mm->locked_vm -= num_pages;
3190 +       vx_vmlocked_sub(current->mm, num_pages);
3191  
3192         up_write(&current->mm->mmap_sem);
3193  }
3194 @@ -173,7 +175,7 @@ static void user_pages_account(void *ptr
3195         struct ipath_user_pages_work *work = ptr;
3196  
3197         down_write(&work->mm->mmap_sem);
3198 -       work->mm->locked_vm -= work->num_pages;
3199 +       vx_vmlocked_sub(work->mm, work->num_pages);
3200         up_write(&work->mm->mmap_sem);
3201         mmput(work->mm);
3202         kfree(work);
3203 diff -NurpP --minimal linux-2.6.17.11/drivers/md/dm-ioctl.c linux-2.6.17.11-vs2.1.1-rc31/drivers/md/dm-ioctl.c
3204 --- linux-2.6.17.11/drivers/md/dm-ioctl.c       2006-06-18 04:53:10 +0200
3205 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/md/dm-ioctl.c  2006-08-06 08:10:58 +0200
3206 @@ -102,7 +102,8 @@ static struct hash_cell *__get_name_cell
3207         unsigned int h = hash_str(str);
3208  
3209         list_for_each_entry (hc, _name_buckets + h, name_list)
3210 -               if (!strcmp(hc->name, str))
3211 +               if (vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT) &&
3212 +                       !strcmp(hc->name, str))
3213                         return hc;
3214  
3215         return NULL;
3216 @@ -114,7 +115,8 @@ static struct hash_cell *__get_uuid_cell
3217         unsigned int h = hash_str(str);
3218  
3219         list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
3220 -               if (!strcmp(hc->uuid, str))
3221 +               if (vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT) &&
3222 +                       !strcmp(hc->uuid, str))
3223                         return hc;
3224  
3225         return NULL;
3226 @@ -344,6 +346,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl 
3227  
3228  static int remove_all(struct dm_ioctl *param, size_t param_size)
3229  {
3230 +       if (!vx_check(0, VX_ADMIN))
3231 +               return -EPERM;
3232 +
3233         dm_hash_remove_all();
3234         param->data_size = 0;
3235         return 0;
3236 @@ -391,6 +396,8 @@ static int list_devices(struct dm_ioctl 
3237          */
3238         for (i = 0; i < NUM_BUCKETS; i++) {
3239                 list_for_each_entry (hc, _name_buckets + i, name_list) {
3240 +                       if (!vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT))
3241 +                               continue;
3242                         needed += sizeof(struct dm_name_list);
3243                         needed += strlen(hc->name) + 1;
3244                         needed += ALIGN_MASK;
3245 @@ -414,6 +421,8 @@ static int list_devices(struct dm_ioctl 
3246          */
3247         for (i = 0; i < NUM_BUCKETS; i++) {
3248                 list_for_each_entry (hc, _name_buckets + i, name_list) {
3249 +                       if (!vx_check(dm_get_xid(hc->md), VX_WATCH_P|VX_IDENT))
3250 +                               continue;
3251                         if (old_nl)
3252                                 old_nl->next = (uint32_t) ((void *) nl -
3253                                                            (void *) old_nl);
3254 @@ -612,7 +621,8 @@ static struct hash_cell *__find_device_h
3255  
3256         md = dm_get_md(huge_decode_dev(param->dev));
3257         if (md) {
3258 -               mdptr = dm_get_mdptr(md);
3259 +               if (vx_check(dm_get_xid(md), VX_WATCH_P|VX_IDENT))
3260 +                       mdptr = dm_get_mdptr(md);
3261                 dm_put(md);
3262         }
3263  
3264 @@ -1390,8 +1400,8 @@ static int ctl_ioctl(struct inode *inode
3265         ioctl_fn fn = NULL;
3266         size_t param_size;
3267  
3268 -       /* only root can play with this */
3269 -       if (!capable(CAP_SYS_ADMIN))
3270 +       /* only root and certain contexts can play with this */
3271 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER))
3272                 return -EACCES;
3273  
3274         if (_IOC_TYPE(command) != DM_IOCTL)
3275 diff -NurpP --minimal linux-2.6.17.11/drivers/md/dm.c linux-2.6.17.11-vs2.1.1-rc31/drivers/md/dm.c
3276 --- linux-2.6.17.11/drivers/md/dm.c     2006-06-18 04:53:11 +0200
3277 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/md/dm.c        2006-08-06 06:14:06 +0200
3278 @@ -66,6 +66,7 @@ struct mapped_device {
3279         struct semaphore suspend_lock;
3280         rwlock_t map_lock;
3281         atomic_t holders;
3282 +       xid_t xid;
3283  
3284         unsigned long flags;
3285  
3286 @@ -219,6 +220,8 @@ static int dm_blk_open(struct inode *ino
3287         struct mapped_device *md;
3288  
3289         md = inode->i_bdev->bd_disk->private_data;
3290 +       if (!vx_check(md->xid, VX_IDENT))
3291 +               return -EACCES;
3292         dm_get(md);
3293         return 0;
3294  }
3295 @@ -352,6 +355,14 @@ int dm_set_geometry(struct mapped_device
3296         return 0;
3297  }
3298  
3299 +/*
3300 + * Get the xid associated with a dm device
3301 + */
3302 +xid_t dm_get_xid(struct mapped_device *md)
3303 +{
3304 +       return md->xid;
3305 +}
3306 +
3307  /*-----------------------------------------------------------------
3308   * CRUD START:
3309   *   A more elegant soln is in the works that uses the queue
3310 @@ -850,6 +861,7 @@ static struct mapped_device *alloc_dev(u
3311         rwlock_init(&md->map_lock);
3312         atomic_set(&md->holders, 1);
3313         atomic_set(&md->event_nr, 0);
3314 +       md->xid = vx_current_xid();
3315  
3316         md->queue = blk_alloc_queue(GFP_KERNEL);
3317         if (!md->queue)
3318 diff -NurpP --minimal linux-2.6.17.11/drivers/md/dm.h linux-2.6.17.11-vs2.1.1-rc31/drivers/md/dm.h
3319 --- linux-2.6.17.11/drivers/md/dm.h     2006-06-18 04:53:11 +0200
3320 +++ linux-2.6.17.11-vs2.1.1-rc31/drivers/md/dm.h        2006-08-06 05:21:14 +0200
3321 @@ -92,6 +92,8 @@ int dm_suspended(struct mapped_device *m
3322  int dm_get_geometry(struct mapped_device *md, struct hd_geometry *geo);
3323  int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo);
3324  
3325 +xid_t dm_get_xid(struct mapped_device *md);
3326 +
3327  /*-----------------------------------------------------------------
3328   * Functions for manipulating a table.  Tables are also reference
3329   * counted.
3330 diff -NurpP --minimal linux-2.6.17.11/fs/attr.c linux-2.6.17.11-vs2.1.1-rc31/fs/attr.c
3331 --- linux-2.6.17.11/fs/attr.c   2006-04-09 13:49:53 +0200
3332 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/attr.c      2006-07-09 17:06:49 +0200
3333 @@ -15,6 +15,9 @@
3334  #include <linux/fcntl.h>
3335  #include <linux/quotaops.h>
3336  #include <linux/security.h>
3337 +#include <linux/proc_fs.h>
3338 +#include <linux/devpts_fs.h>
3339 +#include <linux/vserver/debug.h>
3340  
3341  /* Taken over from the old code... */
3342  
3343 @@ -56,6 +59,30 @@ int inode_change_ok(struct inode *inode,
3344                 if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
3345                         goto error;
3346         }
3347 +
3348 +       /* Check for evil vserver activity */
3349 +       if (vx_check(0, VX_ADMIN))
3350 +               goto fine;
3351 +
3352 +       if (IS_BARRIER(inode)) {
3353 +               vxwprintk(1, "xid=%d messing with the barrier.",
3354 +                       vx_current_xid());
3355 +               goto error;
3356 +       }
3357 +       switch (inode->i_sb->s_magic) {
3358 +               case PROC_SUPER_MAGIC:
3359 +                       /* maybe allow that in the future? */
3360 +                       vxwprintk(1, "xid=%d messing with the procfs.",
3361 +                               vx_current_xid());
3362 +                       goto error;
3363 +               case DEVPTS_SUPER_MAGIC:
3364 +                       /* devpts is xid tagged */
3365 +                       if (vx_check((xid_t)inode->i_tag, VX_IDENT))
3366 +                               goto fine;
3367 +                       vxwprintk(1, "xid=%d messing with the devpts.",
3368 +                               vx_current_xid());
3369 +                       goto error;
3370 +       }
3371  fine:
3372         retval = 0;
3373  error:
3374 @@ -79,6 +106,8 @@ int inode_setattr(struct inode * inode, 
3375                 inode->i_uid = attr->ia_uid;
3376         if (ia_valid & ATTR_GID)
3377                 inode->i_gid = attr->ia_gid;
3378 +       if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode))
3379 +               inode->i_tag = attr->ia_tag;
3380         if (ia_valid & ATTR_ATIME)
3381                 inode->i_atime = timespec_trunc(attr->ia_atime,
3382                                                 inode->i_sb->s_time_gran);
3383 @@ -153,7 +182,8 @@ int notify_change(struct dentry * dentry
3384                         error = security_inode_setattr(dentry, attr);
3385                 if (!error) {
3386                         if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
3387 -                           (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
3388 +                           (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
3389 +                           (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag))
3390                                 error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
3391                         if (!error)
3392                                 error = inode_setattr(inode, attr);
3393 diff -NurpP --minimal linux-2.6.17.11/fs/binfmt_aout.c linux-2.6.17.11-vs2.1.1-rc31/fs/binfmt_aout.c
3394 --- linux-2.6.17.11/fs/binfmt_aout.c    2006-04-09 13:49:53 +0200
3395 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/binfmt_aout.c       2006-07-09 17:06:49 +0200
3396 @@ -24,6 +24,7 @@
3397  #include <linux/binfmts.h>
3398  #include <linux/personality.h>
3399  #include <linux/init.h>
3400 +#include <linux/vs_memory.h>
3401  
3402  #include <asm/system.h>
3403  #include <asm/uaccess.h>
3404 diff -NurpP --minimal linux-2.6.17.11/fs/binfmt_elf.c linux-2.6.17.11-vs2.1.1-rc31/fs/binfmt_elf.c
3405 --- linux-2.6.17.11/fs/binfmt_elf.c     2006-06-18 04:54:29 +0200
3406 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/binfmt_elf.c        2006-07-09 17:06:49 +0200
3407 @@ -38,6 +38,8 @@
3408  #include <linux/security.h>
3409  #include <linux/syscalls.h>
3410  #include <linux/random.h>
3411 +#include <linux/vs_memory.h>
3412 +#include <linux/vs_cvirt.h>
3413  
3414  #include <asm/uaccess.h>
3415  #include <asm/param.h>
3416 diff -NurpP --minimal linux-2.6.17.11/fs/binfmt_elf_fdpic.c linux-2.6.17.11-vs2.1.1-rc31/fs/binfmt_elf_fdpic.c
3417 --- linux-2.6.17.11/fs/binfmt_elf_fdpic.c       2006-06-18 04:54:29 +0200
3418 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/binfmt_elf_fdpic.c  2006-07-09 17:06:49 +0200
3419 @@ -32,6 +32,7 @@
3420  #include <linux/elf.h>
3421  #include <linux/elf-fdpic.h>
3422  #include <linux/elfcore.h>
3423 +#include <linux/vs_cvirt.h>
3424  
3425  #include <asm/uaccess.h>
3426  #include <asm/param.h>
3427 diff -NurpP --minimal linux-2.6.17.11/fs/binfmt_flat.c linux-2.6.17.11-vs2.1.1-rc31/fs/binfmt_flat.c
3428 --- linux-2.6.17.11/fs/binfmt_flat.c    2006-06-18 04:54:29 +0200
3429 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/binfmt_flat.c       2006-07-09 17:06:49 +0200
3430 @@ -37,6 +37,7 @@
3431  #include <linux/init.h>
3432  #include <linux/flat.h>
3433  #include <linux/syscalls.h>
3434 +#include <linux/vs_memory.h>
3435  
3436  #include <asm/byteorder.h>
3437  #include <asm/system.h>
3438 diff -NurpP --minimal linux-2.6.17.11/fs/binfmt_som.c linux-2.6.17.11-vs2.1.1-rc31/fs/binfmt_som.c
3439 --- linux-2.6.17.11/fs/binfmt_som.c     2006-01-03 17:29:55 +0100
3440 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/binfmt_som.c        2006-07-09 17:06:49 +0200
3441 @@ -28,6 +28,7 @@
3442  #include <linux/shm.h>
3443  #include <linux/personality.h>
3444  #include <linux/init.h>
3445 +#include <linux/vs_memory.h>
3446  
3447  #include <asm/uaccess.h>
3448  #include <asm/pgtable.h>
3449 diff -NurpP --minimal linux-2.6.17.11/fs/buffer.c linux-2.6.17.11-vs2.1.1-rc31/fs/buffer.c
3450 --- linux-2.6.17.11/fs/buffer.c 2006-08-25 00:25:37 +0200
3451 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/buffer.c    2006-08-17 00:42:17 +0200
3452 @@ -163,7 +163,7 @@ EXPORT_SYMBOL(sync_blockdev);
3453  static void __fsync_super(struct super_block *sb)
3454  {
3455         sync_inodes_sb(sb, 0);
3456 -       DQUOT_SYNC(sb);
3457 +       DQUOT_SYNC(sb->s_dqh);
3458         lock_super(sb);
3459         if (sb->s_dirt && sb->s_op->write_super)
3460                 sb->s_op->write_super(sb);
3461 diff -NurpP --minimal linux-2.6.17.11/fs/dcache.c linux-2.6.17.11-vs2.1.1-rc31/fs/dcache.c
3462 --- linux-2.6.17.11/fs/dcache.c 2006-06-18 04:54:30 +0200
3463 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/dcache.c    2006-07-09 17:06:49 +0200
3464 @@ -33,6 +33,7 @@
3465  #include <linux/seqlock.h>
3466  #include <linux/swap.h>
3467  #include <linux/bootmem.h>
3468 +#include <linux/vs_limit.h>
3469  
3470  
3471  int sysctl_vfs_cache_pressure __read_mostly = 100;
3472 @@ -147,6 +148,7 @@ void dput(struct dentry *dentry)
3473         if (!dentry)
3474                 return;
3475  
3476 +       vx_dentry_dec(dentry);
3477  repeat:
3478         if (atomic_read(&dentry->d_count) == 1)
3479                 might_sleep();
3480 @@ -160,6 +162,8 @@ repeat:
3481                 return;
3482         }
3483  
3484 +       vx_dentry_dec(dentry);
3485 +
3486         /*
3487          * AV: ->d_delete() is _NOT_ allowed to block now.
3488          */
3489 @@ -270,6 +274,7 @@ static inline struct dentry * __dget_loc
3490         if (!list_empty(&dentry->d_lru)) {
3491                 dentry_stat.nr_unused--;
3492                 list_del_init(&dentry->d_lru);
3493 +               vx_dentry_inc(dentry);
3494         }
3495         return dentry;
3496  }
3497 @@ -709,6 +714,9 @@ struct dentry *d_alloc(struct dentry * p
3498         struct dentry *dentry;
3499         char *dname;
3500  
3501 +       if (!vx_dentry_avail(1))
3502 +               return NULL;
3503 +
3504         dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); 
3505         if (!dentry)
3506                 return NULL;
3507 @@ -757,6 +765,7 @@ struct dentry *d_alloc(struct dentry * p
3508         if (parent)
3509                 list_add(&dentry->d_u.d_child, &parent->d_subdirs);
3510         dentry_stat.nr_dentry++;
3511 +       vx_dentry_inc(dentry);
3512         spin_unlock(&dcache_lock);
3513  
3514         return dentry;
3515 @@ -1088,6 +1097,7 @@ struct dentry * __d_lookup(struct dentry
3516  
3517                 if (!d_unhashed(dentry)) {
3518                         atomic_inc(&dentry->d_count);
3519 +                       vx_dentry_inc(dentry);
3520                         found = dentry;
3521                 }
3522                 spin_unlock(&dentry->d_lock);
3523 diff -NurpP --minimal linux-2.6.17.11/fs/devpts/inode.c linux-2.6.17.11-vs2.1.1-rc31/fs/devpts/inode.c
3524 --- linux-2.6.17.11/fs/devpts/inode.c   2006-06-18 04:54:31 +0200
3525 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/devpts/inode.c      2006-08-06 06:14:56 +0200
3526 @@ -20,7 +20,20 @@
3527  #include <linux/devpts_fs.h>
3528  #include <linux/parser.h>
3529  
3530 -#define DEVPTS_SUPER_MAGIC 0x1cd1
3531 +
3532 +static int devpts_permission(struct inode *inode, int mask, struct nameidata *nd)
3533 +{
3534 +       int ret = -EACCES;
3535 +
3536 +       /* devpts is xid tagged */
3537 +       if (vx_check((xid_t)inode->i_tag, VX_WATCH_P|VX_IDENT))
3538 +               ret = generic_permission(inode, mask, NULL);
3539 +       return ret;
3540 +}
3541 +
3542 +static struct inode_operations devpts_file_inode_operations = {
3543 +       .permission     = devpts_permission,
3544 +};
3545  
3546  static struct vfsmount *devpts_mnt;
3547  static struct dentry *devpts_root;
3548 @@ -91,6 +104,25 @@ static int devpts_remount(struct super_b
3549         return 0;
3550  }
3551  
3552 +static int devpts_filter(struct dentry *de)
3553 +{
3554 +       /* devpts is xid tagged */
3555 +       return vx_check((xid_t)de->d_inode->i_tag, VX_WATCH_P|VX_IDENT);
3556 +}
3557 +
3558 +static int devpts_readdir(struct file * filp, void * dirent, filldir_t filldir)
3559 +{
3560 +       return dcache_readdir_filter(filp, dirent, filldir, devpts_filter);
3561 +}
3562 +
3563 +static struct file_operations devpts_dir_operations = {
3564 +       .open           = dcache_dir_open,
3565 +       .release        = dcache_dir_close,
3566 +       .llseek         = dcache_dir_lseek,
3567 +       .read           = generic_read_dir,
3568 +       .readdir        = devpts_readdir,
3569 +};
3570 +
3571  static struct super_operations devpts_sops = {
3572         .statfs         = simple_statfs,
3573         .remount_fs     = devpts_remount,
3574 @@ -117,8 +149,10 @@ devpts_fill_super(struct super_block *s,
3575         inode->i_uid = inode->i_gid = 0;
3576         inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
3577         inode->i_op = &simple_dir_inode_operations;
3578 -       inode->i_fop = &simple_dir_operations;
3579 +       inode->i_fop = &devpts_dir_operations;
3580         inode->i_nlink = 2;
3581 +       /* devpts is xid tagged */
3582 +       inode->i_tag = (tag_t)vx_current_xid();
3583  
3584         devpts_root = s->s_root = d_alloc_root(inode);
3585         if (s->s_root)
3586 @@ -177,6 +211,9 @@ int devpts_pty_new(struct tty_struct *tt
3587         inode->i_gid = config.setgid ? config.gid : current->fsgid;
3588         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
3589         init_special_inode(inode, S_IFCHR|config.mode, device);
3590 +       /* devpts is xid tagged */
3591 +       inode->i_tag = (tag_t)vx_current_xid();
3592 +       inode->i_op = &devpts_file_inode_operations;
3593         inode->u.generic_ip = tty;
3594  
3595         dentry = get_node(number);
3596 diff -NurpP --minimal linux-2.6.17.11/fs/dquot.c linux-2.6.17.11-vs2.1.1-rc31/fs/dquot.c
3597 --- linux-2.6.17.11/fs/dquot.c  2006-06-18 04:54:33 +0200
3598 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/dquot.c     2006-08-25 20:00:57 +0200
3599 @@ -79,6 +79,7 @@
3600  #include <linux/buffer_head.h>
3601  #include <linux/capability.h>
3602  #include <linux/quotaops.h>
3603 +#include <linux/vserver/debug.h>
3604  
3605  #include <asm/uaccess.h>
3606  
3607 @@ -185,7 +186,7 @@ static void put_quota_format(struct quot
3608  /*
3609   * Dquot List Management:
3610   * The quota code uses three lists for dquot management: the inuse_list,
3611 - * free_dquots, and dquot_hash[] array. A single dquot structure may be
3612 + * free_dquots, and hash->dqh_hash[] array. A single dquot structure may be
3613   * on all three lists, depending on its current state.
3614   *
3615   * All dquots are placed to the end of inuse_list when first created, and this
3616 @@ -198,7 +199,7 @@ static void put_quota_format(struct quot
3617   * dquot is invalidated it's completely released from memory.
3618   *
3619   * Dquots with a specific identity (device, type and id) are placed on
3620 - * one of the dquot_hash[] hash chains. The provides an efficient search
3621 + * one of the hash->dqh_hash[] hash chains. The provides an efficient search
3622   * mechanism to locate a specific dquot.
3623   */
3624  
3625 @@ -212,36 +213,44 @@ struct dqstats dqstats;
3626  static void dqput(struct dquot *dquot);
3627  
3628  static inline unsigned int
3629 -hashfn(const struct super_block *sb, unsigned int id, int type)
3630 +hashfn(struct dqhash *hash, unsigned int id, int type)
3631  {
3632         unsigned long tmp;
3633  
3634 -       tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type);
3635 +       tmp = (((unsigned long)hash >> L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type);
3636         return (tmp + (tmp >> dq_hash_bits)) & dq_hash_mask;
3637  }
3638  
3639  /*
3640   * Following list functions expect dq_list_lock to be held
3641   */
3642 -static inline void insert_dquot_hash(struct dquot *dquot)
3643 +static inline void insert_dquot_hash(struct dqhash *hash, struct dquot *dquot)
3644  {
3645 -       struct hlist_head *head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
3646 +       struct hlist_head *head = dquot_hash +
3647 +               hashfn(hash, dquot->dq_id, dquot->dq_type);
3648 +       /* struct hlist_head *head = hash->dqh_hash +
3649 +               hashfn(dquot->dq_dqh, dquot->dq_id, dquot->dq_type); */
3650         hlist_add_head(&dquot->dq_hash, head);
3651 +       dquot->dq_dqh = dqhget(hash);
3652  }
3653  
3654  static inline void remove_dquot_hash(struct dquot *dquot)
3655  {
3656         hlist_del_init(&dquot->dq_hash);
3657 +       dqhput(dquot->dq_dqh);
3658 +       dquot->dq_dqh = NULL;
3659  }
3660  
3661 -static inline struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, unsigned int id, int type)
3662 +static inline struct dquot *find_dquot(struct dqhash *hash,
3663 +       unsigned int hashent, unsigned int id, int type)
3664  {
3665         struct hlist_node *node;
3666         struct dquot *dquot;
3667  
3668 -       hlist_for_each (node, dquot_hash+hashent) {
3669 +       /* hlist_for_each (node, hash->dqh_hash + hashent) { */
3670 +       hlist_for_each (node, dquot_hash + hashent) {
3671                 dquot = hlist_entry(node, struct dquot, dq_hash);
3672 -               if (dquot->dq_sb == sb && dquot->dq_id == id && dquot->dq_type == type)
3673 +               if (dquot->dq_dqh == hash && dquot->dq_id == id && dquot->dq_type == type)
3674                         return dquot;
3675         }
3676         return NODQUOT;
3677 @@ -285,13 +294,13 @@ static void wait_on_dquot(struct dquot *
3678         mutex_unlock(&dquot->dq_lock);
3679  }
3680  
3681 -#define mark_dquot_dirty(dquot) ((dquot)->dq_sb->dq_op->mark_dirty(dquot))
3682 +#define mark_dquot_dirty(dquot) ((dquot)->dq_dqh->dqh_qop->mark_dirty(dquot))
3683  
3684  int dquot_mark_dquot_dirty(struct dquot *dquot)
3685  {
3686         spin_lock(&dq_list_lock);
3687         if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags))
3688 -               list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)->
3689 +               list_add(&dquot->dq_dirty, &dqh_dqopt(dquot->dq_dqh)->
3690                                 info[dquot->dq_type].dqi_dirty_list);
3691         spin_unlock(&dq_list_lock);
3692         return 0;
3693 @@ -306,9 +315,9 @@ static inline int clear_dquot_dirty(stru
3694         return 1;
3695  }
3696  
3697 -void mark_info_dirty(struct super_block *sb, int type)
3698 +void mark_info_dirty(struct dqhash *hash, int type)
3699  {
3700 -       set_bit(DQF_INFO_DIRTY_B, &sb_dqopt(sb)->info[type].dqi_flags);
3701 +       set_bit(DQF_INFO_DIRTY_B, &dqh_dqopt(hash)->info[type].dqi_flags);
3702  }
3703  EXPORT_SYMBOL(mark_info_dirty);
3704  
3705 @@ -319,7 +328,7 @@ EXPORT_SYMBOL(mark_info_dirty);
3706  int dquot_acquire(struct dquot *dquot)
3707  {
3708         int ret = 0, ret2 = 0;
3709 -       struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
3710 +       struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh);
3711  
3712         mutex_lock(&dquot->dq_lock);
3713         mutex_lock(&dqopt->dqio_mutex);
3714 @@ -333,7 +342,7 @@ int dquot_acquire(struct dquot *dquot)
3715                 ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
3716                 /* Write the info if needed */
3717                 if (info_dirty(&dqopt->info[dquot->dq_type]))
3718 -                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
3719 +                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type);
3720                 if (ret < 0)
3721                         goto out_iolock;
3722                 if (ret2 < 0) {
3723 @@ -354,7 +363,7 @@ out_iolock:
3724  int dquot_commit(struct dquot *dquot)
3725  {
3726         int ret = 0, ret2 = 0;
3727 -       struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
3728 +       struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh);
3729  
3730         mutex_lock(&dqopt->dqio_mutex);
3731         spin_lock(&dq_list_lock);
3732 @@ -368,7 +377,7 @@ int dquot_commit(struct dquot *dquot)
3733         if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
3734                 ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
3735                 if (info_dirty(&dqopt->info[dquot->dq_type]))
3736 -                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
3737 +                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type);
3738                 if (ret >= 0)
3739                         ret = ret2;
3740         }
3741 @@ -383,7 +392,7 @@ out_sem:
3742  int dquot_release(struct dquot *dquot)
3743  {
3744         int ret = 0, ret2 = 0;
3745 -       struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
3746 +       struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh);
3747  
3748         mutex_lock(&dquot->dq_lock);
3749         /* Check whether we are not racing with some other dqget() */
3750 @@ -394,7 +403,7 @@ int dquot_release(struct dquot *dquot)
3751                 ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);
3752                 /* Write the info */
3753                 if (info_dirty(&dqopt->info[dquot->dq_type]))
3754 -                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
3755 +                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type);
3756                 if (ret >= 0)
3757                         ret = ret2;
3758         }
3759 @@ -411,14 +420,14 @@ out_dqlock:
3760   * just deleted or pruned by prune_icache() (those are not attached to any
3761   * list). We have to wait for such users.
3762   */
3763 -static void invalidate_dquots(struct super_block *sb, int type)
3764 +static void invalidate_dquots(struct dqhash *hash, int type)
3765  {
3766         struct dquot *dquot, *tmp;
3767  
3768  restart:
3769         spin_lock(&dq_list_lock);
3770         list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
3771 -               if (dquot->dq_sb != sb)
3772 +               if (dquot->dq_dqh != hash)
3773                         continue;
3774                 if (dquot->dq_type != type)
3775                         continue;
3776 @@ -458,18 +467,18 @@ restart:
3777         spin_unlock(&dq_list_lock);
3778  }
3779  
3780 -int vfs_quota_sync(struct super_block *sb, int type)
3781 +int vfs_quota_sync(struct dqhash *hash, int type)
3782  {
3783         struct list_head *dirty;
3784         struct dquot *dquot;
3785 -       struct quota_info *dqopt = sb_dqopt(sb);
3786 +       struct quota_info *dqopt = dqh_dqopt(hash);
3787         int cnt;
3788  
3789         mutex_lock(&dqopt->dqonoff_mutex);
3790         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
3791                 if (type != -1 && cnt != type)
3792                         continue;
3793 -               if (!sb_has_quota_enabled(sb, cnt))
3794 +               if (!dqh_has_quota_enabled(hash, cnt))
3795                         continue;
3796                 spin_lock(&dq_list_lock);
3797                 dirty = &dqopt->info[cnt].dqi_dirty_list;
3798 @@ -486,7 +495,7 @@ int vfs_quota_sync(struct super_block *s
3799                         atomic_inc(&dquot->dq_count);
3800                         dqstats.lookups++;
3801                         spin_unlock(&dq_list_lock);
3802 -                       sb->dq_op->write_dquot(dquot);
3803 +                       hash->dqh_qop->write_dquot(dquot);
3804                         dqput(dquot);
3805                         spin_lock(&dq_list_lock);
3806                 }
3807 @@ -494,9 +503,10 @@ int vfs_quota_sync(struct super_block *s
3808         }
3809  
3810         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3811 -               if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt)
3812 +               if ((cnt == type || type == -1)
3813 +                       && dqh_has_quota_enabled(hash, cnt)
3814                         && info_dirty(&dqopt->info[cnt]))
3815 -                       sb->dq_op->write_info(sb, cnt);
3816 +                       hash->dqh_qop->write_info(hash, cnt);
3817         spin_lock(&dq_list_lock);
3818         dqstats.syncs++;
3819         spin_unlock(&dq_list_lock);
3820 @@ -551,7 +561,7 @@ static void dqput(struct dquot *dquot)
3821         if (!atomic_read(&dquot->dq_count)) {
3822                 printk("VFS: dqput: trying to free free dquot\n");
3823                 printk("VFS: device %s, dquot of %s %d\n",
3824 -                       dquot->dq_sb->s_id,
3825 +                       dquot->dq_dqh->dqh_sb->s_id,
3826                         quotatypes[dquot->dq_type],
3827                         dquot->dq_id);
3828                 BUG();
3829 @@ -567,7 +577,7 @@ we_slept:
3830                 /* We have more than one user... nothing to do */
3831                 atomic_dec(&dquot->dq_count);
3832                 /* Releasing dquot during quotaoff phase? */
3833 -               if (!sb_has_quota_enabled(dquot->dq_sb, dquot->dq_type) &&
3834 +               if (!dqh_has_quota_enabled(dquot->dq_dqh, dquot->dq_type) &&
3835                     atomic_read(&dquot->dq_count) == 1)
3836                         wake_up(&dquot->dq_wait_unused);
3837                 spin_unlock(&dq_list_lock);
3838 @@ -577,14 +587,14 @@ we_slept:
3839         if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) {
3840                 spin_unlock(&dq_list_lock);
3841                 /* Commit dquot before releasing */
3842 -               dquot->dq_sb->dq_op->write_dquot(dquot);
3843 +               dquot->dq_dqh->dqh_qop->write_dquot(dquot);
3844                 goto we_slept;
3845         }
3846         /* Clear flag in case dquot was inactive (something bad happened) */
3847         clear_dquot_dirty(dquot);
3848         if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
3849                 spin_unlock(&dq_list_lock);
3850 -               dquot->dq_sb->dq_op->release_dquot(dquot);
3851 +               dquot->dq_dqh->dqh_qop->release_dquot(dquot);
3852                 goto we_slept;
3853         }
3854         atomic_dec(&dquot->dq_count);
3855 @@ -596,7 +606,7 @@ we_slept:
3856         spin_unlock(&dq_list_lock);
3857  }
3858  
3859 -static struct dquot *get_empty_dquot(struct super_block *sb, int type)
3860 +static struct dquot *get_empty_dquot(int type)
3861  {
3862         struct dquot *dquot;
3863  
3864 @@ -611,7 +621,7 @@ static struct dquot *get_empty_dquot(str
3865         INIT_HLIST_NODE(&dquot->dq_hash);
3866         INIT_LIST_HEAD(&dquot->dq_dirty);
3867         init_waitqueue_head(&dquot->dq_wait_unused);
3868 -       dquot->dq_sb = sb;
3869 +       dquot->dq_dqh = NULL;
3870         dquot->dq_type = type;
3871         atomic_set(&dquot->dq_count, 1);
3872  
3873 @@ -622,19 +632,19 @@ static struct dquot *get_empty_dquot(str
3874   * Get reference to dquot
3875   * MUST be called with either dqptr_sem or dqonoff_mutex held
3876   */
3877 -static struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
3878 +static struct dquot *dqget(struct dqhash *hash, unsigned int id, int type)
3879  {
3880 -       unsigned int hashent = hashfn(sb, id, type);
3881 +       unsigned int hashent = hashfn(hash, id, type);
3882         struct dquot *dquot, *empty = NODQUOT;
3883  
3884 -        if (!sb_has_quota_enabled(sb, type))
3885 +       if (!dqh_has_quota_enabled(hash, type))
3886                 return NODQUOT;
3887  we_slept:
3888         spin_lock(&dq_list_lock);
3889 -       if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) {
3890 +       if ((dquot = find_dquot(hash, hashent, id, type)) == NODQUOT) {
3891                 if (empty == NODQUOT) {
3892                         spin_unlock(&dq_list_lock);
3893 -                       if ((empty = get_empty_dquot(sb, type)) == NODQUOT)
3894 +                       if ((empty = get_empty_dquot(type)) == NODQUOT)
3895                                 schedule();     /* Try to wait for a moment... */
3896                         goto we_slept;
3897                 }
3898 @@ -643,7 +653,7 @@ we_slept:
3899                 /* all dquots go on the inuse_list */
3900                 put_inuse(dquot);
3901                 /* hash it first so it can be found */
3902 -               insert_dquot_hash(dquot);
3903 +               insert_dquot_hash(hash, dquot);
3904                 dqstats.lookups++;
3905                 spin_unlock(&dq_list_lock);
3906         } else {
3907 @@ -660,12 +670,13 @@ we_slept:
3908          * finished or it will be canceled due to dq_count > 1 test */
3909         wait_on_dquot(dquot);
3910         /* Read the dquot and instantiate it (everything done only if needed) */
3911 -       if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) {
3912 +       if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) &&
3913 +               hash->dqh_qop->acquire_dquot(dquot) < 0) {
3914                 dqput(dquot);
3915                 return NODQUOT;
3916         }
3917  #ifdef __DQUOT_PARANOIA
3918 -       BUG_ON(!dquot->dq_sb);  /* Has somebody invalidated entry under us? */
3919 +       BUG_ON(!dquot->dq_dqh); /* Has somebody invalidated entry under us? */
3920  #endif
3921  
3922         return dquot;
3923 @@ -686,9 +697,10 @@ static int dqinit_needed(struct inode *i
3924  }
3925  
3926  /* This routine is guarded by dqonoff_mutex mutex */
3927 -static void add_dquot_ref(struct super_block *sb, int type)
3928 +static void add_dquot_ref(struct dqhash *hash, int type)
3929  {
3930         struct list_head *p;
3931 +       struct super_block *sb = hash->dqh_sb;
3932  
3933  restart:
3934         file_list_lock();
3935 @@ -698,7 +710,7 @@ restart:
3936                 if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
3937                         struct dentry *dentry = dget(filp->f_dentry);
3938                         file_list_unlock();
3939 -                       sb->dq_op->initialize(inode, type);
3940 +                       hash->dqh_qop->initialize(inode, type);
3941                         dput(dentry);
3942                         /* As we may have blocked we had better restart... */
3943                         goto restart;
3944 @@ -757,13 +769,13 @@ static void put_dquot_list(struct list_h
3945  }
3946  
3947  /* Gather all references from inodes and drop them */
3948 -static void drop_dquot_ref(struct super_block *sb, int type)
3949 +static void drop_dquot_ref(struct dqhash *hash, int type)
3950  {
3951         LIST_HEAD(tofree_head);
3952  
3953 -       down_write(&sb_dqopt(sb)->dqptr_sem);
3954 -       remove_dquot_ref(sb, type, &tofree_head);
3955 -       up_write(&sb_dqopt(sb)->dqptr_sem);
3956 +       down_write(&dqh_dqopt(hash)->dqptr_sem);
3957 +       remove_dquot_ref(hash, type, &tofree_head);
3958 +       up_write(&dqh_dqopt(hash)->dqptr_sem);
3959         put_dquot_list(&tofree_head);
3960  }
3961  
3962 @@ -834,7 +846,7 @@ static void print_warning(struct dquot *
3963         if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags)))
3964                 return;
3965  
3966 -       tty_write_message(current->signal->tty, dquot->dq_sb->s_id);
3967 +       tty_write_message(current->signal->tty, dquot->dq_dqh->dqh_sb->s_id);
3968         if (warntype == ISOFTWARN || warntype == BSOFTWARN)
3969                 tty_write_message(current->signal->tty, ": warning, ");
3970         else
3971 @@ -874,7 +886,7 @@ static inline void flush_warnings(struct
3972  
3973  static inline char ignore_hardlimit(struct dquot *dquot)
3974  {
3975 -       struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
3976 +       struct mem_dqinfo *info = &dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type];
3977  
3978         return capable(CAP_SYS_RESOURCE) &&
3979             (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || !(info->dqi_flags & V1_DQF_RSQUASH));
3980 @@ -906,7 +918,7 @@ static int check_idq(struct dquot *dquot
3981            (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
3982             dquot->dq_dqb.dqb_itime == 0) {
3983                 *warntype = ISOFTWARN;
3984 -               dquot->dq_dqb.dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
3985 +               dquot->dq_dqb.dqb_itime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_igrace;
3986         }
3987  
3988         return QUOTA_OK;
3989 @@ -941,7 +953,7 @@ static int check_bdq(struct dquot *dquot
3990             dquot->dq_dqb.dqb_btime == 0) {
3991                 if (!prealloc) {
3992                         *warntype = BSOFTWARN;
3993 -                       dquot->dq_dqb.dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
3994 +                       dquot->dq_dqb.dqb_btime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_bgrace;
3995                 }
3996                 else
3997                         /*
3998 @@ -967,7 +979,7 @@ int dquot_initialize(struct inode *inode
3999           * re-enter the quota code and are already holding the mutex */
4000         if (IS_NOQUOTA(inode))
4001                 return 0;
4002 -       down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
4003 +       down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4004         /* Having dqptr_sem we know NOQUOTA flags can't be altered... */
4005         if (IS_NOQUOTA(inode))
4006                 goto out_err;
4007 @@ -983,11 +995,11 @@ int dquot_initialize(struct inode *inode
4008                                         id = inode->i_gid;
4009                                         break;
4010                         }
4011 -                       inode->i_dquot[cnt] = dqget(inode->i_sb, id, cnt);
4012 +                       inode->i_dquot[cnt] = dqget(inode->i_dqh, id, cnt);
4013                 }
4014         }
4015  out_err:
4016 -       up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
4017 +       up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4018         return ret;
4019  }
4020  
4021 @@ -999,14 +1011,14 @@ int dquot_drop(struct inode *inode)
4022  {
4023         int cnt;
4024  
4025 -       down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
4026 +       down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4027         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
4028                 if (inode->i_dquot[cnt] != NODQUOT) {
4029                         dqput(inode->i_dquot[cnt]);
4030                         inode->i_dquot[cnt] = NODQUOT;
4031                 }
4032         }
4033 -       up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
4034 +       up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4035         return 0;
4036  }
4037  
4038 @@ -1037,9 +1049,9 @@ out_add:
4039         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
4040                 warntype[cnt] = NOWARN;
4041  
4042 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4043 +       down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4044         if (IS_NOQUOTA(inode)) {        /* Now we can do reliable test... */
4045 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4046 +               up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4047                 goto out_add;
4048         }
4049         spin_lock(&dq_data_lock);
4050 @@ -1064,7 +1076,7 @@ warn_put_all:
4051                         if (inode->i_dquot[cnt])
4052                                 mark_dquot_dirty(inode->i_dquot[cnt]);
4053         flush_warnings(inode->i_dquot, warntype);
4054 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4055 +       up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4056         return ret;
4057  }
4058  
4059 @@ -1082,9 +1094,9 @@ int dquot_alloc_inode(const struct inode
4060                 return QUOTA_OK;
4061         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
4062                 warntype[cnt] = NOWARN;
4063 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4064 +       down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4065         if (IS_NOQUOTA(inode)) {
4066 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4067 +               up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4068                 return QUOTA_OK;
4069         }
4070         spin_lock(&dq_data_lock);
4071 @@ -1109,7 +1121,7 @@ warn_put_all:
4072                         if (inode->i_dquot[cnt])
4073                                 mark_dquot_dirty(inode->i_dquot[cnt]);
4074         flush_warnings((struct dquot **)inode->i_dquot, warntype);
4075 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4076 +       up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4077         return ret;
4078  }
4079  
4080 @@ -1127,10 +1139,10 @@ out_sub:
4081                 inode_sub_bytes(inode, number);
4082                 return QUOTA_OK;
4083         }
4084 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4085 +       down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4086         /* Now recheck reliably when holding dqptr_sem */
4087         if (IS_NOQUOTA(inode)) {
4088 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4089 +               up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4090                 goto out_sub;
4091         }
4092         spin_lock(&dq_data_lock);
4093 @@ -1145,7 +1157,7 @@ out_sub:
4094         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
4095                 if (inode->i_dquot[cnt])
4096                         mark_dquot_dirty(inode->i_dquot[cnt]);
4097 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4098 +       up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4099         return QUOTA_OK;
4100  }
4101  
4102 @@ -1160,10 +1172,10 @@ int dquot_free_inode(const struct inode 
4103           * re-enter the quota code and are already holding the mutex */
4104         if (IS_NOQUOTA(inode))
4105                 return QUOTA_OK;
4106 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4107 +       down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4108         /* Now recheck reliably when holding dqptr_sem */
4109         if (IS_NOQUOTA(inode)) {
4110 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4111 +               up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4112                 return QUOTA_OK;
4113         }
4114         spin_lock(&dq_data_lock);
4115 @@ -1177,7 +1189,7 @@ int dquot_free_inode(const struct inode 
4116         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
4117                 if (inode->i_dquot[cnt])
4118                         mark_dquot_dirty(inode->i_dquot[cnt]);
4119 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
4120 +       up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4121         return QUOTA_OK;
4122  }
4123  
4124 @@ -1192,6 +1204,7 @@ int dquot_transfer(struct inode *inode, 
4125         qsize_t space;
4126         struct dquot *transfer_from[MAXQUOTAS];
4127         struct dquot *transfer_to[MAXQUOTAS];
4128 +       struct dqhash *dqh = inode->i_sb->s_dqh;
4129         int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid,
4130             chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid;
4131         char warntype[MAXQUOTAS];
4132 @@ -1205,10 +1218,10 @@ int dquot_transfer(struct inode *inode, 
4133                 transfer_to[cnt] = transfer_from[cnt] = NODQUOT;
4134                 warntype[cnt] = NOWARN;
4135         }
4136 -       down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
4137 +       down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4138         /* Now recheck reliably when holding dqptr_sem */
4139         if (IS_NOQUOTA(inode)) {        /* File without quota accounting? */
4140 -               up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
4141 +               up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4142                 return QUOTA_OK;
4143         }
4144         /* First build the transfer_to list - here we can block on
4145 @@ -1219,12 +1232,12 @@ int dquot_transfer(struct inode *inode, 
4146                         case USRQUOTA:
4147                                 if (!chuid)
4148                                         continue;
4149 -                               transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
4150 +                               transfer_to[cnt] = dqget(dqh, iattr->ia_uid, cnt);
4151                                 break;
4152                         case GRPQUOTA:
4153                                 if (!chgid)
4154                                         continue;
4155 -                               transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
4156 +                               transfer_to[cnt] = dqget(dqh, iattr->ia_gid, cnt);
4157                                 break;
4158                 }
4159         }
4160 @@ -1279,20 +1292,20 @@ warn_put_all:
4161                 if (ret == NO_QUOTA && transfer_to[cnt] != NODQUOT)
4162                         dqput(transfer_to[cnt]);
4163         }
4164 -       up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
4165 +       up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
4166         return ret;
4167  }
4168  
4169  /*
4170   * Write info of quota file to disk
4171   */
4172 -int dquot_commit_info(struct super_block *sb, int type)
4173 +int dquot_commit_info(struct dqhash *hash, int type)
4174  {
4175         int ret;
4176 -       struct quota_info *dqopt = sb_dqopt(sb);
4177 +       struct quota_info *dqopt = dqh_dqopt(hash);
4178  
4179         mutex_lock(&dqopt->dqio_mutex);
4180 -       ret = dqopt->ops[type]->write_file_info(sb, type);
4181 +       ret = dqopt->ops[type]->write_file_info(hash, type);
4182         mutex_unlock(&dqopt->dqio_mutex);
4183         return ret;
4184  }
4185 @@ -1342,10 +1355,10 @@ static inline void reset_enable_flags(st
4186  /*
4187   * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
4188   */
4189 -int vfs_quota_off(struct super_block *sb, int type)
4190 +int vfs_quota_off(struct dqhash *hash, int type)
4191  {
4192         int cnt;
4193 -       struct quota_info *dqopt = sb_dqopt(sb);
4194 +       struct quota_info *dqopt = dqh_dqopt(hash);
4195         struct inode *toputinode[MAXQUOTAS];
4196  
4197         /* We need to serialize quota_off() for device */
4198 @@ -1354,21 +1367,21 @@ int vfs_quota_off(struct super_block *sb
4199                 toputinode[cnt] = NULL;
4200                 if (type != -1 && cnt != type)
4201                         continue;
4202 -               if (!sb_has_quota_enabled(sb, cnt))
4203 +               if (!dqh_has_quota_enabled(hash, cnt))
4204                         continue;
4205                 reset_enable_flags(dqopt, cnt);
4206  
4207                 /* Note: these are blocking operations */
4208 -               drop_dquot_ref(sb, cnt);
4209 -               invalidate_dquots(sb, cnt);
4210 +               drop_dquot_ref(hash, cnt);
4211 +               invalidate_dquots(hash, cnt);
4212                 /*
4213                  * Now all dquots should be invalidated, all writes done so we should be only
4214                  * users of the info. No locks needed.
4215                  */
4216                 if (info_dirty(&dqopt->info[cnt]))
4217 -                       sb->dq_op->write_info(sb, cnt);
4218 +                       hash->dqh_qop->write_info(hash, cnt);
4219                 if (dqopt->ops[cnt]->free_file_info)
4220 -                       dqopt->ops[cnt]->free_file_info(sb, cnt);
4221 +                       dqopt->ops[cnt]->free_file_info(hash, cnt);
4222                 put_quota_format(dqopt->info[cnt].dqi_format);
4223  
4224                 toputinode[cnt] = dqopt->files[cnt];
4225 @@ -1381,9 +1394,9 @@ int vfs_quota_off(struct super_block *sb
4226         mutex_unlock(&dqopt->dqonoff_mutex);
4227         /* Sync the superblock so that buffers with quota data are written to
4228          * disk (and so userspace sees correct data afterwards). */
4229 -       if (sb->s_op->sync_fs)
4230 -               sb->s_op->sync_fs(sb, 1);
4231 -       sync_blockdev(sb->s_bdev);
4232 +       if (hash->dqh_sb->s_op->sync_fs)
4233 +               hash->dqh_sb->s_op->sync_fs(hash->dqh_sb, 1);
4234 +       sync_blockdev(hash->dqh_sb->s_bdev);
4235         /* Now the quota files are just ordinary files and we can set the
4236          * inode flags back. Moreover we discard the pagecache so that
4237          * userspace sees the writes we did bypassing the pagecache. We
4238 @@ -1394,7 +1407,7 @@ int vfs_quota_off(struct super_block *sb
4239                         mutex_lock(&dqopt->dqonoff_mutex);
4240                         /* If quota was reenabled in the meantime, we have
4241                          * nothing to do */
4242 -                       if (!sb_has_quota_enabled(sb, cnt)) {
4243 +                       if (!dqh_has_quota_enabled(hash, cnt)) {
4244                                 mutex_lock(&toputinode[cnt]->i_mutex);
4245                                 toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
4246                                   S_NOATIME | S_NOQUOTA);
4247 @@ -1405,8 +1418,8 @@ int vfs_quota_off(struct super_block *sb
4248                         }
4249                         mutex_unlock(&dqopt->dqonoff_mutex);
4250                 }
4251 -       if (sb->s_bdev)
4252 -               invalidate_bdev(sb->s_bdev, 0);
4253 +       if (hash->dqh_sb->s_bdev)
4254 +               invalidate_bdev(hash->dqh_sb->s_bdev, 0);
4255         return 0;
4256  }
4257  
4258 @@ -1419,7 +1432,8 @@ static int vfs_quota_on_inode(struct ino
4259  {
4260         struct quota_format_type *fmt = find_quota_format(format_id);
4261         struct super_block *sb = inode->i_sb;
4262 -       struct quota_info *dqopt = sb_dqopt(sb);
4263 +       struct dqhash *hash = inode->i_dqh;
4264 +       struct quota_info *dqopt = dqh_dqopt(hash);
4265         int error;
4266         int oldflags = -1;
4267  
4268 @@ -1445,7 +1459,7 @@ static int vfs_quota_on_inode(struct ino
4269         invalidate_bdev(sb->s_bdev, 0);
4270         mutex_lock(&inode->i_mutex);
4271         mutex_lock(&dqopt->dqonoff_mutex);
4272 -       if (sb_has_quota_enabled(sb, type)) {
4273 +       if (dqh_has_quota_enabled(hash, type)) {
4274                 error = -EBUSY;
4275                 goto out_lock;
4276         }
4277 @@ -1456,21 +1470,21 @@ static int vfs_quota_on_inode(struct ino
4278         oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA);
4279         inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
4280         up_write(&dqopt->dqptr_sem);
4281 -       sb->dq_op->drop(inode);
4282 +       hash->dqh_qop->drop(inode);
4283  
4284         error = -EIO;
4285         dqopt->files[type] = igrab(inode);
4286         if (!dqopt->files[type])
4287                 goto out_lock;
4288         error = -EINVAL;
4289 -       if (!fmt->qf_ops->check_quota_file(sb, type))
4290 +       if (!fmt->qf_ops->check_quota_file(hash, type))
4291                 goto out_file_init;
4292  
4293         dqopt->ops[type] = fmt->qf_ops;
4294         dqopt->info[type].dqi_format = fmt;
4295         INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
4296         mutex_lock(&dqopt->dqio_mutex);
4297 -       if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) {
4298 +       if ((error = dqopt->ops[type]->read_file_info(hash, type)) < 0) {
4299                 mutex_unlock(&dqopt->dqio_mutex);
4300                 goto out_file_init;
4301         }
4302 @@ -1478,7 +1492,7 @@ static int vfs_quota_on_inode(struct ino
4303         mutex_unlock(&inode->i_mutex);
4304         set_enable_flags(dqopt, type);
4305  
4306 -       add_dquot_ref(sb, type);
4307 +       add_dquot_ref(hash, type);
4308         mutex_unlock(&dqopt->dqonoff_mutex);
4309  
4310         return 0;
4311 @@ -1504,7 +1518,7 @@ out_fmt:
4312  }
4313  
4314  /* Actual function called from quotactl() */
4315 -int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
4316 +int vfs_quota_on(struct dqhash *hash, int type, int format_id, char *path)
4317  {
4318         struct nameidata nd;
4319         int error;
4320 @@ -1516,7 +1530,7 @@ int vfs_quota_on(struct super_block *sb,
4321         if (error)
4322                 goto out_path;
4323         /* Quota file not on the same filesystem? */
4324 -       if (nd.mnt->mnt_sb != sb)
4325 +       if (nd.mnt->mnt_sb != hash->dqh_sb)
4326                 error = -EXDEV;
4327         else
4328                 error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id);
4329 @@ -1529,13 +1543,13 @@ out_path:
4330   * This function is used when filesystem needs to initialize quotas
4331   * during mount time.
4332   */
4333 -int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
4334 +int vfs_quota_on_mount(struct dqhash *hash, char *qf_name,
4335                 int format_id, int type)
4336  {
4337         struct dentry *dentry;
4338         int error;
4339  
4340 -       dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name));
4341 +       dentry = lookup_one_len(qf_name, hash->dqh_sb->s_root, strlen(qf_name));
4342         if (IS_ERR(dentry))
4343                 return PTR_ERR(dentry);
4344  
4345 @@ -1571,18 +1585,18 @@ static void do_get_dqblk(struct dquot *d
4346         spin_unlock(&dq_data_lock);
4347  }
4348  
4349 -int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
4350 +int vfs_get_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di)
4351  {
4352         struct dquot *dquot;
4353  
4354 -       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
4355 -       if (!(dquot = dqget(sb, id, type))) {
4356 -               mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
4357 +       mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
4358 +       if (!(dquot = dqget(hash, id, type))) {
4359 +               mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
4360                 return -ESRCH;
4361         }
4362         do_get_dqblk(dquot, di);
4363         dqput(dquot);
4364 -       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
4365 +       mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
4366         return 0;
4367  }
4368  
4369 @@ -1622,7 +1636,7 @@ static void do_set_dqblk(struct dquot *d
4370                         clear_bit(DQ_BLKS_B, &dquot->dq_flags);
4371                 }
4372                 else if (!(di->dqb_valid & QIF_BTIME))  /* Set grace only if user hasn't provided his own... */
4373 -                       dm->dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
4374 +                       dm->dqb_btime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_bgrace;
4375         }
4376         if (check_ilim) {
4377                 if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) {
4378 @@ -1630,7 +1644,7 @@ static void do_set_dqblk(struct dquot *d
4379                         clear_bit(DQ_INODES_B, &dquot->dq_flags);
4380                 }
4381                 else if (!(di->dqb_valid & QIF_ITIME))  /* Set grace only if user hasn't provided his own... */
4382 -                       dm->dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
4383 +                       dm->dqb_itime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_igrace;
4384         }
4385         if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit)
4386                 clear_bit(DQ_FAKE_B, &dquot->dq_flags);
4387 @@ -1640,53 +1654,53 @@ static void do_set_dqblk(struct dquot *d
4388         mark_dquot_dirty(dquot);
4389  }
4390  
4391 -int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
4392 +int vfs_set_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di)
4393  {
4394         struct dquot *dquot;
4395  
4396 -       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
4397 -       if (!(dquot = dqget(sb, id, type))) {
4398 -               mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
4399 +       mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
4400 +       if (!(dquot = dqget(hash, id, type))) {
4401 +               mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
4402                 return -ESRCH;
4403         }
4404         do_set_dqblk(dquot, di);
4405         dqput(dquot);
4406 -       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
4407 +       mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
4408         return 0;
4409  }
4410  
4411  /* Generic routine for getting common part of quota file information */
4412 -int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
4413 +int vfs_get_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii)
4414  {
4415         struct mem_dqinfo *mi;
4416    
4417 -       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
4418 -       if (!sb_has_quota_enabled(sb, type)) {
4419 -               mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
4420 +       mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
4421 +       if (!dqh_has_quota_enabled(hash, type)) {
4422 +               mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
4423                 return -ESRCH;
4424         }
4425 -       mi = sb_dqopt(sb)->info + type;
4426 +       mi = dqh_dqopt(hash)->info + type;
4427         spin_lock(&dq_data_lock);
4428         ii->dqi_bgrace = mi->dqi_bgrace;
4429         ii->dqi_igrace = mi->dqi_igrace;
4430         ii->dqi_flags = mi->dqi_flags & DQF_MASK;
4431         ii->dqi_valid = IIF_ALL;
4432         spin_unlock(&dq_data_lock);
4433 -       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
4434 +       mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
4435         return 0;
4436  }
4437  
4438  /* Generic routine for setting common part of quota file information */
4439 -int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
4440 +int vfs_set_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii)
4441  {
4442         struct mem_dqinfo *mi;
4443  
4444 -       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
4445 -       if (!sb_has_quota_enabled(sb, type)) {
4446 -               mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
4447 +       mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
4448 +       if (!dqh_has_quota_enabled(hash, type)) {
4449 +               mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
4450                 return -ESRCH;
4451         }
4452 -       mi = sb_dqopt(sb)->info + type;
4453 +       mi = dqh_dqopt(hash)->info + type;
4454         spin_lock(&dq_data_lock);
4455         if (ii->dqi_valid & IIF_BGRACE)
4456                 mi->dqi_bgrace = ii->dqi_bgrace;
4457 @@ -1695,10 +1709,10 @@ int vfs_set_dqinfo(struct super_block *s
4458         if (ii->dqi_valid & IIF_FLAGS)
4459                 mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK);
4460         spin_unlock(&dq_data_lock);
4461 -       mark_info_dirty(sb, type);
4462 +       mark_info_dirty(hash, type);
4463         /* Force write to disk */
4464 -       sb->dq_op->write_info(sb, type);
4465 -       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
4466 +       hash->dqh_qop->write_info(hash, type);
4467 +       mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
4468         return 0;
4469  }
4470  
4471 diff -NurpP --minimal linux-2.6.17.11/fs/exec.c linux-2.6.17.11-vs2.1.1-rc31/fs/exec.c
4472 --- linux-2.6.17.11/fs/exec.c   2006-06-18 04:54:33 +0200
4473 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/exec.c      2006-07-09 17:06:49 +0200
4474 @@ -49,6 +49,8 @@
4475  #include <linux/rmap.h>
4476  #include <linux/acct.h>
4477  #include <linux/cn_proc.h>
4478 +#include <linux/vs_cvirt.h>
4479 +#include <linux/vs_memory.h>
4480  
4481  #include <asm/uaccess.h>
4482  #include <asm/mmu_context.h>
4483 @@ -436,7 +438,8 @@ int setup_arg_pages(struct linux_binprm 
4484                         kmem_cache_free(vm_area_cachep, mpnt);
4485                         return ret;
4486                 }
4487 -               mm->stack_vm = mm->total_vm = vma_pages(mpnt);
4488 +               vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
4489 +               mm->stack_vm = mm->total_vm;
4490         }
4491  
4492         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
4493 @@ -1325,7 +1328,7 @@ static void format_corename(char *corena
4494                         /* UNIX time of coredump */
4495                         case 't': {
4496                                 struct timeval tv;
4497 -                               do_gettimeofday(&tv);
4498 +                               vx_gettimeofday(&tv);
4499                                 rc = snprintf(out_ptr, out_end - out_ptr,
4500                                               "%lu", tv.tv_sec);
4501                                 if (rc > out_end - out_ptr)
4502 @@ -1337,7 +1340,7 @@ static void format_corename(char *corena
4503                         case 'h':
4504                                 down_read(&uts_sem);
4505                                 rc = snprintf(out_ptr, out_end - out_ptr,
4506 -                                             "%s", system_utsname.nodename);
4507 +                                             "%s", vx_new_uts(nodename));
4508                                 up_read(&uts_sem);
4509                                 if (rc > out_end - out_ptr)
4510                                         goto out;
4511 diff -NurpP --minimal linux-2.6.17.11/fs/ext2/balloc.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/balloc.c
4512 --- linux-2.6.17.11/fs/ext2/balloc.c    2006-04-09 13:49:53 +0200
4513 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/balloc.c       2006-07-09 17:06:49 +0200
4514 @@ -17,6 +17,8 @@
4515  #include <linux/sched.h>
4516  #include <linux/buffer_head.h>
4517  #include <linux/capability.h>
4518 +#include <linux/vs_dlimit.h>
4519 +#include <linux/vs_tag.h>
4520  
4521  /*
4522   * balloc.c contains the blocks allocation and deallocation routines
4523 @@ -109,6 +111,8 @@ static int reserve_blocks(struct super_b
4524         free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
4525         root_blocks = le32_to_cpu(es->s_r_blocks_count);
4526  
4527 +       DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
4528 +
4529         if (free_blocks < count)
4530                 count = free_blocks;
4531  
4532 @@ -259,6 +263,7 @@ do_more:
4533         }
4534  error_return:
4535         brelse(bitmap_bh);
4536 +       DLIMIT_FREE_BLOCK(inode, freed);
4537         release_blocks(sb, freed);
4538         DQUOT_FREE_BLOCK(inode, freed);
4539  }
4540 @@ -362,6 +367,10 @@ int ext2_new_block(struct inode *inode, 
4541                 *err = -ENOSPC;
4542                 goto out_dquot;
4543         }
4544 +       if (DLIMIT_ALLOC_BLOCK(inode, es_alloc)) {
4545 +               *err = -ENOSPC;
4546 +               goto out_dlimit;
4547 +       }
4548  
4549         ext2_debug ("goal=%lu.\n", goal);
4550  
4551 @@ -509,6 +518,8 @@ got_block:
4552         *err = 0;
4553  out_release:
4554         group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);
4555 +       DLIMIT_FREE_BLOCK(inode, es_alloc);
4556 +out_dlimit:
4557         release_blocks(sb, es_alloc);
4558  out_dquot:
4559         DQUOT_FREE_BLOCK(inode, dq_alloc);
4560 diff -NurpP --minimal linux-2.6.17.11/fs/ext2/ext2.h linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/ext2.h
4561 --- linux-2.6.17.11/fs/ext2/ext2.h      2006-06-18 04:54:33 +0200
4562 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/ext2.h 2006-07-09 17:06:49 +0200
4563 @@ -165,6 +165,7 @@ extern const struct file_operations ext2
4564  extern struct address_space_operations ext2_aops;
4565  extern struct address_space_operations ext2_aops_xip;
4566  extern struct address_space_operations ext2_nobh_aops;
4567 +extern int ext2_sync_flags(struct inode *inode);
4568  
4569  /* namei.c */
4570  extern struct inode_operations ext2_dir_inode_operations;
4571 diff -NurpP --minimal linux-2.6.17.11/fs/ext2/file.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/file.c
4572 --- linux-2.6.17.11/fs/ext2/file.c      2006-06-18 04:54:33 +0200
4573 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/file.c 2006-07-09 17:06:49 +0200
4574 @@ -53,6 +53,7 @@ const struct file_operations ext2_file_o
4575         .readv          = generic_file_readv,
4576         .writev         = generic_file_writev,
4577         .sendfile       = generic_file_sendfile,
4578 +       .sendpage       = generic_file_sendpage,
4579         .splice_read    = generic_file_splice_read,
4580         .splice_write   = generic_file_splice_write,
4581  };
4582 @@ -81,4 +82,5 @@ struct inode_operations ext2_file_inode_
4583  #endif
4584         .setattr        = ext2_setattr,
4585         .permission     = ext2_permission,
4586 +       .sync_flags     = ext2_sync_flags,
4587  };
4588 diff -NurpP --minimal linux-2.6.17.11/fs/ext2/ialloc.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/ialloc.c
4589 --- linux-2.6.17.11/fs/ext2/ialloc.c    2006-02-18 14:40:21 +0100
4590 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/ialloc.c       2006-07-09 17:06:49 +0200
4591 @@ -18,6 +18,8 @@
4592  #include <linux/backing-dev.h>
4593  #include <linux/buffer_head.h>
4594  #include <linux/random.h>
4595 +#include <linux/vs_dlimit.h>
4596 +#include <linux/vs_tag.h>
4597  #include "ext2.h"
4598  #include "xattr.h"
4599  #include "acl.h"
4600 @@ -126,6 +128,7 @@ void ext2_free_inode (struct inode * ino
4601                 ext2_xattr_delete_inode(inode);
4602                 DQUOT_FREE_INODE(inode);
4603                 DQUOT_DROP(inode);
4604 +               DLIMIT_FREE_INODE(inode);
4605         }
4606  
4607         es = EXT2_SB(sb)->s_es;
4608 @@ -465,6 +468,11 @@ struct inode *ext2_new_inode(struct inod
4609         if (!inode)
4610                 return ERR_PTR(-ENOMEM);
4611  
4612 +       inode->i_tag = dx_current_fstag(sb);
4613 +       if (DLIMIT_ALLOC_INODE(inode)) {
4614 +               err = -ENOSPC;
4615 +               goto fail_dlim;
4616 +       }
4617         ei = EXT2_I(inode);
4618         sbi = EXT2_SB(sb);
4619         es = sbi->s_es;
4620 @@ -579,7 +587,8 @@ got:
4621         inode->i_blocks = 0;
4622         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
4623         memset(ei->i_data, 0, sizeof(ei->i_data));
4624 -       ei->i_flags = EXT2_I(dir)->i_flags & ~EXT2_BTREE_FL;
4625 +       ei->i_flags = EXT2_I(dir)->i_flags &
4626 +               ~(EXT2_BTREE_FL|EXT2_IUNLINK_FL|EXT2_BARRIER_FL);
4627         if (S_ISLNK(mode))
4628                 ei->i_flags &= ~(EXT2_IMMUTABLE_FL|EXT2_APPEND_FL);
4629         /* dirsync is only applied to directories */
4630 @@ -627,12 +636,15 @@ fail_free_drop:
4631  
4632  fail_drop:
4633         DQUOT_DROP(inode);
4634 +       DLIMIT_FREE_INODE(inode);
4635         inode->i_flags |= S_NOQUOTA;
4636         inode->i_nlink = 0;
4637         iput(inode);
4638         return ERR_PTR(err);
4639  
4640  fail:
4641 +       DLIMIT_FREE_INODE(inode);
4642 +fail_dlim:
4643         make_bad_inode(inode);
4644         iput(inode);
4645         return ERR_PTR(err);
4646 diff -NurpP --minimal linux-2.6.17.11/fs/ext2/inode.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/inode.c
4647 --- linux-2.6.17.11/fs/ext2/inode.c     2006-06-18 04:54:33 +0200
4648 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/inode.c        2006-08-17 01:24:55 +0200
4649 @@ -31,6 +31,7 @@
4650  #include <linux/writeback.h>
4651  #include <linux/buffer_head.h>
4652  #include <linux/mpage.h>
4653 +#include <linux/vserver/tag.h>
4654  #include "ext2.h"
4655  #include "acl.h"
4656  #include "xip.h"
4657 @@ -1042,25 +1043,70 @@ void ext2_set_inode_flags(struct inode *
4658  {
4659         unsigned int flags = EXT2_I(inode)->i_flags;
4660  
4661 -       inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
4662 +       inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
4663 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
4664 +
4665 +       if (flags & EXT2_IMMUTABLE_FL)
4666 +               inode->i_flags |= S_IMMUTABLE;
4667 +       if (flags & EXT2_IUNLINK_FL)
4668 +               inode->i_flags |= S_IUNLINK;
4669 +       if (flags & EXT2_BARRIER_FL)
4670 +               inode->i_flags |= S_BARRIER;
4671 +
4672         if (flags & EXT2_SYNC_FL)
4673                 inode->i_flags |= S_SYNC;
4674         if (flags & EXT2_APPEND_FL)
4675                 inode->i_flags |= S_APPEND;
4676 -       if (flags & EXT2_IMMUTABLE_FL)
4677 -               inode->i_flags |= S_IMMUTABLE;
4678         if (flags & EXT2_NOATIME_FL)
4679                 inode->i_flags |= S_NOATIME;
4680         if (flags & EXT2_DIRSYNC_FL)
4681                 inode->i_flags |= S_DIRSYNC;
4682  }
4683  
4684 +int ext2_sync_flags(struct inode *inode)
4685 +{
4686 +       unsigned int oldflags, newflags;
4687 +
4688 +       oldflags = EXT2_I(inode)->i_flags;
4689 +       newflags = oldflags & ~(EXT2_APPEND_FL |
4690 +               EXT2_IMMUTABLE_FL | EXT2_IUNLINK_FL |
4691 +               EXT2_BARRIER_FL | EXT2_NOATIME_FL |
4692 +               EXT2_SYNC_FL | EXT2_DIRSYNC_FL);
4693 +
4694 +       if (IS_APPEND(inode))
4695 +               newflags |= EXT2_APPEND_FL;
4696 +       if (IS_IMMUTABLE(inode))
4697 +               newflags |= EXT2_IMMUTABLE_FL;
4698 +       if (IS_IUNLINK(inode))
4699 +               newflags |= EXT2_IUNLINK_FL;
4700 +       if (IS_BARRIER(inode))
4701 +               newflags |= EXT2_BARRIER_FL;
4702 +
4703 +       /* we do not want to copy superblock flags */
4704 +       if (inode->i_flags & S_NOATIME)
4705 +               newflags |= EXT2_NOATIME_FL;
4706 +       if (inode->i_flags & S_SYNC)
4707 +               newflags |= EXT2_SYNC_FL;
4708 +       if (inode->i_flags & S_DIRSYNC)
4709 +               newflags |= EXT2_DIRSYNC_FL;
4710 +
4711 +       if (oldflags ^ newflags) {
4712 +               EXT2_I(inode)->i_flags = newflags;
4713 +               inode->i_ctime = CURRENT_TIME;
4714 +               mark_inode_dirty(inode);
4715 +       }
4716 +
4717 +       return 0;
4718 +}
4719 +
4720  void ext2_read_inode (struct inode * inode)
4721  {
4722         struct ext2_inode_info *ei = EXT2_I(inode);
4723         ino_t ino = inode->i_ino;
4724         struct buffer_head * bh;
4725         struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
4726 +       uid_t uid;
4727 +       gid_t gid;
4728         int n;
4729  
4730  #ifdef CONFIG_EXT2_FS_POSIX_ACL
4731 @@ -1071,12 +1117,17 @@ void ext2_read_inode (struct inode * ino
4732                 goto bad_inode;
4733  
4734         inode->i_mode = le16_to_cpu(raw_inode->i_mode);
4735 -       inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4736 -       inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4737 +       uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4738 +       gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4739         if (!(test_opt (inode->i_sb, NO_UID32))) {
4740 -               inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
4741 -               inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
4742 +               uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
4743 +               gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
4744         }
4745 +       inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
4746 +       inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
4747 +       inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
4748 +               le16_to_cpu(raw_inode->i_raw_tag));
4749 +
4750         inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
4751         inode->i_size = le32_to_cpu(raw_inode->i_size);
4752         inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
4753 @@ -1174,8 +1225,8 @@ static int ext2_update_inode(struct inod
4754         struct ext2_inode_info *ei = EXT2_I(inode);
4755         struct super_block *sb = inode->i_sb;
4756         ino_t ino = inode->i_ino;
4757 -       uid_t uid = inode->i_uid;
4758 -       gid_t gid = inode->i_gid;
4759 +       uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
4760 +       gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
4761         struct buffer_head * bh;
4762         struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
4763         int n;
4764 @@ -1210,6 +1261,9 @@ static int ext2_update_inode(struct inod
4765                 raw_inode->i_uid_high = 0;
4766                 raw_inode->i_gid_high = 0;
4767         }
4768 +#ifdef CONFIG_TAGGING_INTERN
4769 +       raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
4770 +#endif
4771         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
4772         raw_inode->i_size = cpu_to_le32(inode->i_size);
4773         raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
4774 @@ -1296,7 +1350,8 @@ int ext2_setattr(struct dentry *dentry, 
4775         if (error)
4776                 return error;
4777         if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
4778 -           (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
4779 +           (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) ||
4780 +           (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) {
4781                 error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0;
4782                 if (error)
4783                         return error;
4784 diff -NurpP --minimal linux-2.6.17.11/fs/ext2/ioctl.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/ioctl.c
4785 --- linux-2.6.17.11/fs/ext2/ioctl.c     2006-04-09 13:49:53 +0200
4786 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/ioctl.c        2006-07-09 17:06:49 +0200
4787 @@ -11,6 +11,7 @@
4788  #include <linux/capability.h>
4789  #include <linux/time.h>
4790  #include <linux/sched.h>
4791 +#include <linux/mount.h>
4792  #include <asm/current.h>
4793  #include <asm/uaccess.h>
4794  
4795 @@ -30,7 +31,8 @@ int ext2_ioctl (struct inode * inode, st
4796         case EXT2_IOC_SETFLAGS: {
4797                 unsigned int oldflags;
4798  
4799 -               if (IS_RDONLY(inode))
4800 +               if (IS_RDONLY(inode) ||
4801 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4802                         return -EROFS;
4803  
4804                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4805 @@ -50,7 +52,9 @@ int ext2_ioctl (struct inode * inode, st
4806                  *
4807                  * This test looks nicer. Thanks to Pauline Middelink
4808                  */
4809 -               if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
4810 +               if ((oldflags & EXT2_IMMUTABLE_FL) ||
4811 +                       ((flags ^ oldflags) & (EXT2_APPEND_FL |
4812 +                       EXT2_IMMUTABLE_FL | EXT2_IUNLINK_FL))) {
4813                         if (!capable(CAP_LINUX_IMMUTABLE))
4814                                 return -EPERM;
4815                 }
4816 @@ -69,7 +73,8 @@ int ext2_ioctl (struct inode * inode, st
4817         case EXT2_IOC_SETVERSION:
4818                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4819                         return -EPERM;
4820 -               if (IS_RDONLY(inode))
4821 +               if (IS_RDONLY(inode) ||
4822 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4823                         return -EROFS;
4824                 if (get_user(inode->i_generation, (int __user *) arg))
4825                         return -EFAULT; 
4826 diff -NurpP --minimal linux-2.6.17.11/fs/ext2/namei.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/namei.c
4827 --- linux-2.6.17.11/fs/ext2/namei.c     2006-06-18 04:54:33 +0200
4828 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/namei.c        2006-07-09 17:06:49 +0200
4829 @@ -31,6 +31,7 @@
4830   */
4831  
4832  #include <linux/pagemap.h>
4833 +#include <linux/vserver/tag.h>
4834  #include "ext2.h"
4835  #include "xattr.h"
4836  #include "acl.h"
4837 @@ -66,6 +67,7 @@ static struct dentry *ext2_lookup(struct
4838                 inode = iget(dir->i_sb, ino);
4839                 if (!inode)
4840                         return ERR_PTR(-EACCES);
4841 +               dx_propagate_tag(nd, inode);
4842         }
4843         return d_splice_alias(inode, dentry);
4844  }
4845 @@ -391,6 +393,7 @@ struct inode_operations ext2_dir_inode_o
4846  #endif
4847         .setattr        = ext2_setattr,
4848         .permission     = ext2_permission,
4849 +       .sync_flags     = ext2_sync_flags,
4850  };
4851  
4852  struct inode_operations ext2_special_inode_operations = {
4853 @@ -402,4 +405,5 @@ struct inode_operations ext2_special_ino
4854  #endif
4855         .setattr        = ext2_setattr,
4856         .permission     = ext2_permission,
4857 +       .sync_flags     = ext2_sync_flags,
4858  };
4859 diff -NurpP --minimal linux-2.6.17.11/fs/ext2/super.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/super.c
4860 --- linux-2.6.17.11/fs/ext2/super.c     2006-06-18 04:54:33 +0200
4861 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/super.c        2006-07-09 17:06:49 +0200
4862 @@ -229,8 +229,8 @@ static int ext2_show_options(struct seq_
4863  }
4864  
4865  #ifdef CONFIG_QUOTA
4866 -static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off);
4867 -static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off);
4868 +static ssize_t ext2_quota_read(struct dqhash *hash, int type, char *data, size_t len, loff_t off);
4869 +static ssize_t ext2_quota_write(struct dqhash *hash, int type, const char *data, size_t len, loff_t off);
4870  #endif
4871  
4872  static struct super_operations ext2_sops = {
4873 @@ -287,7 +287,7 @@ enum {
4874         Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
4875         Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
4876         Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
4877 -       Opt_usrquota, Opt_grpquota
4878 +       Opt_usrquota, Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid
4879  };
4880  
4881  static match_table_t tokens = {
4882 @@ -315,6 +315,10 @@ static match_table_t tokens = {
4883         {Opt_acl, "acl"},
4884         {Opt_noacl, "noacl"},
4885         {Opt_xip, "xip"},
4886 +       {Opt_tag, "tag"},
4887 +       {Opt_notag, "notag"},
4888 +       {Opt_tagid, "tagid=%u"},
4889 +       {Opt_tag, "tagxid"},
4890         {Opt_grpquota, "grpquota"},
4891         {Opt_ignore, "noquota"},
4892         {Opt_quota, "quota"},
4893 @@ -378,6 +382,20 @@ static int parse_options (char * options
4894                 case Opt_nouid32:
4895                         set_opt (sbi->s_mount_opt, NO_UID32);
4896                         break;
4897 +#ifndef CONFIG_TAGGING_NONE
4898 +               case Opt_tag:
4899 +                       set_opt (sbi->s_mount_opt, TAGGED);
4900 +                       break;
4901 +               case Opt_notag:
4902 +                       clear_opt (sbi->s_mount_opt, TAGGED);
4903 +                       break;
4904 +#endif
4905 +#ifdef CONFIG_PROPAGATE
4906 +               case Opt_tagid:
4907 +                       /* use args[0] */
4908 +                       set_opt (sbi->s_mount_opt, TAGGED);
4909 +                       break;
4910 +#endif
4911                 case Opt_nocheck:
4912                         clear_opt (sbi->s_mount_opt, CHECK);
4913                         break;
4914 @@ -679,6 +697,8 @@ static int ext2_fill_super(struct super_
4915         if (!parse_options ((char *) data, sbi))
4916                 goto failed_mount;
4917  
4918 +       if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED)
4919 +               sb->s_flags |= MS_TAGGED;
4920         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
4921                 ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
4922                  MS_POSIXACL : 0);
4923 @@ -988,6 +1008,13 @@ static int ext2_remount (struct super_bl
4924                 goto restore_opts;
4925         }
4926  
4927 +       if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) &&
4928 +               !(sb->s_flags & MS_TAGGED)) {
4929 +               printk("EXT2-fs: %s: tagging not permitted on remount.\n",
4930 +                      sb->s_id);
4931 +               return -EINVAL;
4932 +       }
4933 +
4934         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
4935                 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
4936  
4937 @@ -1099,10 +1126,11 @@ static struct super_block *ext2_get_sb(s
4938   * acquiring the locks... As quota files are never truncated and quota code
4939   * itself serializes the operations (and noone else should touch the files)
4940   * we don't have to be afraid of races */
4941 -static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data,
4942 +static ssize_t ext2_quota_read(struct dqhash *hash, int type, char *data,
4943                                size_t len, loff_t off)
4944  {
4945 -       struct inode *inode = sb_dqopt(sb)->files[type];
4946 +       struct inode *inode = dqh_dqopt(hash)->files[type];
4947 +       struct super_block *sb = hash->dqh_sb;
4948         sector_t blk = off >> EXT2_BLOCK_SIZE_BITS(sb);
4949         int err = 0;
4950         int offset = off & (sb->s_blocksize - 1);
4951 @@ -1143,10 +1171,11 @@ static ssize_t ext2_quota_read(struct su
4952  }
4953  
4954  /* Write to quotafile */
4955 -static ssize_t ext2_quota_write(struct super_block *sb, int type,
4956 +static ssize_t ext2_quota_write(struct dqhash *hash, int type,
4957                                 const char *data, size_t len, loff_t off)
4958  {
4959 -       struct inode *inode = sb_dqopt(sb)->files[type];
4960 +       struct inode *inode = dqh_dqopt(hash)->files[type];
4961 +       struct super_block *sb = hash->dqh_sb;
4962         sector_t blk = off >> EXT2_BLOCK_SIZE_BITS(sb);
4963         int err = 0;
4964         int offset = off & (sb->s_blocksize - 1);
4965 diff -NurpP --minimal linux-2.6.17.11/fs/ext2/symlink.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/symlink.c
4966 --- linux-2.6.17.11/fs/ext2/symlink.c   2005-08-29 22:25:30 +0200
4967 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/symlink.c      2006-07-09 17:06:49 +0200
4968 @@ -38,6 +38,7 @@ struct inode_operations ext2_symlink_ino
4969         .listxattr      = ext2_listxattr,
4970         .removexattr    = generic_removexattr,
4971  #endif
4972 +       .sync_flags     = ext2_sync_flags,
4973  };
4974   
4975  struct inode_operations ext2_fast_symlink_inode_operations = {
4976 @@ -49,4 +50,5 @@ struct inode_operations ext2_fast_symlin
4977         .listxattr      = ext2_listxattr,
4978         .removexattr    = generic_removexattr,
4979  #endif
4980 +       .sync_flags     = ext2_sync_flags,
4981  };
4982 diff -NurpP --minimal linux-2.6.17.11/fs/ext2/xattr.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/xattr.c
4983 --- linux-2.6.17.11/fs/ext2/xattr.c     2006-02-18 14:40:21 +0100
4984 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext2/xattr.c        2006-07-09 17:06:49 +0200
4985 @@ -60,6 +60,7 @@
4986  #include <linux/mbcache.h>
4987  #include <linux/quotaops.h>
4988  #include <linux/rwsem.h>
4989 +#include <linux/vs_dlimit.h>
4990  #include "ext2.h"
4991  #include "xattr.h"
4992  #include "acl.h"
4993 @@ -645,8 +646,12 @@ ext2_xattr_set2(struct inode *inode, str
4994                                    the inode.  */
4995                                 ea_bdebug(new_bh, "reusing block");
4996  
4997 +                               error = -ENOSPC;
4998 +                               if (DLIMIT_ALLOC_BLOCK(inode, 1))
4999 +                                       goto cleanup;
5000                                 error = -EDQUOT;
5001                                 if (DQUOT_ALLOC_BLOCK(inode, 1)) {
5002 +                                       DLIMIT_FREE_BLOCK(inode, 1);
5003                                         unlock_buffer(new_bh);
5004                                         goto cleanup;
5005                                 }
5006 @@ -740,6 +745,7 @@ ext2_xattr_set2(struct inode *inode, str
5007                                 le32_to_cpu(HDR(old_bh)->h_refcount) - 1);
5008                         if (ce)
5009                                 mb_cache_entry_release(ce);
5010 +                       DLIMIT_FREE_BLOCK(inode, 1);
5011                         DQUOT_FREE_BLOCK(inode, 1);
5012                         mark_buffer_dirty(old_bh);
5013                         ea_bdebug(old_bh, "refcount now=%d",
5014 @@ -804,6 +810,7 @@ ext2_xattr_delete_inode(struct inode *in
5015                 mark_buffer_dirty(bh);
5016                 if (IS_SYNC(inode))
5017                         sync_dirty_buffer(bh);
5018 +               DLIMIT_FREE_BLOCK(inode, 1);
5019                 DQUOT_FREE_BLOCK(inode, 1);
5020         }
5021         EXT2_I(inode)->i_file_acl = 0;
5022 diff -NurpP --minimal linux-2.6.17.11/fs/ext3/balloc.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/balloc.c
5023 --- linux-2.6.17.11/fs/ext3/balloc.c    2006-06-18 04:54:33 +0200
5024 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/balloc.c       2006-07-09 17:06:49 +0200
5025 @@ -20,6 +20,8 @@
5026  #include <linux/ext3_jbd.h>
5027  #include <linux/quotaops.h>
5028  #include <linux/buffer_head.h>
5029 +#include <linux/vs_dlimit.h>
5030 +#include <linux/vs_tag.h>
5031  
5032  /*
5033   * balloc.c contains the blocks allocation and deallocation routines
5034 @@ -504,8 +506,10 @@ void ext3_free_blocks(handle_t *handle, 
5035                 return;
5036         }
5037         ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
5038 -       if (dquot_freed_blocks)
5039 +       if (dquot_freed_blocks) {
5040 +               DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks);
5041                 DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
5042 +       }
5043         return;
5044  }
5045  
5046 @@ -1162,18 +1166,32 @@ out:
5047         return ret;
5048  }
5049  
5050 -static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
5051 +static int ext3_has_free_blocks(struct super_block *sb)
5052  {
5053 -       int free_blocks, root_blocks;
5054 +       struct ext3_sb_info *sbi = EXT3_SB(sb);
5055 +       int free_blocks, root_blocks, cond;
5056  
5057         free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
5058         root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
5059 -       if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
5060 +
5061 +       vxdprintk(VXD_CBIT(dlim, 3),
5062 +               "ext3_has_free_blocks(%p): free=%u, root=%u",
5063 +               sb, free_blocks, root_blocks);
5064 +
5065 +       DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
5066 +
5067 +       cond = (free_blocks < root_blocks + 1 &&
5068 +               !capable(CAP_SYS_RESOURCE) &&
5069                 sbi->s_resuid != current->fsuid &&
5070 -               (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
5071 -               return 0;
5072 -       }
5073 -       return 1;
5074 +               (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
5075 +
5076 +       vxdprintk(VXD_CBIT(dlim, 3),
5077 +               "ext3_has_free_blocks(%p): %u<%u+1, %c, %u!=%u r=%d",
5078 +               sb, free_blocks, root_blocks,
5079 +               !capable(CAP_SYS_RESOURCE)?'1':'0',
5080 +               sbi->s_resuid, current->fsuid, cond?0:1);
5081 +
5082 +       return (cond ? 0 : 1);
5083  }
5084  
5085  /*
5086 @@ -1184,7 +1202,7 @@ static int ext3_has_free_blocks(struct e
5087   */
5088  int ext3_should_retry_alloc(struct super_block *sb, int *retries)
5089  {
5090 -       if (!ext3_has_free_blocks(EXT3_SB(sb)) || (*retries)++ > 3)
5091 +       if (!ext3_has_free_blocks(sb) || (*retries)++ > 3)
5092                 return 0;
5093  
5094         jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
5095 @@ -1240,6 +1258,8 @@ int ext3_new_blocks(handle_t *handle, st
5096                 *errp = -EDQUOT;
5097                 return 0;
5098         }
5099 +       if (DLIMIT_ALLOC_BLOCK(inode, 1))
5100 +           goto out_dlimit;
5101  
5102         sbi = EXT3_SB(sb);
5103         es = EXT3_SB(sb)->s_es;
5104 @@ -1256,7 +1276,7 @@ int ext3_new_blocks(handle_t *handle, st
5105         if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
5106                 my_rsv = &block_i->rsv_window_node;
5107  
5108 -       if (!ext3_has_free_blocks(sbi)) {
5109 +       if (!ext3_has_free_blocks(sb)) {
5110                 *errp = -ENOSPC;
5111                 goto out;
5112         }
5113 @@ -1448,6 +1468,9 @@ allocated:
5114  io_error:
5115         *errp = -EIO;
5116  out:
5117 +       if (!performed_allocation)
5118 +               DLIMIT_FREE_BLOCK(inode, 1);
5119 +out_dlimit:
5120         if (fatal) {
5121                 *errp = fatal;
5122                 ext3_std_error(sb, fatal);
5123 diff -NurpP --minimal linux-2.6.17.11/fs/ext3/file.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/file.c
5124 --- linux-2.6.17.11/fs/ext3/file.c      2006-06-18 04:54:33 +0200
5125 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/file.c 2006-07-09 17:06:49 +0200
5126 @@ -119,6 +119,7 @@ const struct file_operations ext3_file_o
5127         .release        = ext3_release_file,
5128         .fsync          = ext3_sync_file,
5129         .sendfile       = generic_file_sendfile,
5130 +       .sendpage       = generic_file_sendpage,
5131         .splice_read    = generic_file_splice_read,
5132         .splice_write   = generic_file_splice_write,
5133  };
5134 @@ -133,5 +134,6 @@ struct inode_operations ext3_file_inode_
5135         .removexattr    = generic_removexattr,
5136  #endif
5137         .permission     = ext3_permission,
5138 +       .sync_flags     = ext3_sync_flags,
5139  };
5140  
5141 diff -NurpP --minimal linux-2.6.17.11/fs/ext3/ialloc.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/ialloc.c
5142 --- linux-2.6.17.11/fs/ext3/ialloc.c    2006-04-09 13:49:53 +0200
5143 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/ialloc.c       2006-07-09 17:06:49 +0200
5144 @@ -23,6 +23,8 @@
5145  #include <linux/buffer_head.h>
5146  #include <linux/random.h>
5147  #include <linux/bitops.h>
5148 +#include <linux/vs_dlimit.h>
5149 +#include <linux/vs_tag.h>
5150  
5151  #include <asm/byteorder.h>
5152  
5153 @@ -127,6 +129,7 @@ void ext3_free_inode (handle_t *handle, 
5154         ext3_xattr_delete_inode(handle, inode);
5155         DQUOT_FREE_INODE(inode);
5156         DQUOT_DROP(inode);
5157 +       DLIMIT_FREE_INODE(inode);
5158  
5159         is_directory = S_ISDIR(inode->i_mode);
5160  
5161 @@ -443,6 +446,12 @@ struct inode *ext3_new_inode(handle_t *h
5162         inode = new_inode(sb);
5163         if (!inode)
5164                 return ERR_PTR(-ENOMEM);
5165 +
5166 +       inode->i_tag = dx_current_fstag(sb);
5167 +       if (DLIMIT_ALLOC_INODE(inode)) {
5168 +               err = -ENOSPC;
5169 +               goto out_dlimit;
5170 +       }
5171         ei = EXT3_I(inode);
5172  
5173         sbi = EXT3_SB(sb);
5174 @@ -565,7 +574,8 @@ got:
5175         ei->i_dir_start_lookup = 0;
5176         ei->i_disksize = 0;
5177  
5178 -       ei->i_flags = EXT3_I(dir)->i_flags & ~EXT3_INDEX_FL;
5179 +       ei->i_flags = EXT3_I(dir)->i_flags &
5180 +               ~(EXT3_INDEX_FL|EXT3_IUNLINK_FL|EXT3_BARRIER_FL);
5181         if (S_ISLNK(mode))
5182                 ei->i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
5183         /* dirsync only applies to directories */
5184 @@ -620,6 +630,8 @@ got:
5185  fail:
5186         ext3_std_error(sb, err);
5187  out:
5188 +       DLIMIT_FREE_INODE(inode);
5189 +out_dlimit:
5190         iput(inode);
5191         ret = ERR_PTR(err);
5192  really_out:
5193 @@ -631,6 +643,7 @@ fail_free_drop:
5194  
5195  fail_drop:
5196         DQUOT_DROP(inode);
5197 +       DLIMIT_FREE_INODE(inode);
5198         inode->i_flags |= S_NOQUOTA;
5199         inode->i_nlink = 0;
5200         iput(inode);
5201 diff -NurpP --minimal linux-2.6.17.11/fs/ext3/inode.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/inode.c
5202 --- linux-2.6.17.11/fs/ext3/inode.c     2006-08-25 00:25:37 +0200
5203 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/inode.c        2006-08-17 00:42:17 +0200
5204 @@ -36,6 +36,7 @@
5205  #include <linux/writeback.h>
5206  #include <linux/mpage.h>
5207  #include <linux/uio.h>
5208 +#include <linux/vserver/tag.h>
5209  #include "xattr.h"
5210  #include "acl.h"
5211  
5212 @@ -2563,19 +2564,77 @@ void ext3_set_inode_flags(struct inode *
5213  {
5214         unsigned int flags = EXT3_I(inode)->i_flags;
5215  
5216 -       inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
5217 +       inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
5218 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
5219 +
5220 +       if (flags & EXT3_IMMUTABLE_FL)
5221 +               inode->i_flags |= S_IMMUTABLE;
5222 +       if (flags & EXT3_IUNLINK_FL)
5223 +               inode->i_flags |= S_IUNLINK;
5224 +       if (flags & EXT3_BARRIER_FL)
5225 +               inode->i_flags |= S_BARRIER;
5226 +
5227         if (flags & EXT3_SYNC_FL)
5228                 inode->i_flags |= S_SYNC;
5229         if (flags & EXT3_APPEND_FL)
5230                 inode->i_flags |= S_APPEND;
5231 -       if (flags & EXT3_IMMUTABLE_FL)
5232 -               inode->i_flags |= S_IMMUTABLE;
5233         if (flags & EXT3_NOATIME_FL)
5234                 inode->i_flags |= S_NOATIME;
5235         if (flags & EXT3_DIRSYNC_FL)
5236                 inode->i_flags |= S_DIRSYNC;
5237  }
5238  
5239 +int ext3_sync_flags(struct inode *inode)
5240 +{
5241 +       unsigned int oldflags, newflags;
5242 +       int err = 0;
5243 +
5244 +       oldflags = EXT3_I(inode)->i_flags;
5245 +       newflags = oldflags & ~(EXT3_APPEND_FL |
5246 +               EXT3_IMMUTABLE_FL | EXT3_IUNLINK_FL |
5247 +               EXT3_BARRIER_FL | EXT3_NOATIME_FL |
5248 +               EXT3_SYNC_FL | EXT3_DIRSYNC_FL);
5249 +
5250 +       if (IS_APPEND(inode))
5251 +               newflags |= EXT3_APPEND_FL;
5252 +       if (IS_IMMUTABLE(inode))
5253 +               newflags |= EXT3_IMMUTABLE_FL;
5254 +       if (IS_IUNLINK(inode))
5255 +               newflags |= EXT3_IUNLINK_FL;
5256 +       if (IS_BARRIER(inode))
5257 +               newflags |= EXT3_BARRIER_FL;
5258 +
5259 +       /* we do not want to copy superblock flags */
5260 +       if (inode->i_flags & S_NOATIME)
5261 +               newflags |= EXT3_NOATIME_FL;
5262 +       if (inode->i_flags & S_SYNC)
5263 +               newflags |= EXT3_SYNC_FL;
5264 +       if (inode->i_flags & S_DIRSYNC)
5265 +               newflags |= EXT3_DIRSYNC_FL;
5266 +
5267 +       if (oldflags ^ newflags) {
5268 +               handle_t *handle;
5269 +               struct ext3_iloc iloc;
5270 +
5271 +               handle = ext3_journal_start(inode, 1);
5272 +               if (IS_ERR(handle))
5273 +                       return PTR_ERR(handle);
5274 +               if (IS_SYNC(inode))
5275 +                       handle->h_sync = 1;
5276 +               err = ext3_reserve_inode_write(handle, inode, &iloc);
5277 +               if (err)
5278 +                       goto flags_err;
5279 +
5280 +               EXT3_I(inode)->i_flags = newflags;
5281 +               inode->i_ctime = CURRENT_TIME;
5282 +
5283 +               err = ext3_mark_iloc_dirty(handle, inode, &iloc);
5284 +       flags_err:
5285 +               ext3_journal_stop(handle);
5286 +       }
5287 +       return err;
5288 +}
5289 +
5290  void ext3_read_inode(struct inode * inode)
5291  {
5292         struct ext3_iloc iloc;
5293 @@ -2583,6 +2642,8 @@ void ext3_read_inode(struct inode * inod
5294         struct ext3_inode_info *ei = EXT3_I(inode);
5295         struct buffer_head *bh;
5296         int block;
5297 +       uid_t uid;
5298 +       gid_t gid;
5299  
5300  #ifdef CONFIG_EXT3_FS_POSIX_ACL
5301         ei->i_acl = EXT3_ACL_NOT_CACHED;
5302 @@ -2595,12 +2656,17 @@ void ext3_read_inode(struct inode * inod
5303         bh = iloc.bh;
5304         raw_inode = ext3_raw_inode(&iloc);
5305         inode->i_mode = le16_to_cpu(raw_inode->i_mode);
5306 -       inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
5307 -       inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
5308 +       uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
5309 +       gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
5310         if(!(test_opt (inode->i_sb, NO_UID32))) {
5311 -               inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
5312 -               inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
5313 +               uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
5314 +               gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
5315         }
5316 +       inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
5317 +       inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
5318 +       inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
5319 +               le16_to_cpu(raw_inode->i_raw_tag));
5320 +
5321         inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
5322         inode->i_size = le32_to_cpu(raw_inode->i_size);
5323         inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
5324 @@ -2727,6 +2793,8 @@ static int ext3_do_update_inode(handle_t
5325         struct ext3_inode *raw_inode = ext3_raw_inode(iloc);
5326         struct ext3_inode_info *ei = EXT3_I(inode);
5327         struct buffer_head *bh = iloc->bh;
5328 +       uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
5329 +       gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
5330         int err = 0, rc, block;
5331  
5332         /* For fields not not tracking in the in-memory inode,
5333 @@ -2736,29 +2804,32 @@ static int ext3_do_update_inode(handle_t
5334  
5335         raw_inode->i_mode = cpu_to_le16(inode->i_mode);
5336         if(!(test_opt(inode->i_sb, NO_UID32))) {
5337 -               raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
5338 -               raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
5339 +               raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
5340 +               raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid));
5341  /*
5342   * Fix up interoperability with old kernels. Otherwise, old inodes get
5343   * re-used with the upper 16 bits of the uid/gid intact
5344   */
5345                 if(!ei->i_dtime) {
5346                         raw_inode->i_uid_high =
5347 -                               cpu_to_le16(high_16_bits(inode->i_uid));
5348 +                               cpu_to_le16(high_16_bits(uid));
5349                         raw_inode->i_gid_high =
5350 -                               cpu_to_le16(high_16_bits(inode->i_gid));
5351 +                               cpu_to_le16(high_16_bits(gid));
5352                 } else {
5353                         raw_inode->i_uid_high = 0;
5354                         raw_inode->i_gid_high = 0;
5355                 }
5356         } else {
5357                 raw_inode->i_uid_low =
5358 -                       cpu_to_le16(fs_high2lowuid(inode->i_uid));
5359 +                       cpu_to_le16(fs_high2lowuid(uid));
5360                 raw_inode->i_gid_low =
5361 -                       cpu_to_le16(fs_high2lowgid(inode->i_gid));
5362 +                       cpu_to_le16(fs_high2lowgid(gid));
5363                 raw_inode->i_uid_high = 0;
5364                 raw_inode->i_gid_high = 0;
5365         }
5366 +#ifdef CONFIG_TAGGING_INTERN
5367 +       raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
5368 +#endif
5369         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
5370         raw_inode->i_size = cpu_to_le32(ei->i_disksize);
5371         raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
5372 @@ -2911,7 +2982,8 @@ int ext3_setattr(struct dentry *dentry, 
5373                 return error;
5374  
5375         if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
5376 -               (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
5377 +               (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
5378 +               (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
5379                 handle_t *handle;
5380  
5381                 /* (user+group)*(old+new) structure, inode write (sb,
5382 @@ -2933,6 +3005,8 @@ int ext3_setattr(struct dentry *dentry, 
5383                         inode->i_uid = attr->ia_uid;
5384                 if (attr->ia_valid & ATTR_GID)
5385                         inode->i_gid = attr->ia_gid;
5386 +               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
5387 +                       inode->i_tag = attr->ia_tag;
5388                 error = ext3_mark_inode_dirty(handle, inode);
5389                 ext3_journal_stop(handle);
5390         }
5391 diff -NurpP --minimal linux-2.6.17.11/fs/ext3/ioctl.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/ioctl.c
5392 --- linux-2.6.17.11/fs/ext3/ioctl.c     2006-06-18 04:54:33 +0200
5393 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/ioctl.c        2006-07-09 17:06:49 +0200
5394 @@ -8,11 +8,13 @@
5395   */
5396  
5397  #include <linux/fs.h>
5398 +#include <linux/mount.h>
5399  #include <linux/jbd.h>
5400  #include <linux/capability.h>
5401  #include <linux/ext3_fs.h>
5402  #include <linux/ext3_jbd.h>
5403  #include <linux/time.h>
5404 +#include <linux/vserver/tag.h>
5405  #include <asm/uaccess.h>
5406  
5407  
5408 @@ -36,7 +38,8 @@ int ext3_ioctl (struct inode * inode, st
5409                 unsigned int oldflags;
5410                 unsigned int jflag;
5411  
5412 -               if (IS_RDONLY(inode))
5413 +               if (IS_RDONLY(inode) ||
5414 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5415                         return -EROFS;
5416  
5417                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
5418 @@ -60,7 +63,9 @@ int ext3_ioctl (struct inode * inode, st
5419                  *
5420                  * This test looks nicer. Thanks to Pauline Middelink
5421                  */
5422 -               if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
5423 +               if ((oldflags & EXT3_IMMUTABLE_FL) ||
5424 +                       ((flags ^ oldflags) & (EXT3_APPEND_FL |
5425 +                       EXT3_IMMUTABLE_FL | EXT3_IUNLINK_FL))) {
5426                         if (!capable(CAP_LINUX_IMMUTABLE)) {
5427                                 mutex_unlock(&inode->i_mutex);
5428                                 return -EPERM;
5429 @@ -122,7 +127,8 @@ flags_err:
5430  
5431                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
5432                         return -EPERM;
5433 -               if (IS_RDONLY(inode))
5434 +               if (IS_RDONLY(inode) ||
5435 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5436                         return -EROFS;
5437                 if (get_user(generation, (int __user *) arg))
5438                         return -EFAULT;
5439 @@ -176,7 +182,8 @@ flags_err:
5440                 if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
5441                         return -ENOTTY;
5442  
5443 -               if (IS_RDONLY(inode))
5444 +               if (IS_RDONLY(inode) ||
5445 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5446                         return -EROFS;
5447  
5448                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
5449 @@ -211,7 +218,8 @@ flags_err:
5450                 if (!capable(CAP_SYS_RESOURCE))
5451                         return -EPERM;
5452  
5453 -               if (IS_RDONLY(inode))
5454 +               if (IS_RDONLY(inode) ||
5455 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5456                         return -EROFS;
5457  
5458                 if (get_user(n_blocks_count, (__u32 __user *)arg))
5459 @@ -232,7 +240,8 @@ flags_err:
5460                 if (!capable(CAP_SYS_RESOURCE))
5461                         return -EPERM;
5462  
5463 -               if (IS_RDONLY(inode))
5464 +               if (IS_RDONLY(inode) ||
5465 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5466                         return -EROFS;
5467  
5468                 if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg,
5469 @@ -247,6 +256,38 @@ flags_err:
5470                 return err;
5471         }
5472  
5473 +#if defined(CONFIG_VSERVER_LEGACY) && !defined(CONFIG_TAGGING_NONE)
5474 +       case EXT3_IOC_SETTAG: {
5475 +               handle_t *handle;
5476 +               struct ext3_iloc iloc;
5477 +               int tag;
5478 +               int err;
5479 +
5480 +               /* fixme: if stealth, return -ENOTTY */
5481 +               if (!capable(CAP_CONTEXT))
5482 +                       return -EPERM;
5483 +               if (IS_RDONLY(inode))
5484 +                       return -EROFS;
5485 +               if (!(inode->i_sb->s_flags & MS_TAGGED))
5486 +                       return -ENOSYS;
5487 +               if (get_user(tag, (int __user *) arg))
5488 +                       return -EFAULT;
5489 +
5490 +               handle = ext3_journal_start(inode, 1);
5491 +               if (IS_ERR(handle))
5492 +                       return PTR_ERR(handle);
5493 +               err = ext3_reserve_inode_write(handle, inode, &iloc);
5494 +               if (err)
5495 +                       return err;
5496 +
5497 +               inode->i_tag = (tag & 0xFFFF);
5498 +               inode->i_ctime = CURRENT_TIME;
5499 +
5500 +               err = ext3_mark_iloc_dirty(handle, inode, &iloc);
5501 +               ext3_journal_stop(handle);
5502 +               return err;
5503 +       }
5504 +#endif
5505  
5506         default:
5507                 return -ENOTTY;
5508 diff -NurpP --minimal linux-2.6.17.11/fs/ext3/namei.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/namei.c
5509 --- linux-2.6.17.11/fs/ext3/namei.c     2006-08-25 00:25:37 +0200
5510 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/namei.c        2006-08-17 00:42:17 +0200
5511 @@ -36,6 +36,7 @@
5512  #include <linux/quotaops.h>
5513  #include <linux/buffer_head.h>
5514  #include <linux/smp_lock.h>
5515 +#include <linux/vserver/tag.h>
5516  
5517  #include "namei.h"
5518  #include "xattr.h"
5519 @@ -1009,6 +1010,7 @@ static struct dentry *ext3_lookup(struct
5520  
5521                 if (!inode)
5522                         return ERR_PTR(-EACCES);
5523 +               dx_propagate_tag(nd, inode);
5524         }
5525         return d_splice_alias(inode, dentry);
5526  }
5527 @@ -2384,6 +2386,7 @@ struct inode_operations ext3_dir_inode_o
5528         .removexattr    = generic_removexattr,
5529  #endif
5530         .permission     = ext3_permission,
5531 +       .sync_flags     = ext3_sync_flags,
5532  };
5533  
5534  struct inode_operations ext3_special_inode_operations = {
5535 @@ -2395,4 +2398,5 @@ struct inode_operations ext3_special_ino
5536         .removexattr    = generic_removexattr,
5537  #endif
5538         .permission     = ext3_permission,
5539 +       .sync_flags     = ext3_sync_flags,
5540  }; 
5541 diff -NurpP --minimal linux-2.6.17.11/fs/ext3/super.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/super.c
5542 --- linux-2.6.17.11/fs/ext3/super.c     2006-08-25 00:25:37 +0200
5543 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/super.c        2006-08-25 00:12:52 +0200
5544 @@ -564,12 +564,12 @@ static int ext3_write_dquot(struct dquot
5545  static int ext3_acquire_dquot(struct dquot *dquot);
5546  static int ext3_release_dquot(struct dquot *dquot);
5547  static int ext3_mark_dquot_dirty(struct dquot *dquot);
5548 -static int ext3_write_info(struct super_block *sb, int type);
5549 -static int ext3_quota_on(struct super_block *sb, int type, int format_id, char *path);
5550 -static int ext3_quota_on_mount(struct super_block *sb, int type);
5551 -static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
5552 +static int ext3_write_info(struct dqhash *hash, int type);
5553 +static int ext3_quota_on(struct dqhash *hash, int type, int format_id, char *path);
5554 +static int ext3_quota_on_mount(struct dqhash *hash, int type);
5555 +static ssize_t ext3_quota_read(struct dqhash *hash, int type, char *data,
5556                                size_t len, loff_t off);
5557 -static ssize_t ext3_quota_write(struct super_block *sb, int type,
5558 +static ssize_t ext3_quota_write(struct dqhash *hash, int type,
5559                                 const char *data, size_t len, loff_t off);
5560  
5561  static struct dquot_operations ext3_quota_operations = {
5562 @@ -675,7 +675,7 @@ enum {
5563         Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
5564         Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
5565         Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
5566 -       Opt_grpquota
5567 +       Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid
5568  };
5569  
5570  static match_table_t tokens = {
5571 @@ -724,6 +724,10 @@ static match_table_t tokens = {
5572         {Opt_quota, "quota"},
5573         {Opt_usrquota, "usrquota"},
5574         {Opt_barrier, "barrier=%u"},
5575 +       {Opt_tag, "tag"},
5576 +       {Opt_notag, "notag"},
5577 +       {Opt_tagid, "tagid=%u"},
5578 +       {Opt_tag, "tagxid"},
5579         {Opt_err, NULL},
5580         {Opt_resize, "resize"},
5581  };
5582 @@ -816,6 +820,20 @@ static int parse_options (char *options,
5583                 case Opt_nouid32:
5584                         set_opt (sbi->s_mount_opt, NO_UID32);
5585                         break;
5586 +#ifndef CONFIG_TAGGING_NONE
5587 +               case Opt_tag:
5588 +                       set_opt (sbi->s_mount_opt, TAGGED);
5589 +                       break;
5590 +               case Opt_notag:
5591 +                       clear_opt (sbi->s_mount_opt, TAGGED);
5592 +                       break;
5593 +#endif
5594 +#ifdef CONFIG_PROPAGATE
5595 +               case Opt_tagid:
5596 +                       /* use args[0] */
5597 +                       set_opt (sbi->s_mount_opt, TAGGED);
5598 +                       break;
5599 +#endif
5600                 case Opt_nocheck:
5601                         clear_opt (sbi->s_mount_opt, CHECK);
5602                         break;
5603 @@ -934,7 +952,7 @@ static int parse_options (char *options,
5604                 case Opt_grpjquota:
5605                         qtype = GRPQUOTA;
5606  set_qf_name:
5607 -                       if (sb_any_quota_enabled(sb)) {
5608 +                       if (dqh_any_quota_enabled(sb->s_dqh)) {
5609                                 printk(KERN_ERR
5610                                         "EXT3-fs: Cannot change journalled "
5611                                         "quota options when quota turned on.\n");
5612 @@ -972,7 +990,7 @@ set_qf_name:
5613                 case Opt_offgrpjquota:
5614                         qtype = GRPQUOTA;
5615  clear_qf_name:
5616 -                       if (sb_any_quota_enabled(sb)) {
5617 +                       if (dqh_any_quota_enabled(sb->s_dqh)) {
5618                                 printk(KERN_ERR "EXT3-fs: Cannot change "
5619                                         "journalled quota options when "
5620                                         "quota turned on.\n");
5621 @@ -1000,7 +1018,7 @@ clear_qf_name:
5622                         set_opt(sbi->s_mount_opt, GRPQUOTA);
5623                         break;
5624                 case Opt_noquota:
5625 -                       if (sb_any_quota_enabled(sb)) {
5626 +                       if (dqh_any_quota_enabled(sb->s_dqh)) {
5627                                 printk(KERN_ERR "EXT3-fs: Cannot change quota "
5628                                         "options when quota turned on.\n");
5629                                 return 0;
5630 @@ -1272,7 +1290,7 @@ static void ext3_orphan_cleanup (struct 
5631         /* Turn on quotas so that they are updated correctly */
5632         for (i = 0; i < MAXQUOTAS; i++) {
5633                 if (EXT3_SB(sb)->s_qf_names[i]) {
5634 -                       int ret = ext3_quota_on_mount(sb, i);
5635 +                       int ret = ext3_quota_on_mount(sb->s_dqh, i);
5636                         if (ret < 0)
5637                                 printk(KERN_ERR
5638                                         "EXT3-fs: Cannot turn on journalled "
5639 @@ -1322,8 +1340,8 @@ static void ext3_orphan_cleanup (struct 
5640  #ifdef CONFIG_QUOTA
5641         /* Turn quotas off */
5642         for (i = 0; i < MAXQUOTAS; i++) {
5643 -               if (sb_dqopt(sb)->files[i])
5644 -                       vfs_quota_off(sb, i);
5645 +               if (dqh_dqopt(sb->s_dqh)->files[i])
5646 +                       vfs_quota_off(sb->s_dqh, i);
5647         }
5648  #endif
5649         sb->s_flags = s_flags; /* Restore MS_RDONLY status */
5650 @@ -1470,6 +1488,9 @@ static int ext3_fill_super (struct super
5651                             NULL, 0))
5652                 goto failed_mount;
5653  
5654 +       if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAGGED)
5655 +               sb->s_flags |= MS_TAGGED;
5656 +
5657         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
5658                 ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
5659  
5660 @@ -1661,8 +1682,8 @@ static int ext3_fill_super (struct super
5661         sb->s_export_op = &ext3_export_ops;
5662         sb->s_xattr = ext3_xattr_handlers;
5663  #ifdef CONFIG_QUOTA
5664 -       sb->s_qcop = &ext3_qctl_operations;
5665 -       sb->dq_op = &ext3_quota_operations;
5666 +       sb->s_dqh->dqh_qop = &ext3_quota_operations;
5667 +       sb->s_dqh->dqh_qcop = &ext3_qctl_operations;
5668  #endif
5669         INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
5670  
5671 @@ -2273,6 +2294,12 @@ static int ext3_remount (struct super_bl
5672  
5673         if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
5674                 ext3_abort(sb, __FUNCTION__, "Abort forced by user");
5675 +       if ((sbi->s_mount_opt & EXT3_MOUNT_TAGGED) &&
5676 +               !(sb->s_flags & MS_TAGGED)) {
5677 +               printk("EXT3-fs: %s: tagging not permitted on remount.\n",
5678 +                       sb->s_id);
5679 +               return -EINVAL;
5680 +       }
5681  
5682         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
5683                 ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
5684 @@ -2427,7 +2454,7 @@ static int ext3_statfs (struct super_blo
5685  
5686  static inline struct inode *dquot_to_inode(struct dquot *dquot)
5687  {
5688 -       return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
5689 +       return dqh_dqopt(dquot->dq_dqh)->files[dquot->dq_type];
5690  }
5691  
5692  static int ext3_dquot_initialize(struct inode *inode, int type)
5693 @@ -2470,7 +2497,7 @@ static int ext3_write_dquot(struct dquot
5694  
5695         inode = dquot_to_inode(dquot);
5696         handle = ext3_journal_start(inode,
5697 -                                       EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
5698 +               EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb));
5699         if (IS_ERR(handle))
5700                 return PTR_ERR(handle);
5701         ret = dquot_commit(dquot);
5702 @@ -2486,7 +2513,7 @@ static int ext3_acquire_dquot(struct dqu
5703         handle_t *handle;
5704  
5705         handle = ext3_journal_start(dquot_to_inode(dquot),
5706 -                                       EXT3_QUOTA_INIT_BLOCKS(dquot->dq_sb));
5707 +               EXT3_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb));
5708         if (IS_ERR(handle))
5709                 return PTR_ERR(handle);
5710         ret = dquot_acquire(dquot);
5711 @@ -2502,7 +2529,7 @@ static int ext3_release_dquot(struct dqu
5712         handle_t *handle;
5713  
5714         handle = ext3_journal_start(dquot_to_inode(dquot),
5715 -                                       EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb));
5716 +               EXT3_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb));
5717         if (IS_ERR(handle))
5718                 return PTR_ERR(handle);
5719         ret = dquot_release(dquot);
5720 @@ -2515,8 +2542,8 @@ static int ext3_release_dquot(struct dqu
5721  static int ext3_mark_dquot_dirty(struct dquot *dquot)
5722  {
5723         /* Are we journalling quotas? */
5724 -       if (EXT3_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
5725 -           EXT3_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
5726 +       if (EXT3_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[USRQUOTA] ||
5727 +           EXT3_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[GRPQUOTA]) {
5728                 dquot_mark_dquot_dirty(dquot);
5729                 return ext3_write_dquot(dquot);
5730         } else {
5731 @@ -2524,8 +2551,9 @@ static int ext3_mark_dquot_dirty(struct 
5732         }
5733  }
5734  
5735 -static int ext3_write_info(struct super_block *sb, int type)
5736 +static int ext3_write_info(struct dqhash *hash, int type)
5737  {
5738 +       struct super_block *sb = hash->dqh_sb;
5739         int ret, err;
5740         handle_t *handle;
5741  
5742 @@ -2533,7 +2561,7 @@ static int ext3_write_info(struct super_
5743         handle = ext3_journal_start(sb->s_root->d_inode, 2);
5744         if (IS_ERR(handle))
5745                 return PTR_ERR(handle);
5746 -       ret = dquot_commit_info(sb, type);
5747 +       ret = dquot_commit_info(hash, type);
5748         err = ext3_journal_stop(handle);
5749         if (!ret)
5750                 ret = err;
5751 @@ -2544,18 +2572,20 @@ static int ext3_write_info(struct super_
5752   * Turn on quotas during mount time - we need to find
5753   * the quota file and such...
5754   */
5755 -static int ext3_quota_on_mount(struct super_block *sb, int type)
5756 +static int ext3_quota_on_mount(struct dqhash *hash, int type)
5757  {
5758 -       return vfs_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type],
5759 -                       EXT3_SB(sb)->s_jquota_fmt, type);
5760 +       return vfs_quota_on_mount(hash,
5761 +               EXT3_SB(hash->dqh_sb)->s_qf_names[type],
5762 +               EXT3_SB(hash->dqh_sb)->s_jquota_fmt, type);
5763  }
5764  
5765  /*
5766   * Standard function to be called on quota_on
5767   */
5768 -static int ext3_quota_on(struct super_block *sb, int type, int format_id,
5769 +static int ext3_quota_on(struct dqhash *hash, int type, int format_id,
5770                          char *path)
5771  {
5772 +       struct super_block *sb = hash->dqh_sb;
5773         int err;
5774         struct nameidata nd;
5775  
5776 @@ -2564,7 +2594,7 @@ static int ext3_quota_on(struct super_bl
5777         /* Not journalling quota? */
5778         if (!EXT3_SB(sb)->s_qf_names[USRQUOTA] &&
5779             !EXT3_SB(sb)->s_qf_names[GRPQUOTA])
5780 -               return vfs_quota_on(sb, type, format_id, path);
5781 +               return vfs_quota_on(hash, type, format_id, path);
5782         err = path_lookup(path, LOOKUP_FOLLOW, &nd);
5783         if (err)
5784                 return err;
5785 @@ -2579,17 +2609,18 @@ static int ext3_quota_on(struct super_bl
5786                         "EXT3-fs: Quota file not on filesystem root. "
5787                         "Journalled quota will not work.\n");
5788         path_release(&nd);
5789 -       return vfs_quota_on(sb, type, format_id, path);
5790 +       return vfs_quota_on(hash, type, format_id, path);
5791  }
5792  
5793  /* Read data from quotafile - avoid pagecache and such because we cannot afford
5794   * acquiring the locks... As quota files are never truncated and quota code
5795   * itself serializes the operations (and noone else should touch the files)
5796   * we don't have to be afraid of races */
5797 -static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
5798 +static ssize_t ext3_quota_read(struct dqhash *hash, int type, char *data,
5799                                size_t len, loff_t off)
5800  {
5801 -       struct inode *inode = sb_dqopt(sb)->files[type];
5802 +       struct inode *inode = dqh_dqopt(hash)->files[type];
5803 +       struct super_block *sb = hash->dqh_sb;
5804         sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
5805         int err = 0;
5806         int offset = off & (sb->s_blocksize - 1);
5807 @@ -2624,10 +2655,11 @@ static ssize_t ext3_quota_read(struct su
5808  
5809  /* Write to quotafile (we know the transaction is already started and has
5810   * enough credits) */
5811 -static ssize_t ext3_quota_write(struct super_block *sb, int type,
5812 +static ssize_t ext3_quota_write(struct dqhash *hash, int type,
5813                                 const char *data, size_t len, loff_t off)
5814  {
5815 -       struct inode *inode = sb_dqopt(sb)->files[type];
5816 +       struct inode *inode = dqh_dqopt(hash)->files[type];
5817 +       struct super_block *sb = hash->dqh_sb;
5818         sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
5819         int err = 0;
5820         int offset = off & (sb->s_blocksize - 1);
5821 diff -NurpP --minimal linux-2.6.17.11/fs/ext3/symlink.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/symlink.c
5822 --- linux-2.6.17.11/fs/ext3/symlink.c   2005-08-29 22:25:30 +0200
5823 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/symlink.c      2006-07-09 17:06:49 +0200
5824 @@ -40,6 +40,7 @@ struct inode_operations ext3_symlink_ino
5825         .listxattr      = ext3_listxattr,
5826         .removexattr    = generic_removexattr,
5827  #endif
5828 +       .sync_flags     = ext3_sync_flags,
5829  };
5830  
5831  struct inode_operations ext3_fast_symlink_inode_operations = {
5832 @@ -51,4 +52,5 @@ struct inode_operations ext3_fast_symlin
5833         .listxattr      = ext3_listxattr,
5834         .removexattr    = generic_removexattr,
5835  #endif
5836 +       .sync_flags     = ext3_sync_flags,
5837  };
5838 diff -NurpP --minimal linux-2.6.17.11/fs/ext3/xattr.c linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/xattr.c
5839 --- linux-2.6.17.11/fs/ext3/xattr.c     2006-04-09 13:49:53 +0200
5840 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ext3/xattr.c        2006-07-09 17:06:49 +0200
5841 @@ -58,6 +58,7 @@
5842  #include <linux/mbcache.h>
5843  #include <linux/quotaops.h>
5844  #include <linux/rwsem.h>
5845 +#include <linux/vs_dlimit.h>
5846  #include "xattr.h"
5847  #include "acl.h"
5848  
5849 @@ -495,6 +496,7 @@ ext3_xattr_release_block(handle_t *handl
5850                         ext3_journal_dirty_metadata(handle, bh);
5851                         if (IS_SYNC(inode))
5852                                 handle->h_sync = 1;
5853 +                       DLIMIT_FREE_BLOCK(inode, 1);
5854                         DQUOT_FREE_BLOCK(inode, 1);
5855                         unlock_buffer(bh);
5856                         ea_bdebug(bh, "refcount now=%d; releasing",
5857 @@ -763,11 +765,14 @@ inserted:
5858                         if (new_bh == bs->bh)
5859                                 ea_bdebug(new_bh, "keeping");
5860                         else {
5861 +                               error = -ENOSPC;
5862 +                               if (DLIMIT_ALLOC_BLOCK(inode, 1))
5863 +                                       goto cleanup;
5864                                 /* The old block is released after updating
5865                                    the inode. */
5866                                 error = -EDQUOT;
5867                                 if (DQUOT_ALLOC_BLOCK(inode, 1))
5868 -                                       goto cleanup;
5869 +                                       goto cleanup_dlimit;
5870                                 error = ext3_journal_get_write_access(handle,
5871                                                                       new_bh);
5872                                 if (error)
5873 @@ -843,6 +848,8 @@ cleanup:
5874  
5875  cleanup_dquot:
5876         DQUOT_FREE_BLOCK(inode, 1);
5877 +cleanup_dlimit:
5878 +       DLIMIT_FREE_BLOCK(inode, 1);
5879         goto cleanup;
5880  
5881  bad_block:
5882 diff -NurpP --minimal linux-2.6.17.11/fs/fcntl.c linux-2.6.17.11-vs2.1.1-rc31/fs/fcntl.c
5883 --- linux-2.6.17.11/fs/fcntl.c  2006-06-18 04:54:34 +0200
5884 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/fcntl.c     2006-07-09 17:06:49 +0200
5885 @@ -18,6 +18,7 @@
5886  #include <linux/ptrace.h>
5887  #include <linux/signal.h>
5888  #include <linux/rcupdate.h>
5889 +#include <linux/vs_limit.h>
5890  
5891  #include <asm/poll.h>
5892  #include <asm/siginfo.h>
5893 @@ -85,6 +86,8 @@ repeat:
5894         error = -EMFILE;
5895         if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
5896                 goto out;
5897 +       if (!vx_files_avail(1))
5898 +               goto out;
5899  
5900         error = expand_files(files, newfd);
5901         if (error < 0)
5902 @@ -125,6 +128,7 @@ static int dupfd(struct file *file, unsi
5903                 FD_SET(fd, fdt->open_fds);
5904                 FD_CLR(fd, fdt->close_on_exec);
5905                 spin_unlock(&files->file_lock);
5906 +               vx_openfd_inc(fd);
5907                 fd_install(fd, file);
5908         } else {
5909                 spin_unlock(&files->file_lock);
5910 @@ -177,6 +181,9 @@ asmlinkage long sys_dup2(unsigned int ol
5911  
5912         if (tofree)
5913                 filp_close(tofree, files);
5914 +       else
5915 +               vx_openfd_inc(newfd);   /* fd was unused */
5916 +
5917         err = newfd;
5918  out:
5919         return err;
5920 @@ -479,7 +486,7 @@ void send_sigio(struct fown_struct *fown
5921         
5922         read_lock(&tasklist_lock);
5923         if (pid > 0) {
5924 -               p = find_task_by_pid(pid);
5925 +               p = find_task_by_real_pid(pid);
5926                 if (p) {
5927                         send_sigio_to_task(p, fown, fd, band);
5928                 }
5929 @@ -514,7 +521,7 @@ int send_sigurg(struct fown_struct *fown
5930         
5931         read_lock(&tasklist_lock);
5932         if (pid > 0) {
5933 -               p = find_task_by_pid(pid);
5934 +               p = find_task_by_real_pid(pid);
5935                 if (p) {
5936                         send_sigurg_to_task(p, fown);
5937                 }
5938 diff -NurpP --minimal linux-2.6.17.11/fs/file_table.c linux-2.6.17.11-vs2.1.1-rc31/fs/file_table.c
5939 --- linux-2.6.17.11/fs/file_table.c     2006-06-18 04:54:34 +0200
5940 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/file_table.c        2006-07-09 17:06:49 +0200
5941 @@ -22,6 +22,8 @@
5942  #include <linux/fsnotify.h>
5943  #include <linux/sysctl.h>
5944  #include <linux/percpu_counter.h>
5945 +#include <linux/vs_limit.h>
5946 +#include <linux/vs_context.h>
5947  
5948  #include <asm/atomic.h>
5949  
5950 @@ -121,6 +123,8 @@ struct file *get_empty_filp(void)
5951         f->f_gid = tsk->fsgid;
5952         eventpoll_init_file(f);
5953         /* f->f_version: 0 */
5954 +       f->f_xid = vx_current_xid();
5955 +       vx_files_inc(f);
5956         return f;
5957  
5958  over:
5959 @@ -175,6 +179,8 @@ void fastcall __fput(struct file *file)
5960         fops_put(file->f_op);
5961         if (file->f_mode & FMODE_WRITE)
5962                 put_write_access(inode);
5963 +       vx_files_dec(file);
5964 +       file->f_xid = 0;
5965         file_kill(file);
5966         file->f_dentry = NULL;
5967         file->f_vfsmnt = NULL;
5968 @@ -240,6 +246,8 @@ void put_filp(struct file *file)
5969  {
5970         if (atomic_dec_and_test(&file->f_count)) {
5971                 security_file_free(file);
5972 +               vx_files_dec(file);
5973 +               file->f_xid = 0;
5974                 file_kill(file);
5975                 file_free(file);
5976         }
5977 diff -NurpP --minimal linux-2.6.17.11/fs/hfsplus/ioctl.c linux-2.6.17.11-vs2.1.1-rc31/fs/hfsplus/ioctl.c
5978 --- linux-2.6.17.11/fs/hfsplus/ioctl.c  2006-04-09 13:49:53 +0200
5979 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/hfsplus/ioctl.c     2006-07-09 17:06:49 +0200
5980 @@ -16,6 +16,7 @@
5981  #include <linux/fs.h>
5982  #include <linux/sched.h>
5983  #include <linux/xattr.h>
5984 +#include <linux/mount.h>
5985  #include <asm/uaccess.h>
5986  #include "hfsplus_fs.h"
5987  
5988 @@ -35,7 +36,8 @@ int hfsplus_ioctl(struct inode *inode, s
5989                         flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */
5990                 return put_user(flags, (int __user *)arg);
5991         case HFSPLUS_IOC_EXT2_SETFLAGS: {
5992 -               if (IS_RDONLY(inode))
5993 +               if (IS_RDONLY(inode) ||
5994 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5995                         return -EROFS;
5996  
5997                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
5998 diff -NurpP --minimal linux-2.6.17.11/fs/inode.c linux-2.6.17.11-vs2.1.1-rc31/fs/inode.c
5999 --- linux-2.6.17.11/fs/inode.c  2006-06-18 04:54:35 +0200
6000 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/inode.c     2006-08-25 19:33:27 +0200
6001 @@ -116,6 +116,9 @@ static struct inode *alloc_inode(struct 
6002                 struct address_space * const mapping = &inode->i_data;
6003  
6004                 inode->i_sb = sb;
6005 +
6006 +               /* essential because of inode slab reuse */
6007 +               inode->i_tag = 0;
6008                 inode->i_blkbits = sb->s_blocksize_bits;
6009                 inode->i_flags = 0;
6010                 atomic_set(&inode->i_count, 1);
6011 @@ -127,6 +130,9 @@ static struct inode *alloc_inode(struct 
6012                 inode->i_blocks = 0;
6013                 inode->i_bytes = 0;
6014                 inode->i_generation = 0;
6015 +#ifdef CONFIG_QUOTACTL
6016 +               inode->i_dqh = dqhget(sb->s_dqh);
6017 +#endif
6018  #ifdef CONFIG_QUOTA
6019                 memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
6020  #endif
6021 @@ -174,6 +180,8 @@ void destroy_inode(struct inode *inode) 
6022  {
6023         BUG_ON(inode_has_buffers(inode));
6024         security_inode_free(inode);
6025 +       if (dqhash_valid(inode->i_dqh))
6026 +               dqhput(inode->i_dqh);
6027         if (inode->i_sb->s_op->destroy_inode)
6028                 inode->i_sb->s_op->destroy_inode(inode);
6029         else
6030 @@ -235,6 +243,8 @@ void __iget(struct inode * inode)
6031         inodes_stat.nr_unused--;
6032  }
6033  
6034 +EXPORT_SYMBOL_GPL(__iget);
6035 +
6036  /**
6037   * clear_inode - clear an inode
6038   * @inode: inode to clear
6039 @@ -1267,12 +1277,13 @@ EXPORT_SYMBOL(inode_needs_sync);
6040  /* Function back in dquot.c */
6041  int remove_inode_dquot_ref(struct inode *, int, struct list_head *);
6042  
6043 -void remove_dquot_ref(struct super_block *sb, int type,
6044 +void remove_dquot_ref(struct dqhash *hash, int type,
6045                         struct list_head *tofree_head)
6046  {
6047         struct inode *inode;
6048 +       struct super_block *sb = hash->dqh_sb;
6049  
6050 -       if (!sb->dq_op)
6051 +       if (!hash->dqh_qop)
6052                 return; /* nothing to do */
6053         spin_lock(&inode_lock); /* This lock is for inodes code */
6054  
6055 diff -NurpP --minimal linux-2.6.17.11/fs/ioctl.c linux-2.6.17.11-vs2.1.1-rc31/fs/ioctl.c
6056 --- linux-2.6.17.11/fs/ioctl.c  2006-04-09 13:49:53 +0200
6057 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ioctl.c     2006-07-09 17:06:49 +0200
6058 @@ -13,10 +13,19 @@
6059  #include <linux/fs.h>
6060  #include <linux/security.h>
6061  #include <linux/module.h>
6062 +#include <linux/proc_fs.h>
6063 +#include <linux/vserver/inode.h>
6064 +#include <linux/vserver/tag.h>
6065  
6066  #include <asm/uaccess.h>
6067  #include <asm/ioctls.h>
6068  
6069 +
6070 +#ifdef CONFIG_VSERVER_LEGACY
6071 +extern int vx_proc_ioctl(struct inode *, struct file *,
6072 +       unsigned int, unsigned long);
6073 +#endif
6074 +
6075  static long do_ioctl(struct file *filp, unsigned int cmd,
6076                 unsigned long arg)
6077  {
6078 @@ -147,6 +156,48 @@ int vfs_ioctl(struct file *filp, unsigne
6079                         else
6080                                 error = -ENOTTY;
6081                         break;
6082 +#ifdef CONFIG_VSERVER_LEGACY
6083 +#ifndef CONFIG_TAGGING_NONE
6084 +               case FIOC_GETTAG: {
6085 +                       struct inode *inode = filp->f_dentry->d_inode;
6086 +
6087 +                       /* fixme: if stealth, return -ENOTTY */
6088 +                       error = -EPERM;
6089 +                       if (capable(CAP_CONTEXT))
6090 +                               error = put_user(inode->i_tag, (int __user *) arg);
6091 +                       break;
6092 +               }
6093 +               case FIOC_SETTAG: {
6094 +                       struct inode *inode = filp->f_dentry->d_inode;
6095 +                       int tag;
6096 +
6097 +                       /* fixme: if stealth, return -ENOTTY */
6098 +                       error = -EPERM;
6099 +                       if (!capable(CAP_CONTEXT))
6100 +                               break;
6101 +                       error = -EROFS;
6102 +                       if (IS_RDONLY(inode))
6103 +                               break;
6104 +                       error = -ENOSYS;
6105 +                       if (!(inode->i_sb->s_flags & MS_TAGGED))
6106 +                               break;
6107 +                       error = -EFAULT;
6108 +                       if (get_user(tag, (int __user *) arg))
6109 +                               break;
6110 +                       error = 0;
6111 +                       inode->i_tag = (tag & 0xFFFF);
6112 +                       inode->i_ctime = CURRENT_TIME;
6113 +                       mark_inode_dirty(inode);
6114 +                       break;
6115 +               }
6116 +#endif
6117 +               case FIOC_GETXFLG:
6118 +               case FIOC_SETXFLG:
6119 +                       error = -ENOTTY;
6120 +                       if (filp->f_dentry->d_inode->i_sb->s_magic == PROC_SUPER_MAGIC)
6121 +                               error = vx_proc_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
6122 +                       break;
6123 +#endif
6124                 default:
6125                         if (S_ISREG(filp->f_dentry->d_inode->i_mode))
6126                                 error = file_ioctl(filp, cmd, arg);
6127 diff -NurpP --minimal linux-2.6.17.11/fs/ioprio.c linux-2.6.17.11-vs2.1.1-rc31/fs/ioprio.c
6128 --- linux-2.6.17.11/fs/ioprio.c 2006-04-09 13:49:53 +0200
6129 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ioprio.c    2006-07-09 17:06:49 +0200
6130 @@ -24,6 +24,7 @@
6131  #include <linux/blkdev.h>
6132  #include <linux/capability.h>
6133  #include <linux/syscalls.h>
6134 +#include <linux/vs_pid.h>
6135  
6136  static int set_task_ioprio(struct task_struct *task, int ioprio)
6137  {
6138 @@ -95,7 +96,7 @@ asmlinkage long sys_ioprio_set(int which
6139                         if (!who)
6140                                 user = current->user;
6141                         else
6142 -                               user = find_user(who);
6143 +                               user = find_user(vx_current_xid(), who);
6144  
6145                         if (!user)
6146                                 break;
6147 @@ -149,7 +150,7 @@ asmlinkage long sys_ioprio_get(int which
6148                         if (!who)
6149                                 user = current->user;
6150                         else
6151 -                               user = find_user(who);
6152 +                               user = find_user(vx_current_xid(), who);
6153  
6154                         if (!user)
6155                                 break;
6156 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/acl.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/acl.c
6157 --- linux-2.6.17.11/fs/jfs/acl.c        2006-06-18 04:54:36 +0200
6158 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/acl.c   2006-07-09 17:06:49 +0200
6159 @@ -232,7 +232,8 @@ int jfs_setattr(struct dentry *dentry, s
6160                 return rc;
6161  
6162         if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
6163 -           (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
6164 +           (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) ||
6165 +           (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) {
6166                 if (DQUOT_TRANSFER(inode, iattr))
6167                         return -EDQUOT;
6168         }
6169 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/file.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/file.c
6170 --- linux-2.6.17.11/fs/jfs/file.c       2006-06-18 04:54:36 +0200
6171 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/file.c  2006-07-09 17:06:49 +0200
6172 @@ -98,6 +98,7 @@ struct inode_operations jfs_file_inode_o
6173         .setattr        = jfs_setattr,
6174         .permission     = jfs_permission,
6175  #endif
6176 +       .sync_flags     = jfs_sync_flags,
6177  };
6178  
6179  const struct file_operations jfs_file_operations = {
6180 @@ -111,6 +112,7 @@ const struct file_operations jfs_file_op
6181         .readv          = generic_file_readv,
6182         .writev         = generic_file_writev,
6183         .sendfile       = generic_file_sendfile,
6184 +       .sendpage       = generic_file_sendpage,
6185         .fsync          = jfs_fsync,
6186         .release        = jfs_release,
6187         .ioctl          = jfs_ioctl,
6188 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/inode.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/inode.c
6189 --- linux-2.6.17.11/fs/jfs/inode.c      2006-06-18 04:54:36 +0200
6190 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/inode.c 2006-07-09 17:06:49 +0200
6191 @@ -22,6 +22,7 @@
6192  #include <linux/buffer_head.h>
6193  #include <linux/pagemap.h>
6194  #include <linux/quotaops.h>
6195 +#include <linux/vs_dlimit.h>
6196  #include "jfs_incore.h"
6197  #include "jfs_inode.h"
6198  #include "jfs_filsys.h"
6199 @@ -144,6 +145,7 @@ void jfs_delete_inode(struct inode *inod
6200                 DQUOT_INIT(inode);
6201                 DQUOT_FREE_INODE(inode);
6202                 DQUOT_DROP(inode);
6203 +               DLIMIT_FREE_INODE(inode);
6204         }
6205  
6206         clear_inode(inode);
6207 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/ioctl.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/ioctl.c
6208 --- linux-2.6.17.11/fs/jfs/ioctl.c      2006-06-18 04:54:36 +0200
6209 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/ioctl.c 2006-07-09 17:06:49 +0200
6210 @@ -10,6 +10,7 @@
6211  #include <linux/ctype.h>
6212  #include <linux/capability.h>
6213  #include <linux/time.h>
6214 +#include <linux/mount.h>
6215  #include <asm/current.h>
6216  #include <asm/uaccess.h>
6217  
6218 @@ -65,7 +66,8 @@ int jfs_ioctl(struct inode * inode, stru
6219         case JFS_IOC_SETFLAGS: {
6220                 unsigned int oldflags;
6221  
6222 -               if (IS_RDONLY(inode))
6223 +               if (IS_RDONLY(inode) ||
6224 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
6225                         return -EROFS;
6226  
6227                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
6228 @@ -85,8 +87,8 @@ int jfs_ioctl(struct inode * inode, stru
6229                  * the relevant capability.
6230                  */
6231                 if ((oldflags & JFS_IMMUTABLE_FL) ||
6232 -                       ((flags ^ oldflags) &
6233 -                       (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
6234 +                       ((flags ^ oldflags) & (JFS_APPEND_FL |
6235 +                       JFS_IMMUTABLE_FL | JFS_IUNLINK_FL))) {
6236                         if (!capable(CAP_LINUX_IMMUTABLE))
6237                                 return -EPERM;
6238                 }
6239 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/jfs_dinode.h linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_dinode.h
6240 --- linux-2.6.17.11/fs/jfs/jfs_dinode.h 2006-06-18 04:54:36 +0200
6241 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_dinode.h    2006-08-17 01:24:55 +0200
6242 @@ -162,9 +162,12 @@ struct dinode {
6243  #define JFS_APPEND_FL          0x01000000 /* writes to file may only append */
6244  #define JFS_IMMUTABLE_FL       0x02000000 /* Immutable file */
6245  
6246 -#define JFS_FL_USER_VISIBLE    0x03F80000
6247 +#define JFS_BARRIER_FL         0x04000000 /* Barrier for chroot() */
6248 +#define JFS_IUNLINK_FL         0x08000000 /* Immutable unlink */
6249 +
6250 +#define JFS_FL_USER_VISIBLE    0x0FF80000
6251  #define JFS_FL_USER_MODIFIABLE 0x03F80000
6252 -#define JFS_FL_INHERIT         0x03C80000
6253 +#define JFS_FL_INHERIT         0x0BC80000
6254  
6255  /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
6256  #define JFS_IOC_GETFLAGS       _IOR('f', 1, long)
6257 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/jfs_dtree.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_dtree.c
6258 --- linux-2.6.17.11/fs/jfs/jfs_dtree.c  2006-06-18 04:54:36 +0200
6259 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_dtree.c     2006-08-17 01:24:16 +0200
6260 @@ -102,6 +102,7 @@
6261  
6262  #include <linux/fs.h>
6263  #include <linux/quotaops.h>
6264 +#include <linux/vs_dlimit.h>
6265  #include "jfs_incore.h"
6266  #include "jfs_superblock.h"
6267  #include "jfs_filsys.h"
6268 @@ -383,10 +384,10 @@ static u32 add_index(tid_t tid, struct i
6269                  */
6270                 if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage))
6271                         goto clean_up;
6272 -               if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) {
6273 -                       DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
6274 -                       goto clean_up;
6275 -               }
6276 +               if (DLIMIT_ALLOC_BLOCK(ip, sbi->nbperpage))
6277 +                       goto clean_up_dquot;
6278 +               if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
6279 +                       goto clean_up_dlimit;
6280  
6281                 /*
6282                  * Save the table, we're going to overwrite it with the
6283 @@ -479,6 +480,12 @@ static u32 add_index(tid_t tid, struct i
6284  
6285         return index;
6286  
6287 +      clean_up_dlimit:
6288 +       DLIMIT_FREE_BLOCK(ip, sbi->nbperpage);
6289 +
6290 +      clean_up_dquot:
6291 +       DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
6292 +
6293        clean_up:
6294  
6295         jfs_ip->next_index--;
6296 @@ -952,6 +959,7 @@ static int dtSplitUp(tid_t tid,
6297         struct tlock *tlck;
6298         struct lv *lv;
6299         int quota_allocation = 0;
6300 +       int dlimit_allocation = 0;
6301  
6302         /* get split page */
6303         smp = split->mp;
6304 @@ -1036,6 +1044,12 @@ static int dtSplitUp(tid_t tid,
6305                 }
6306                 quota_allocation += n;
6307  
6308 +               if (DLIMIT_ALLOC_BLOCK(ip, n)) {
6309 +                       rc = -ENOSPC;
6310 +                       goto extendOut;
6311 +               }
6312 +               dlimit_allocation += n;
6313 +
6314                 if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen,
6315                                     (s64) n, &nxaddr)))
6316                         goto extendOut;
6317 @@ -1309,6 +1323,9 @@ static int dtSplitUp(tid_t tid,
6318        freeKeyName:
6319         kfree(key.name);
6320  
6321 +       /* Rollback dlimit allocation */
6322 +       if (rc && dlimit_allocation)
6323 +               DLIMIT_FREE_BLOCK(ip, dlimit_allocation);
6324         /* Rollback quota allocation */
6325         if (rc && quota_allocation)
6326                 DQUOT_FREE_BLOCK(ip, quota_allocation);
6327 @@ -1376,6 +1393,12 @@ static int dtSplitPage(tid_t tid, struct
6328                 release_metapage(rmp);
6329                 return -EDQUOT;
6330         }
6331 +       /* Allocate blocks to dlimit. */
6332 +       if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
6333 +               DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
6334 +               release_metapage(rmp);
6335 +               return -ENOSPC;
6336 +       }
6337  
6338         jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
6339  
6340 @@ -1926,6 +1949,12 @@ static int dtSplitRoot(tid_t tid,
6341                 release_metapage(rmp);
6342                 return -EDQUOT;
6343         }
6344 +       /* Allocate blocks to dlimit. */
6345 +       if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
6346 +               DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
6347 +               release_metapage(rmp);
6348 +               return -ENOSPC;
6349 +       }
6350  
6351         BT_MARK_DIRTY(rmp, ip);
6352         /*
6353 @@ -2292,6 +2321,8 @@ static int dtDeleteUp(tid_t tid, struct 
6354  
6355         xlen = lengthPXD(&fp->header.self);
6356  
6357 +       /* Free dlimit allocation. */
6358 +       DLIMIT_FREE_BLOCK(ip, xlen);
6359         /* Free quota allocation. */
6360         DQUOT_FREE_BLOCK(ip, xlen);
6361  
6362 @@ -2368,6 +2399,8 @@ static int dtDeleteUp(tid_t tid, struct 
6363  
6364                                 xlen = lengthPXD(&p->header.self);
6365  
6366 +                               /* Free dlimit allocation */
6367 +                               DLIMIT_FREE_BLOCK(ip, xlen);
6368                                 /* Free quota allocation */
6369                                 DQUOT_FREE_BLOCK(ip, xlen);
6370  
6371 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/jfs_extent.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_extent.c
6372 --- linux-2.6.17.11/fs/jfs/jfs_extent.c 2006-06-18 04:54:36 +0200
6373 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_extent.c    2006-07-09 17:06:49 +0200
6374 @@ -18,6 +18,7 @@
6375  
6376  #include <linux/fs.h>
6377  #include <linux/quotaops.h>
6378 +#include <linux/vs_dlimit.h>
6379  #include "jfs_incore.h"
6380  #include "jfs_inode.h"
6381  #include "jfs_superblock.h"
6382 @@ -146,6 +147,13 @@ extAlloc(struct inode *ip, s64 xlen, s64
6383                 mutex_unlock(&JFS_IP(ip)->commit_mutex);
6384                 return -EDQUOT;
6385         }
6386 +       /* Allocate blocks to dlimit. */
6387 +       if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
6388 +               DQUOT_FREE_BLOCK(ip, nxlen);
6389 +               dbFree(ip, nxaddr, (s64) nxlen);
6390 +               mutex_unlock(&JFS_IP(ip)->commit_mutex);
6391 +               return -ENOSPC;
6392 +       }
6393  
6394         /* determine the value of the extent flag */
6395         xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0;
6396 @@ -164,6 +172,7 @@ extAlloc(struct inode *ip, s64 xlen, s64
6397          */
6398         if (rc) {
6399                 dbFree(ip, nxaddr, nxlen);
6400 +               DLIMIT_FREE_BLOCK(ip, nxlen);
6401                 DQUOT_FREE_BLOCK(ip, nxlen);
6402                 mutex_unlock(&JFS_IP(ip)->commit_mutex);
6403                 return (rc);
6404 @@ -261,6 +270,13 @@ int extRealloc(struct inode *ip, s64 nxl
6405                 mutex_unlock(&JFS_IP(ip)->commit_mutex);
6406                 return -EDQUOT;
6407         }
6408 +       /* Allocate blocks to dlimit. */
6409 +       if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
6410 +               DQUOT_FREE_BLOCK(ip, nxlen);
6411 +               dbFree(ip, nxaddr, (s64) nxlen);
6412 +               up(&JFS_IP(ip)->commit_sem);
6413 +               return -ENOSPC;
6414 +       }
6415  
6416         delta = nxlen - xlen;
6417  
6418 @@ -297,6 +313,7 @@ int extRealloc(struct inode *ip, s64 nxl
6419                 /* extend the extent */
6420                 if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
6421                         dbFree(ip, xaddr + xlen, delta);
6422 +                       DLIMIT_FREE_BLOCK(ip, nxlen);
6423                         DQUOT_FREE_BLOCK(ip, nxlen);
6424                         goto exit;
6425                 }
6426 @@ -308,6 +325,7 @@ int extRealloc(struct inode *ip, s64 nxl
6427                  */
6428                 if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
6429                         dbFree(ip, nxaddr, nxlen);
6430 +                       DLIMIT_FREE_BLOCK(ip, nxlen);
6431                         DQUOT_FREE_BLOCK(ip, nxlen);
6432                         goto exit;
6433                 }
6434 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/jfs_filsys.h linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_filsys.h
6435 --- linux-2.6.17.11/fs/jfs/jfs_filsys.h 2005-10-28 20:49:44 +0200
6436 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_filsys.h    2006-07-09 17:06:49 +0200
6437 @@ -84,6 +84,7 @@
6438  #define JFS_DIR_INDEX          0x00200000      /* Persistant index for */
6439                                                 /* directory entries    */
6440  
6441 +#define JFS_TAGGED             0x00800000      /* Context Tagging */
6442  
6443  /*
6444   *     buffer cache configuration
6445 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/jfs_imap.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_imap.c
6446 --- linux-2.6.17.11/fs/jfs/jfs_imap.c   2006-06-18 04:54:36 +0200
6447 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_imap.c      2006-07-09 17:06:49 +0200
6448 @@ -45,6 +45,7 @@
6449  #include <linux/buffer_head.h>
6450  #include <linux/pagemap.h>
6451  #include <linux/quotaops.h>
6452 +#include <linux/vserver/tag.h>
6453  
6454  #include "jfs_incore.h"
6455  #include "jfs_inode.h"
6456 @@ -3075,6 +3076,8 @@ static int copy_from_dinode(struct dinod
6457  {
6458         struct jfs_inode_info *jfs_ip = JFS_IP(ip);
6459         struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
6460 +       uid_t uid;
6461 +       gid_t gid;
6462  
6463         jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
6464         jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
6465 @@ -3094,14 +3097,18 @@ static int copy_from_dinode(struct dinod
6466         }
6467         ip->i_nlink = le32_to_cpu(dip->di_nlink);
6468  
6469 -       jfs_ip->saved_uid = le32_to_cpu(dip->di_uid);
6470 +       uid = le32_to_cpu(dip->di_uid);
6471 +       gid = le32_to_cpu(dip->di_gid);
6472 +       ip->i_tag = INOTAG_TAG(DX_TAG(ip), uid, gid, 0);
6473 +
6474 +       jfs_ip->saved_uid = INOTAG_UID(DX_TAG(ip), uid, gid);
6475         if (sbi->uid == -1)
6476                 ip->i_uid = jfs_ip->saved_uid;
6477         else {
6478                 ip->i_uid = sbi->uid;
6479         }
6480  
6481 -       jfs_ip->saved_gid = le32_to_cpu(dip->di_gid);
6482 +       jfs_ip->saved_gid = INOTAG_GID(DX_TAG(ip), uid, gid);
6483         if (sbi->gid == -1)
6484                 ip->i_gid = jfs_ip->saved_gid;
6485         else {
6486 @@ -3167,14 +3174,12 @@ static void copy_to_dinode(struct dinode
6487         dip->di_size = cpu_to_le64(ip->i_size);
6488         dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
6489         dip->di_nlink = cpu_to_le32(ip->i_nlink);
6490 -       if (sbi->uid == -1)
6491 -               dip->di_uid = cpu_to_le32(ip->i_uid);
6492 -       else
6493 -               dip->di_uid = cpu_to_le32(jfs_ip->saved_uid);
6494 -       if (sbi->gid == -1)
6495 -               dip->di_gid = cpu_to_le32(ip->i_gid);
6496 -       else
6497 -               dip->di_gid = cpu_to_le32(jfs_ip->saved_gid);
6498 +
6499 +       dip->di_uid = cpu_to_le32(TAGINO_UID(DX_TAG(ip),
6500 +               (sbi->uid == -1) ? ip->i_uid : jfs_ip->saved_uid, ip->i_tag));
6501 +       dip->di_gid = cpu_to_le32(TAGINO_GID(DX_TAG(ip),
6502 +               (sbi->gid == -1) ? ip->i_gid : jfs_ip->saved_gid, ip->i_tag));
6503 +
6504         /*
6505          * mode2 is only needed for storing the higher order bits.
6506          * Trust i_mode for the lower order ones
6507 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/jfs_inode.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_inode.c
6508 --- linux-2.6.17.11/fs/jfs/jfs_inode.c  2006-06-18 04:54:36 +0200
6509 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_inode.c     2006-07-09 17:06:49 +0200
6510 @@ -18,6 +18,8 @@
6511  
6512  #include <linux/fs.h>
6513  #include <linux/quotaops.h>
6514 +#include <linux/vs_dlimit.h>
6515 +#include <linux/vs_tag.h>
6516  #include "jfs_incore.h"
6517  #include "jfs_inode.h"
6518  #include "jfs_filsys.h"
6519 @@ -30,19 +32,59 @@ void jfs_set_inode_flags(struct inode *i
6520  {
6521         unsigned int flags = JFS_IP(inode)->mode2;
6522  
6523 -       inode->i_flags &= ~(S_IMMUTABLE | S_APPEND |
6524 -               S_NOATIME | S_DIRSYNC | S_SYNC);
6525 +       inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
6526 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
6527  
6528         if (flags & JFS_IMMUTABLE_FL)
6529                 inode->i_flags |= S_IMMUTABLE;
6530 +       if (flags & JFS_IUNLINK_FL)
6531 +               inode->i_flags |= S_IUNLINK;
6532 +       if (flags & JFS_BARRIER_FL)
6533 +               inode->i_flags |= S_BARRIER;
6534 +
6535 +       if (flags & JFS_SYNC_FL)
6536 +               inode->i_flags |= S_SYNC;
6537         if (flags & JFS_APPEND_FL)
6538                 inode->i_flags |= S_APPEND;
6539         if (flags & JFS_NOATIME_FL)
6540                 inode->i_flags |= S_NOATIME;
6541         if (flags & JFS_DIRSYNC_FL)
6542                 inode->i_flags |= S_DIRSYNC;
6543 -       if (flags & JFS_SYNC_FL)
6544 -               inode->i_flags |= S_SYNC;
6545 +}
6546 +
6547 +int jfs_sync_flags(struct inode *inode)
6548 +{
6549 +       unsigned int oldflags, newflags;
6550 +
6551 +       oldflags = JFS_IP(inode)->mode2;
6552 +       newflags = oldflags & ~(JFS_APPEND_FL |
6553 +               JFS_IMMUTABLE_FL | JFS_IUNLINK_FL |
6554 +               JFS_BARRIER_FL | JFS_NOATIME_FL |
6555 +               JFS_SYNC_FL | JFS_DIRSYNC_FL);
6556 +
6557 +       if (IS_APPEND(inode))
6558 +               newflags |= JFS_APPEND_FL;
6559 +       if (IS_IMMUTABLE(inode))
6560 +               newflags |= JFS_IMMUTABLE_FL;
6561 +       if (IS_IUNLINK(inode))
6562 +               newflags |= JFS_IUNLINK_FL;
6563 +       if (IS_BARRIER(inode))
6564 +               newflags |= JFS_BARRIER_FL;
6565 +
6566 +       /* we do not want to copy superblock flags */
6567 +       if (inode->i_flags & S_NOATIME)
6568 +               newflags |= JFS_NOATIME_FL;
6569 +       if (inode->i_flags & S_SYNC)
6570 +               newflags |= JFS_SYNC_FL;
6571 +       if (inode->i_flags & S_DIRSYNC)
6572 +               newflags |= JFS_DIRSYNC_FL;
6573 +
6574 +       if (oldflags ^ newflags) {
6575 +               JFS_IP(inode)->mode2 = newflags;
6576 +               inode->i_ctime = CURRENT_TIME;
6577 +               mark_inode_dirty(inode);
6578 +       }
6579 +       return 0;
6580  }
6581  
6582  /*
6583 @@ -89,10 +131,17 @@ struct inode *ialloc(struct inode *paren
6584         jfs_inode->saved_uid = inode->i_uid;
6585         jfs_inode->saved_gid = inode->i_gid;
6586  
6587 +       inode->i_tag = dx_current_fstag(sb);
6588 +       if (DLIMIT_ALLOC_INODE(inode)) {
6589 +               iput(inode);
6590 +               return NULL;
6591 +       }
6592 +
6593         /*
6594          * Allocate inode to quota.
6595          */
6596         if (DQUOT_ALLOC_INODE(inode)) {
6597 +               DLIMIT_FREE_INODE(inode);
6598                 DQUOT_DROP(inode);
6599                 inode->i_flags |= S_NOQUOTA;
6600                 inode->i_nlink = 0;
6601 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/jfs_inode.h linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_inode.h
6602 --- linux-2.6.17.11/fs/jfs/jfs_inode.h  2006-06-18 04:54:36 +0200
6603 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_inode.h     2006-07-09 17:06:49 +0200
6604 @@ -31,6 +31,7 @@ extern void jfs_truncate(struct inode *)
6605  extern void jfs_truncate_nolock(struct inode *, loff_t);
6606  extern void jfs_free_zero_link(struct inode *);
6607  extern struct dentry *jfs_get_parent(struct dentry *dentry);
6608 +extern int jfs_sync_flags(struct inode *);
6609  extern void jfs_set_inode_flags(struct inode *);
6610  
6611  extern struct address_space_operations jfs_aops;
6612 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/jfs_xtree.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_xtree.c
6613 --- linux-2.6.17.11/fs/jfs/jfs_xtree.c  2006-01-03 17:29:57 +0100
6614 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/jfs_xtree.c     2006-08-17 01:24:55 +0200
6615 @@ -21,6 +21,7 @@
6616  
6617  #include <linux/fs.h>
6618  #include <linux/quotaops.h>
6619 +#include <linux/vs_dlimit.h>
6620  #include "jfs_incore.h"
6621  #include "jfs_filsys.h"
6622  #include "jfs_metapage.h"
6623 @@ -841,7 +842,12 @@ int xtInsert(tid_t tid,            /* transaction 
6624                         hint = 0;
6625                 if ((rc = DQUOT_ALLOC_BLOCK(ip, xlen)))
6626                         goto out;
6627 +               if ((rc = DLIMIT_ALLOC_BLOCK(ip, xlen))) {
6628 +                       DQUOT_FREE_BLOCK(ip, xlen);
6629 +                       goto out;
6630 +               }
6631                 if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) {
6632 +                       DLIMIT_FREE_BLOCK(ip, xlen);
6633                         DQUOT_FREE_BLOCK(ip, xlen);
6634                         goto out;
6635                 }
6636 @@ -871,6 +877,7 @@ int xtInsert(tid_t tid,             /* transaction 
6637                         /* undo data extent allocation */
6638                         if (*xaddrp == 0) {
6639                                 dbFree(ip, xaddr, (s64) xlen);
6640 +                               DLIMIT_FREE_BLOCK(ip, xlen);
6641                                 DQUOT_FREE_BLOCK(ip, xlen);
6642                         }
6643                         return rc;
6644 @@ -1231,6 +1238,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
6645         struct tlock *tlck;
6646         struct xtlock *sxtlck = NULL, *rxtlck = NULL;
6647         int quota_allocation = 0;
6648 +       int dlimit_allocation = 0;
6649  
6650         smp = split->mp;
6651         sp = XT_PAGE(ip, smp);
6652 @@ -1250,6 +1258,13 @@ xtSplitPage(tid_t tid, struct inode *ip,
6653  
6654         quota_allocation += lengthPXD(pxd);
6655  
6656 +       /* Allocate blocks to dlimit. */
6657 +       if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
6658 +              rc = -ENOSPC;
6659 +              goto clean_up;
6660 +       }
6661 +       dlimit_allocation += lengthPXD(pxd);
6662 +
6663         /*
6664          * allocate the new right page for the split
6665          */
6666 @@ -1451,6 +1466,9 @@ xtSplitPage(tid_t tid, struct inode *ip,
6667  
6668        clean_up:
6669  
6670 +       /* Rollback dlimit allocation. */
6671 +       if (dlimit_allocation)
6672 +               DLIMIT_FREE_BLOCK(ip, dlimit_allocation);
6673         /* Rollback quota allocation. */
6674         if (quota_allocation)
6675                 DQUOT_FREE_BLOCK(ip, quota_allocation);
6676 @@ -1515,6 +1533,12 @@ xtSplitRoot(tid_t tid,
6677                 release_metapage(rmp);
6678                 return -EDQUOT;
6679         }
6680 +       /* Allocate blocks to dlimit. */
6681 +       if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
6682 +               DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
6683 +               release_metapage(rmp);
6684 +               return -ENOSPC;
6685 +       }
6686  
6687         jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp);
6688  
6689 @@ -3941,6 +3965,8 @@ s64 xtTruncate(tid_t tid, struct inode *
6690         else
6691                 ip->i_size = newsize;
6692  
6693 +       /* update dlimit allocation to reflect freed blocks */
6694 +       DLIMIT_FREE_BLOCK(ip, nfreed);
6695         /* update quota allocation to reflect freed blocks */
6696         DQUOT_FREE_BLOCK(ip, nfreed);
6697  
6698 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/namei.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/namei.c
6699 --- linux-2.6.17.11/fs/jfs/namei.c      2006-06-18 04:54:36 +0200
6700 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/namei.c 2006-07-09 17:06:49 +0200
6701 @@ -20,6 +20,7 @@
6702  #include <linux/fs.h>
6703  #include <linux/ctype.h>
6704  #include <linux/quotaops.h>
6705 +#include <linux/vserver/tag.h>
6706  #include "jfs_incore.h"
6707  #include "jfs_superblock.h"
6708  #include "jfs_inode.h"
6709 @@ -1465,6 +1466,7 @@ static struct dentry *jfs_lookup(struct 
6710                 return ERR_PTR(-EACCES);
6711         }
6712  
6713 +       dx_propagate_tag(nd, ip);
6714         dentry = d_splice_alias(ip, dentry);
6715  
6716         if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2))
6717 @@ -1517,6 +1519,7 @@ struct inode_operations jfs_dir_inode_op
6718         .setattr        = jfs_setattr,
6719         .permission     = jfs_permission,
6720  #endif
6721 +       .sync_flags     = jfs_sync_flags,
6722  };
6723  
6724  const struct file_operations jfs_dir_operations = {
6725 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/super.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/super.c
6726 --- linux-2.6.17.11/fs/jfs/super.c      2006-06-18 04:54:36 +0200
6727 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/super.c 2006-07-09 17:06:49 +0200
6728 @@ -194,7 +194,8 @@ static void jfs_put_super(struct super_b
6729  enum {
6730         Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
6731         Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
6732 -       Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask
6733 +       Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
6734 +       Opt_tag, Opt_notag, Opt_tagid
6735  };
6736  
6737  static match_table_t tokens = {
6738 @@ -204,6 +205,10 @@ static match_table_t tokens = {
6739         {Opt_resize, "resize=%u"},
6740         {Opt_resize_nosize, "resize"},
6741         {Opt_errors, "errors=%s"},
6742 +       {Opt_tag, "tag"},
6743 +       {Opt_notag, "notag"},
6744 +       {Opt_tagid, "tagid=%u"},
6745 +       {Opt_tag, "tagxid"},
6746         {Opt_ignore, "noquota"},
6747         {Opt_ignore, "quota"},
6748         {Opt_usrquota, "usrquota"},
6749 @@ -338,6 +343,20 @@ static int parse_options(char *options, 
6750                         }
6751                         break;
6752                 }
6753 +#ifndef CONFIG_TAGGING_NONE
6754 +               case Opt_tag:
6755 +                       *flag |= JFS_TAGGED;
6756 +                       break;
6757 +               case Opt_notag:
6758 +                       *flag &= JFS_TAGGED;
6759 +                       break;
6760 +#endif
6761 +#ifdef CONFIG_PROPAGATE
6762 +               case Opt_tagid:
6763 +                       /* use args[0] */
6764 +                       *flag |= JFS_TAGGED;
6765 +                       break;
6766 +#endif
6767                 default:
6768                         printk("jfs: Unrecognized mount option \"%s\" "
6769                                         " or missing value\n", p);
6770 @@ -368,6 +387,13 @@ static int jfs_remount(struct super_bloc
6771         if (!parse_options(data, sb, &newLVSize, &flag)) {
6772                 return -EINVAL;
6773         }
6774 +
6775 +       if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) {
6776 +               printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n",
6777 +                       sb->s_id);
6778 +               return -EINVAL;
6779 +       }
6780 +
6781         if (newLVSize) {
6782                 if (sb->s_flags & MS_RDONLY) {
6783                         printk(KERN_ERR
6784 @@ -439,6 +465,9 @@ static int jfs_fill_super(struct super_b
6785  #ifdef CONFIG_JFS_POSIX_ACL
6786         sb->s_flags |= MS_POSIXACL;
6787  #endif
6788 +       /* map mount option tagxid */
6789 +       if (sbi->flag & JFS_TAGGED)
6790 +               sb->s_flags |= MS_TAGGED;
6791  
6792         if (newLVSize) {
6793                 printk(KERN_ERR "resize option for remount only\n");
6794 diff -NurpP --minimal linux-2.6.17.11/fs/jfs/xattr.c linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/xattr.c
6795 --- linux-2.6.17.11/fs/jfs/xattr.c      2006-06-18 04:54:36 +0200
6796 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/jfs/xattr.c 2006-07-09 17:06:49 +0200
6797 @@ -23,6 +23,7 @@
6798  #include <linux/posix_acl_xattr.h>
6799  #include <linux/quotaops.h>
6800  #include <linux/security.h>
6801 +#include <linux/vs_dlimit.h>
6802  #include "jfs_incore.h"
6803  #include "jfs_superblock.h"
6804  #include "jfs_dmap.h"
6805 @@ -263,9 +264,16 @@ static int ea_write(struct inode *ip, st
6806         if (DQUOT_ALLOC_BLOCK(ip, nblocks)) {
6807                 return -EDQUOT;
6808         }
6809 +       /* Allocate new blocks to dlimit. */
6810 +       if (DLIMIT_ALLOC_BLOCK(ip, nblocks)) {
6811 +               DQUOT_FREE_BLOCK(ip, nblocks);
6812 +               return -ENOSPC;
6813 +       }
6814  
6815         rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno);
6816         if (rc) {
6817 +               /*Rollback dlimit allocation. */
6818 +               DLIMIT_FREE_BLOCK(ip, nblocks);
6819                 /*Rollback quota allocation. */
6820                 DQUOT_FREE_BLOCK(ip, nblocks);
6821                 return rc;
6822 @@ -332,6 +340,8 @@ static int ea_write(struct inode *ip, st
6823  
6824        failed:
6825         /* Rollback quota allocation. */
6826 +       DLIMIT_FREE_BLOCK(ip, nblocks);
6827 +       /* Rollback quota allocation. */
6828         DQUOT_FREE_BLOCK(ip, nblocks);
6829  
6830         dbFree(ip, blkno, nblocks);
6831 @@ -468,6 +478,7 @@ static int ea_get(struct inode *inode, s
6832         s64 blkno;
6833         int rc;
6834         int quota_allocation = 0;
6835 +       int dlimit_allocation = 0;
6836  
6837         /* When fsck.jfs clears a bad ea, it doesn't clear the size */
6838         if (ji->ea.flag == 0)
6839 @@ -543,6 +554,12 @@ static int ea_get(struct inode *inode, s
6840  
6841                 quota_allocation = blocks_needed;
6842  
6843 +               /* Allocate new blocks to dlimit. */
6844 +               rc = -ENOSPC;
6845 +               if (DLIMIT_ALLOC_BLOCK(inode, blocks_needed))
6846 +                       goto clean_up;
6847 +               dlimit_allocation = blocks_needed;
6848 +
6849                 rc = dbAlloc(inode, INOHINT(inode), (s64) blocks_needed,
6850                              &blkno);
6851                 if (rc)
6852 @@ -599,6 +616,9 @@ static int ea_get(struct inode *inode, s
6853         return ea_size;
6854  
6855        clean_up:
6856 +       /* Rollback dlimit allocation */
6857 +       if (dlimit_allocation)
6858 +               DLIMIT_FREE_BLOCK(inode, dlimit_allocation);
6859         /* Rollback quota allocation */
6860         if (quota_allocation)
6861                 DQUOT_FREE_BLOCK(inode, quota_allocation);
6862 @@ -675,8 +695,10 @@ static int ea_put(tid_t tid, struct inod
6863         }
6864  
6865         /* If old blocks exist, they must be removed from quota allocation. */
6866 -       if (old_blocks)
6867 +       if (old_blocks) {
6868 +               DLIMIT_FREE_BLOCK(inode, old_blocks);
6869                 DQUOT_FREE_BLOCK(inode, old_blocks);
6870 +       }
6871  
6872         inode->i_ctime = CURRENT_TIME;
6873  
6874 diff -NurpP --minimal linux-2.6.17.11/fs/libfs.c linux-2.6.17.11-vs2.1.1-rc31/fs/libfs.c
6875 --- linux-2.6.17.11/fs/libfs.c  2006-06-18 04:54:36 +0200
6876 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/libfs.c     2006-07-09 17:06:49 +0200
6877 @@ -124,7 +124,8 @@ static inline unsigned char dt_type(stru
6878   * both impossible due to the lock on directory.
6879   */
6880  
6881 -int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
6882 +static inline int do_dcache_readdir_filter(struct file * filp,
6883 +       void * dirent, filldir_t filldir, int (*filter)(struct dentry *dentry))
6884  {
6885         struct dentry *dentry = filp->f_dentry;
6886         struct dentry *cursor = filp->private_data;
6887 @@ -158,6 +159,8 @@ int dcache_readdir(struct file * filp, v
6888                                 next = list_entry(p, struct dentry, d_u.d_child);
6889                                 if (d_unhashed(next) || !next->d_inode)
6890                                         continue;
6891 +                               if (filter && !filter(next))
6892 +                                       continue;
6893  
6894                                 spin_unlock(&dcache_lock);
6895                                 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)
6896 @@ -174,6 +177,18 @@ int dcache_readdir(struct file * filp, v
6897         return 0;
6898  }
6899  
6900 +int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
6901 +{
6902 +       return do_dcache_readdir_filter(filp, dirent, filldir, NULL);
6903 +}
6904 +
6905 +int dcache_readdir_filter(struct file * filp, void * dirent, filldir_t filldir,
6906 +       int (*filter)(struct dentry *))
6907 +{
6908 +       return do_dcache_readdir_filter(filp, dirent, filldir, filter);
6909 +}
6910 +
6911 +
6912  ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
6913  {
6914         return -EISDIR;
6915 @@ -623,6 +638,7 @@ EXPORT_SYMBOL(dcache_dir_close);
6916  EXPORT_SYMBOL(dcache_dir_lseek);
6917  EXPORT_SYMBOL(dcache_dir_open);
6918  EXPORT_SYMBOL(dcache_readdir);
6919 +EXPORT_SYMBOL(dcache_readdir_filter);
6920  EXPORT_SYMBOL(generic_read_dir);
6921  EXPORT_SYMBOL(get_sb_pseudo);
6922  EXPORT_SYMBOL(simple_commit_write);
6923 diff -NurpP --minimal linux-2.6.17.11/fs/lockd/clntproc.c linux-2.6.17.11-vs2.1.1-rc31/fs/lockd/clntproc.c
6924 --- linux-2.6.17.11/fs/lockd/clntproc.c 2006-06-18 04:54:36 +0200
6925 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/lockd/clntproc.c    2006-07-09 17:06:49 +0200
6926 @@ -14,6 +14,7 @@
6927  #include <linux/nfs_fs.h>
6928  #include <linux/utsname.h>
6929  #include <linux/smp_lock.h>
6930 +#include <linux/vs_cvirt.h>
6931  #include <linux/sunrpc/clnt.h>
6932  #include <linux/sunrpc/svc.h>
6933  #include <linux/lockd/lockd.h>
6934 @@ -130,11 +131,11 @@ static void nlmclnt_setlockargs(struct n
6935         nlmclnt_next_cookie(&argp->cookie);
6936         argp->state   = nsm_local_state;
6937         memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry->d_inode), sizeof(struct nfs_fh));
6938 -       lock->caller  = system_utsname.nodename;
6939 +       lock->caller  = vx_new_uts(nodename);
6940         lock->oh.data = req->a_owner;
6941         lock->oh.len  = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
6942                                 (unsigned int)fl->fl_u.nfs_fl.owner->pid,
6943 -                               system_utsname.nodename);
6944 +                               vx_new_uts(nodename));
6945         lock->svid = fl->fl_u.nfs_fl.owner->pid;
6946         lock->fl.fl_start = fl->fl_start;
6947         lock->fl.fl_end = fl->fl_end;
6948 diff -NurpP --minimal linux-2.6.17.11/fs/lockd/mon.c linux-2.6.17.11-vs2.1.1-rc31/fs/lockd/mon.c
6949 --- linux-2.6.17.11/fs/lockd/mon.c      2006-06-18 04:54:37 +0200
6950 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/lockd/mon.c 2006-07-09 17:06:49 +0200
6951 @@ -13,6 +13,7 @@
6952  #include <linux/sunrpc/svc.h>
6953  #include <linux/lockd/lockd.h>
6954  #include <linux/lockd/sm_inter.h>
6955 +#include <linux/vs_cvirt.h>
6956  
6957  
6958  #define NLMDBG_FACILITY                NLMDBG_MONITOR
6959 @@ -152,7 +153,7 @@ xdr_encode_common(struct rpc_rqst *rqstp
6960          */
6961         sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(argp->addr));
6962         if (!(p = xdr_encode_string(p, buffer))
6963 -        || !(p = xdr_encode_string(p, system_utsname.nodename)))
6964 +        || !(p = xdr_encode_string(p, vx_new_uts(nodename))))
6965                 return ERR_PTR(-EIO);
6966         *p++ = htonl(argp->prog);
6967         *p++ = htonl(argp->vers);
6968 diff -NurpP --minimal linux-2.6.17.11/fs/locks.c linux-2.6.17.11-vs2.1.1-rc31/fs/locks.c
6969 --- linux-2.6.17.11/fs/locks.c  2006-06-18 04:54:37 +0200
6970 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/locks.c     2006-08-06 06:03:34 +0200
6971 @@ -125,6 +125,7 @@
6972  #include <linux/syscalls.h>
6973  #include <linux/time.h>
6974  #include <linux/rcupdate.h>
6975 +#include <linux/vs_limit.h>
6976  
6977  #include <asm/semaphore.h>
6978  #include <asm/uaccess.h>
6979 @@ -147,6 +148,8 @@ static kmem_cache_t *filelock_cache __re
6980  /* Allocate an empty lock structure. */
6981  static struct file_lock *locks_alloc_lock(void)
6982  {
6983 +       if (!vx_locks_avail(1))
6984 +               return NULL;
6985         return kmem_cache_alloc(filelock_cache, SLAB_KERNEL);
6986  }
6987  
6988 @@ -172,6 +175,7 @@ static void locks_free_lock(struct file_
6989         BUG_ON(!list_empty(&fl->fl_block));
6990         BUG_ON(!list_empty(&fl->fl_link));
6991  
6992 +       vx_locks_dec(fl);
6993         locks_release_private(fl);
6994         kmem_cache_free(filelock_cache, fl);
6995  }
6996 @@ -191,6 +195,7 @@ void locks_init_lock(struct file_lock *f
6997         fl->fl_start = fl->fl_end = 0;
6998         fl->fl_ops = NULL;
6999         fl->fl_lmops = NULL;
7000 +       fl->fl_xid = -1;
7001  }
7002  
7003  EXPORT_SYMBOL(locks_init_lock);
7004 @@ -248,6 +253,7 @@ void locks_copy_lock(struct file_lock *n
7005         new->fl_file = fl->fl_file;
7006         new->fl_ops = fl->fl_ops;
7007         new->fl_lmops = fl->fl_lmops;
7008 +       new->fl_xid = fl->fl_xid;
7009  
7010         locks_copy_private(new, fl);
7011  }
7012 @@ -286,6 +292,11 @@ static int flock_make_lock(struct file *
7013         fl->fl_flags = FL_FLOCK;
7014         fl->fl_type = type;
7015         fl->fl_end = OFFSET_MAX;
7016 +
7017 +       vxd_assert(filp->f_xid == vx_current_xid(),
7018 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
7019 +       fl->fl_xid = filp->f_xid;
7020 +       vx_locks_inc(fl);
7021         
7022         *lock = fl;
7023         return 0;
7024 @@ -451,6 +462,7 @@ static int lease_init(struct file *filp,
7025  
7026         fl->fl_owner = current->files;
7027         fl->fl_pid = current->tgid;
7028 +       fl->fl_xid = vx_current_xid();
7029  
7030         fl->fl_file = filp;
7031         fl->fl_flags = FL_LEASE;
7032 @@ -470,6 +482,11 @@ static int lease_alloc(struct file *filp
7033         if (fl == NULL)
7034                 goto out;
7035  
7036 +       fl->fl_xid = vx_current_xid();
7037 +       if (filp)
7038 +               vxd_assert(filp->f_xid == fl->fl_xid,
7039 +                       "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid);
7040 +       vx_locks_inc(fl);
7041         error = lease_init(filp, type, fl);
7042         if (error) {
7043                 locks_free_lock(fl);
7044 @@ -780,6 +797,7 @@ static int flock_lock_file(struct file *
7045                 goto out;
7046         }
7047         locks_copy_lock(new_fl, request);
7048 +       vx_locks_inc(new_fl);
7049         locks_insert_lock(&inode->i_flock, new_fl);
7050         new_fl = NULL;
7051         error = 0;
7052 @@ -791,7 +809,8 @@ out:
7053         return error;
7054  }
7055  
7056 -static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
7057 +static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request,
7058 +       struct file_lock *conflock, xid_t xid)
7059  {
7060         struct file_lock *fl;
7061         struct file_lock *new_fl, *new_fl2;
7062 @@ -800,12 +819,18 @@ static int __posix_lock_file_conf(struct
7063         struct file_lock **before;
7064         int error, added = 0;
7065  
7066 +       vxd_assert(xid == vx_current_xid(),
7067 +               "xid(%d) == current(%d)", xid, vx_current_xid());
7068         /*
7069          * We may need two file_lock structures for this operation,
7070          * so we get them in advance to avoid races.
7071          */
7072         new_fl = locks_alloc_lock();
7073 +       new_fl->fl_xid = xid;
7074 +       vx_locks_inc(new_fl);
7075         new_fl2 = locks_alloc_lock();
7076 +       new_fl2->fl_xid = xid;
7077 +       vx_locks_inc(new_fl2);
7078  
7079         lock_kernel();
7080         if (request->fl_type != F_UNLCK) {
7081 @@ -986,7 +1011,8 @@ static int __posix_lock_file_conf(struct
7082   */
7083  int posix_lock_file(struct file *filp, struct file_lock *fl)
7084  {
7085 -       return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, NULL);
7086 +       return __posix_lock_file_conf(filp->f_dentry->d_inode,
7087 +               fl, NULL, filp->f_xid);
7088  }
7089  EXPORT_SYMBOL(posix_lock_file);
7090  
7091 @@ -1001,7 +1027,8 @@ EXPORT_SYMBOL(posix_lock_file);
7092  int posix_lock_file_conf(struct file *filp, struct file_lock *fl,
7093                         struct file_lock *conflock)
7094  {
7095 -       return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, conflock);
7096 +       return __posix_lock_file_conf(filp->f_dentry->d_inode,
7097 +               fl, conflock, filp->f_xid);
7098  }
7099  EXPORT_SYMBOL(posix_lock_file_conf);
7100  
7101 @@ -1091,7 +1118,7 @@ int locks_mandatory_area(int read_write,
7102         fl.fl_end = offset + count - 1;
7103  
7104         for (;;) {
7105 -               error = __posix_lock_file_conf(inode, &fl, NULL);
7106 +               error = __posix_lock_file_conf(inode, &fl, NULL, filp->f_xid);
7107                 if (error != -EAGAIN)
7108                         break;
7109                 if (!(fl.fl_flags & FL_SLEEP))
7110 @@ -1651,6 +1678,11 @@ int fcntl_setlk(unsigned int fd, struct 
7111         if (file_lock == NULL)
7112                 return -ENOLCK;
7113  
7114 +       vxd_assert(filp->f_xid == vx_current_xid(),
7115 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
7116 +       file_lock->fl_xid = filp->f_xid;
7117 +       vx_locks_inc(file_lock);
7118 +
7119         /*
7120          * This might block, so we do it before checking the inode.
7121          */
7122 @@ -1794,6 +1826,11 @@ int fcntl_setlk64(unsigned int fd, struc
7123         if (file_lock == NULL)
7124                 return -ENOLCK;
7125  
7126 +       vxd_assert(filp->f_xid == vx_current_xid(),
7127 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
7128 +       file_lock->fl_xid = filp->f_xid;
7129 +       vx_locks_inc(file_lock);
7130 +
7131         /*
7132          * This might block, so we do it before checking the inode.
7133          */
7134 @@ -2104,6 +2141,10 @@ int get_locks_status(char *buffer, char 
7135         list_for_each(tmp, &file_lock_list) {
7136                 struct list_head *btmp;
7137                 struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
7138 +
7139 +               if (!vx_check(fl->fl_xid, VX_WATCH_P|VX_IDENT))
7140 +                       continue;
7141 +
7142                 lock_get_status(q, fl, ++i, "");
7143                 move_lock_status(&q, &pos, offset);
7144  
7145 diff -NurpP --minimal linux-2.6.17.11/fs/namei.c linux-2.6.17.11-vs2.1.1-rc31/fs/namei.c
7146 --- linux-2.6.17.11/fs/namei.c  2006-08-25 00:25:37 +0200
7147 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/namei.c     2006-08-17 01:24:55 +0200
7148 @@ -32,6 +32,10 @@
7149  #include <linux/file.h>
7150  #include <linux/fcntl.h>
7151  #include <linux/namei.h>
7152 +#include <linux/proc_fs.h>
7153 +#include <linux/vserver/inode.h>
7154 +#include <linux/vs_tag.h>
7155 +#include <linux/vserver/debug.h>
7156  #include <asm/namei.h>
7157  #include <asm/uaccess.h>
7158  
7159 @@ -225,6 +229,24 @@ int generic_permission(struct inode *ino
7160         return -EACCES;
7161  }
7162  
7163 +static inline int dx_permission(struct inode *inode, int mask, struct nameidata *nd)
7164 +{
7165 +       if (IS_BARRIER(inode) && !vx_check(0, VX_ADMIN)) {
7166 +               vxwprintk(1, "xid=%d did hit the barrier.",
7167 +                       vx_current_xid());
7168 +               return -EACCES;
7169 +       }
7170 +       if (inode->i_tag == 0)
7171 +               return 0;
7172 +       if (dx_check(inode->i_tag, DX_ADMIN|DX_WATCH|DX_IDENT))
7173 +               return 0;
7174 +
7175 +       vxwprintk(1, "xid=%d denied access to %p[#%d,%lu] »%s«.",
7176 +               vx_current_xid(), inode, inode->i_tag, inode->i_ino,
7177 +               vxd_cond_path(nd));
7178 +       return -EACCES;
7179 +}
7180 +
7181  int permission(struct inode *inode, int mask, struct nameidata *nd)
7182  {
7183         int retval, submask;
7184 @@ -235,20 +257,22 @@ int permission(struct inode *inode, int 
7185                 /*
7186                  * Nobody gets write access to a read-only fs.
7187                  */
7188 -               if (IS_RDONLY(inode) &&
7189 +               if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
7190                     (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
7191                         return -EROFS;
7192  
7193                 /*
7194                  * Nobody gets write access to an immutable file.
7195                  */
7196 -               if (IS_IMMUTABLE(inode))
7197 +               if (IS_IMMUTABLE(inode) && !IS_COW(inode))
7198                         return -EACCES;
7199         }
7200  
7201  
7202         /* Ordinary permission routines do not understand MAY_APPEND. */
7203         submask = mask & ~MAY_APPEND;
7204 +       if ((retval = dx_permission(inode, mask, nd)))
7205 +               return retval;
7206         if (inode->i_op && inode->i_op->permission)
7207                 retval = inode->i_op->permission(inode, submask, nd);
7208         else
7209 @@ -705,7 +729,8 @@ static __always_inline void follow_dotdo
7210                 if (nd->dentry == current->fs->root &&
7211                     nd->mnt == current->fs->rootmnt) {
7212                          read_unlock(&current->fs->lock);
7213 -                       break;
7214 +                       /* for sane '/' avoid follow_mount() */
7215 +                       return;
7216                 }
7217                  read_unlock(&current->fs->lock);
7218                 spin_lock(&dcache_lock);
7219 @@ -742,16 +767,34 @@ static int do_lookup(struct nameidata *n
7220  {
7221         struct vfsmount *mnt = nd->mnt;
7222         struct dentry *dentry = __d_lookup(nd->dentry, name);
7223 +       struct inode *inode;
7224  
7225         if (!dentry)
7226                 goto need_lookup;
7227         if (dentry->d_op && dentry->d_op->d_revalidate)
7228                 goto need_revalidate;
7229 +       inode = dentry->d_inode;
7230 +       if (!inode)
7231 +               goto done;
7232 +       if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
7233 +               struct proc_dir_entry *de = PDE(inode);
7234 +
7235 +               if (de && !vx_hide_check(0, de->vx_flags))
7236 +                       goto hidden;
7237 +       }
7238 +       if (!dx_check(inode->i_tag, DX_WATCH|DX_ADMIN|DX_HOSTID|DX_IDENT))
7239 +               goto hidden;
7240  done:
7241         path->mnt = mnt;
7242         path->dentry = dentry;
7243         __follow_mount(path);
7244         return 0;
7245 +hidden:
7246 +       vxwprintk(1, "xid=%d did lookup hidden %p[#%d,%lu] »%s«.",
7247 +               vx_current_xid(), inode, inode->i_tag, inode->i_ino,
7248 +               vxd_path(dentry, mnt));
7249 +       dput(dentry);
7250 +       return -ENOENT;
7251  
7252  need_lookup:
7253         dentry = real_lookup(nd->dentry, name, nd);
7254 @@ -1349,7 +1392,8 @@ static inline int check_sticky(struct in
7255   * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
7256   *     nfs_async_unlink().
7257   */
7258 -static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
7259 +static int may_delete(struct inode *dir, struct dentry *victim,
7260 +       int isdir, struct nameidata *nd)
7261  {
7262         int error;
7263  
7264 @@ -1359,13 +1403,13 @@ static int may_delete(struct inode *dir,
7265         BUG_ON(victim->d_parent->d_inode != dir);
7266         audit_inode_child(victim->d_name.name, victim->d_inode, dir->i_ino);
7267  
7268 -       error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
7269 +       error = permission(dir,MAY_WRITE | MAY_EXEC, nd);
7270         if (error)
7271                 return error;
7272         if (IS_APPEND(dir))
7273                 return -EPERM;
7274         if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
7275 -           IS_IMMUTABLE(victim->d_inode))
7276 +               IS_IXORUNLINK(victim->d_inode))
7277                 return -EPERM;
7278         if (isdir) {
7279                 if (!S_ISDIR(victim->d_inode->i_mode))
7280 @@ -1496,6 +1540,14 @@ int may_open(struct nameidata *nd, int a
7281         if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
7282                 return -EISDIR;
7283  
7284 +#ifdef CONFIG_VSERVER_COWBL
7285 +       if (IS_COW(inode) && (flag & FMODE_WRITE)) {
7286 +               if (IS_COW_LINK(inode))
7287 +                       return -EMLINK;
7288 +               inode->i_flags &= ~(S_IUNLINK|S_IMMUTABLE);
7289 +               mark_inode_dirty(inode);
7290 +       }
7291 +#endif
7292         error = vfs_permission(nd, acc_mode);
7293         if (error)
7294                 return error;
7295 @@ -1512,7 +1564,8 @@ int may_open(struct nameidata *nd, int a
7296                         return -EACCES;
7297  
7298                 flag &= ~O_TRUNC;
7299 -       } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
7300 +       } else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
7301 +               && (flag & FMODE_WRITE))
7302                 return -EROFS;
7303         /*
7304          * An append-only file must be opened in append mode for writing.
7305 @@ -1560,6 +1613,8 @@ int may_open(struct nameidata *nd, int a
7306         return 0;
7307  }
7308  
7309 +int cow_break_link(struct dentry *dentry, const char *pathname);
7310 +
7311  /*
7312   *     open_namei()
7313   *
7314 @@ -1582,6 +1637,11 @@ int open_namei(int dfd, const char *path
7315         struct dentry *dir;
7316         int count = 0;
7317  
7318 +#ifdef CONFIG_VSERVER_COWBL
7319 +       int rflag = flag;
7320 +       int rmode = mode;
7321 +restart:
7322 +#endif
7323         acc_mode = ACC_MODE(flag);
7324  
7325         /* O_TRUNC implies we need access checks for write permissions */
7326 @@ -1681,6 +1741,19 @@ do_last:
7327                 goto exit;
7328  ok:
7329         error = may_open(nd, acc_mode, flag);
7330 +#ifdef CONFIG_VSERVER_COWBL
7331 +       if (error == -EMLINK) {
7332 +               error = cow_break_link(path.dentry, pathname);
7333 +               if (error)
7334 +                       goto exit;
7335 +               release_open_intent(nd);
7336 +               path_release(nd);
7337 +               vxdprintk(VXD_CBIT(misc, 2), "restarting open_namei() ...");
7338 +               flag = rflag;
7339 +               mode = rmode;
7340 +               goto restart;
7341 +       }
7342 +#endif
7343         if (error)
7344                 goto exit;
7345         return 0;
7346 @@ -1790,9 +1863,10 @@ fail:
7347  }
7348  EXPORT_SYMBOL_GPL(lookup_create);
7349  
7350 -int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
7351 +int vfs_mknod(struct inode *dir, struct dentry *dentry,
7352 +       int mode, dev_t dev, struct nameidata *nd)
7353  {
7354 -       int error = may_create(dir, dentry, NULL);
7355 +       int error = may_create(dir, dentry, nd);
7356  
7357         if (error)
7358                 return error;
7359 @@ -1842,11 +1916,12 @@ asmlinkage long sys_mknodat(int dfd, con
7360                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
7361                         break;
7362                 case S_IFCHR: case S_IFBLK:
7363 -                       error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
7364 -                                       new_decode_dev(dev));
7365 +                       error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
7366 +                                       new_decode_dev(dev), &nd);
7367                         break;
7368                 case S_IFIFO: case S_IFSOCK:
7369 -                       error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
7370 +                       error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
7371 +                                       0, &nd);
7372                         break;
7373                 case S_IFDIR:
7374                         error = -EPERM;
7375 @@ -1869,9 +1944,10 @@ asmlinkage long sys_mknod(const char __u
7376         return sys_mknodat(AT_FDCWD, filename, mode, dev);
7377  }
7378  
7379 -int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
7380 +int vfs_mkdir(struct inode *dir, struct dentry *dentry,
7381 +       int mode, struct nameidata *nd)
7382  {
7383 -       int error = may_create(dir, dentry, NULL);
7384 +       int error = may_create(dir, dentry, nd);
7385  
7386         if (error)
7387                 return error;
7388 @@ -1910,7 +1986,8 @@ asmlinkage long sys_mkdirat(int dfd, con
7389                 if (!IS_ERR(dentry)) {
7390                         if (!IS_POSIXACL(nd.dentry->d_inode))
7391                                 mode &= ~current->fs->umask;
7392 -                       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
7393 +                       error = vfs_mkdir(nd.dentry->d_inode, dentry,
7394 +                               mode, &nd);
7395                         dput(dentry);
7396                 }
7397                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
7398 @@ -1955,9 +2032,10 @@ void dentry_unhash(struct dentry *dentry
7399         spin_unlock(&dcache_lock);
7400  }
7401  
7402 -int vfs_rmdir(struct inode *dir, struct dentry *dentry)
7403 +int vfs_rmdir(struct inode *dir, struct dentry *dentry,
7404 +       struct nameidata *nd)
7405  {
7406 -       int error = may_delete(dir, dentry, 1);
7407 +       int error = may_delete(dir, dentry, 1, nd);
7408  
7409         if (error)
7410                 return error;
7411 @@ -2018,7 +2096,7 @@ static long do_rmdir(int dfd, const char
7412         dentry = lookup_hash(&nd);
7413         error = PTR_ERR(dentry);
7414         if (!IS_ERR(dentry)) {
7415 -               error = vfs_rmdir(nd.dentry->d_inode, dentry);
7416 +               error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
7417                 dput(dentry);
7418         }
7419         mutex_unlock(&nd.dentry->d_inode->i_mutex);
7420 @@ -2034,9 +2112,10 @@ asmlinkage long sys_rmdir(const char __u
7421         return do_rmdir(AT_FDCWD, pathname);
7422  }
7423  
7424 -int vfs_unlink(struct inode *dir, struct dentry *dentry)
7425 +int vfs_unlink(struct inode *dir, struct dentry *dentry,
7426 +       struct nameidata *nd)
7427  {
7428 -       int error = may_delete(dir, dentry, 0);
7429 +       int error = may_delete(dir, dentry, 0, nd);
7430  
7431         if (error)
7432                 return error;
7433 @@ -2098,7 +2177,7 @@ static long do_unlinkat(int dfd, const c
7434                 inode = dentry->d_inode;
7435                 if (inode)
7436                         atomic_inc(&inode->i_count);
7437 -               error = vfs_unlink(nd.dentry->d_inode, dentry);
7438 +               error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
7439         exit2:
7440                 dput(dentry);
7441         }
7442 @@ -2133,9 +2212,10 @@ asmlinkage long sys_unlink(const char __
7443         return do_unlinkat(AT_FDCWD, pathname);
7444  }
7445  
7446 -int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
7447 +int vfs_symlink(struct inode *dir, struct dentry *dentry,
7448 +       const char *oldname, int mode, struct nameidata *nd)
7449  {
7450 -       int error = may_create(dir, dentry, NULL);
7451 +       int error = may_create(dir, dentry, nd);
7452  
7453         if (error)
7454                 return error;
7455 @@ -2176,7 +2256,8 @@ asmlinkage long sys_symlinkat(const char
7456                 dentry = lookup_create(&nd, 0);
7457                 error = PTR_ERR(dentry);
7458                 if (!IS_ERR(dentry)) {
7459 -                       error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
7460 +                       error = vfs_symlink(nd.dentry->d_inode, dentry,
7461 +                               from, S_IALLUGO, &nd);
7462                         dput(dentry);
7463                 }
7464                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
7465 @@ -2193,7 +2274,8 @@ asmlinkage long sys_symlink(const char _
7466         return sys_symlinkat(oldname, AT_FDCWD, newname);
7467  }
7468  
7469 -int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
7470 +int vfs_link(struct dentry *old_dentry, struct inode *dir,
7471 +       struct dentry *new_dentry, struct nameidata *nd)
7472  {
7473         struct inode *inode = old_dentry->d_inode;
7474         int error;
7475 @@ -2201,7 +2283,7 @@ int vfs_link(struct dentry *old_dentry, 
7476         if (!inode)
7477                 return -ENOENT;
7478  
7479 -       error = may_create(dir, new_dentry, NULL);
7480 +       error = may_create(dir, new_dentry, nd);
7481         if (error)
7482                 return error;
7483  
7484 @@ -2211,7 +2293,7 @@ int vfs_link(struct dentry *old_dentry, 
7485         /*
7486          * A link to an append-only or immutable file cannot be created.
7487          */
7488 -       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
7489 +       if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
7490                 return -EPERM;
7491         if (!dir->i_op || !dir->i_op->link)
7492                 return -EPERM;
7493 @@ -2268,7 +2350,8 @@ asmlinkage long sys_linkat(int olddfd, c
7494         new_dentry = lookup_create(&nd, 0);
7495         error = PTR_ERR(new_dentry);
7496         if (!IS_ERR(new_dentry)) {
7497 -               error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
7498 +               error = vfs_link(old_nd.dentry, nd.dentry->d_inode,
7499 +                       new_dentry, &nd);
7500                 dput(new_dentry);
7501         }
7502         mutex_unlock(&nd.dentry->d_inode->i_mutex);
7503 @@ -2400,14 +2483,14 @@ int vfs_rename(struct inode *old_dir, st
7504         if (old_dentry->d_inode == new_dentry->d_inode)
7505                 return 0;
7506   
7507 -       error = may_delete(old_dir, old_dentry, is_dir);
7508 +       error = may_delete(old_dir, old_dentry, is_dir, NULL);
7509         if (error)
7510                 return error;
7511  
7512         if (!new_dentry->d_inode)
7513                 error = may_create(new_dir, new_dentry, NULL);
7514         else
7515 -               error = may_delete(new_dir, new_dentry, is_dir);
7516 +               error = may_delete(new_dir, new_dentry, is_dir, NULL);
7517         if (error)
7518                 return error;
7519  
7520 @@ -2485,6 +2568,9 @@ static int do_rename(int olddfd, const c
7521         error = -EINVAL;
7522         if (old_dentry == trap)
7523                 goto exit4;
7524 +       error = -EROFS;
7525 +       if (MNT_IS_RDONLY(newnd.mnt))
7526 +               goto exit4;
7527         new_dentry = lookup_hash(&newnd);
7528         error = PTR_ERR(new_dentry);
7529         if (IS_ERR(new_dentry))
7530 @@ -2578,6 +2664,125 @@ int vfs_follow_link(struct nameidata *nd
7531         return __vfs_follow_link(nd, link);
7532  }
7533  
7534 +
7535 +#ifdef CONFIG_VSERVER_COWBL
7536 +
7537 +#include <linux/file.h>
7538 +
7539 +int cow_break_link(struct dentry *dentry, const char *pathname)
7540 +{
7541 +       int err = -EMLINK;
7542 +       int ret, mode, pathlen;
7543 +       struct nameidata old_nd, dir_nd;
7544 +       struct dentry *old_dentry, *new_dentry;
7545 +       struct vfsmount *old_mnt, *new_mnt;
7546 +       struct file *old_file;
7547 +       struct file *new_file;
7548 +       char *to, *path, pad='\251';
7549 +       loff_t size;
7550 +
7551 +       vxdprintk(VXD_CBIT(misc, 2),
7552 +               "cow_break_link(%p,»%s«)", dentry, pathname);
7553 +       path = kmalloc(PATH_MAX, GFP_KERNEL);
7554 +
7555 +       ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd);
7556 +       vxdprintk(VXD_CBIT(misc, 2), "path_lookup(old): %d", ret);
7557 +       old_dentry = old_nd.dentry;
7558 +       old_mnt = old_nd.mnt;
7559 +       mode = old_dentry->d_inode->i_mode;
7560 +
7561 +       to = d_path(old_dentry, old_mnt, path, PATH_MAX-2);
7562 +       pathlen = strlen(to);
7563 +       vxdprintk(VXD_CBIT(misc, 2), "old path »%s«", to);
7564 +
7565 +       to[pathlen+1] = 0;
7566 +retry:
7567 +       to[pathlen] = pad--;
7568 +       if (pad <= '\240')
7569 +               goto out_rel_old;
7570 +
7571 +       vxdprintk(VXD_CBIT(misc, 2), "temp copy »%s«", to);
7572 +       ret = path_lookup(to,
7573 +               LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, &dir_nd);
7574 +
7575 +       /* this puppy downs the inode sem */
7576 +       new_dentry = lookup_create(&dir_nd, 0);
7577 +       vxdprintk(VXD_CBIT(misc, 2),
7578 +               "lookup_create(new): %p", new_dentry);
7579 +       if (!new_dentry) {
7580 +               path_release(&dir_nd);
7581 +               goto retry;
7582 +       }
7583 +
7584 +       ret = vfs_create(dir_nd.dentry->d_inode, new_dentry, mode, &dir_nd);
7585 +       vxdprintk(VXD_CBIT(misc, 2),
7586 +               "vfs_create(new): %d", ret);
7587 +       if (ret == -EEXIST) {
7588 +
7589 +               mutex_unlock(&dir_nd.dentry->d_inode->i_mutex);
7590 +               dput(new_dentry);
7591 +               path_release(&dir_nd);
7592 +               goto retry;
7593 +       }
7594 +
7595 +       new_mnt = dir_nd.mnt;
7596 +
7597 +       dget(old_dentry);
7598 +       mntget(old_mnt);
7599 +       /* this one cleans up the dentry in case of failure */
7600 +       old_file = dentry_open(old_dentry, old_mnt, O_RDONLY);
7601 +       vxdprintk(VXD_CBIT(misc, 2),
7602 +               "dentry_open(old): %p", old_file);
7603 +       if (!old_file)
7604 +               goto out_rel_both;
7605 +
7606 +       dget(new_dentry);
7607 +       mntget(new_mnt);
7608 +       /* this one cleans up the dentry in case of failure */
7609 +       new_file = dentry_open(new_dentry, new_mnt, O_WRONLY);
7610 +       vxdprintk(VXD_CBIT(misc, 2),
7611 +               "dentry_open(new): %p", new_file);
7612 +       if (!new_file)
7613 +               goto out_fput_old;
7614 +
7615 +       size = i_size_read(old_file->f_dentry->d_inode);
7616 +       ret = vfs_sendfile(new_file, old_file, NULL, size, 0);
7617 +       vxdprintk(VXD_CBIT(misc, 2), "vfs_sendfile: %d", ret);
7618 +
7619 +       if (ret < 0)
7620 +               goto out_fput_both;
7621 +
7622 +       ret = vfs_rename(dir_nd.dentry->d_inode, new_dentry,
7623 +               old_nd.dentry->d_parent->d_inode, old_dentry);
7624 +       vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
7625 +       if (!ret)
7626 +               err = 0;
7627 +
7628 +out_fput_both:
7629 +       vxdprintk(VXD_CBIT(misc, 3),
7630 +               "fput(new_file=%p[#%d])", new_file,
7631 +               atomic_read(&new_file->f_count));
7632 +       fput(new_file);
7633 +
7634 +out_fput_old:
7635 +       vxdprintk(VXD_CBIT(misc, 3),
7636 +               "fput(old_file=%p[#%d])", old_file,
7637 +               atomic_read(&old_file->f_count));
7638 +       fput(old_file);
7639 +
7640 +out_rel_both:
7641 +       mutex_unlock(&dir_nd.dentry->d_inode->i_mutex);
7642 +       dput(new_dentry);
7643 +
7644 +       path_release(&dir_nd);
7645 +out_rel_old:
7646 +       path_release(&old_nd);
7647 +       kfree(path);
7648 +       return err;
7649 +}
7650 +
7651 +#endif
7652 +
7653  /* get the link contents into pagecache */
7654  static char *page_getlink(struct dentry * dentry, struct page **ppage)
7655  {
7656 diff -NurpP --minimal linux-2.6.17.11/fs/namespace.c linux-2.6.17.11-vs2.1.1-rc31/fs/namespace.c
7657 --- linux-2.6.17.11/fs/namespace.c      2006-06-18 04:54:37 +0200
7658 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/namespace.c 2006-08-06 05:54:54 +0200
7659 @@ -23,6 +23,8 @@
7660  #include <linux/namei.h>
7661  #include <linux/security.h>
7662  #include <linux/mount.h>
7663 +#include <linux/vserver/namespace.h>
7664 +#include <linux/vserver/tag.h>
7665  #include <asm/uaccess.h>
7666  #include <asm/unistd.h>
7667  #include "pnode.h"
7668 @@ -241,6 +243,7 @@ static struct vfsmount *clone_mnt(struct
7669                 mnt->mnt_root = dget(root);
7670                 mnt->mnt_mountpoint = mnt->mnt_root;
7671                 mnt->mnt_parent = mnt;
7672 +               mnt->mnt_tag = old->mnt_tag;
7673  
7674                 if (flag & CL_SLAVE) {
7675                         list_add(&mnt->mnt_slave, &old->mnt_slave_list);
7676 @@ -349,43 +352,85 @@ static inline void mangle(struct seq_fil
7677         seq_escape(m, s, " \t\n\\");
7678  }
7679  
7680 +static int mnt_is_reachable(struct vfsmount *mnt)
7681 +{
7682 +       struct vfsmount *root_mnt;
7683 +       struct dentry *root, *point;
7684 +       int ret;
7685 +
7686 +       if (mnt == mnt->mnt_namespace->root)
7687 +               return 1;
7688 +
7689 +       spin_lock(&dcache_lock);
7690 +       root_mnt = current->fs->rootmnt;
7691 +       root = current->fs->root;
7692 +       point = root;
7693 +
7694 +       while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) {
7695 +               point = mnt->mnt_mountpoint;
7696 +               mnt = mnt->mnt_parent;
7697 +       }
7698 +
7699 +       ret = (mnt == root_mnt) && is_subdir(point, root);
7700 +
7701 +       spin_unlock(&dcache_lock);
7702 +
7703 +       return ret;
7704 +}
7705 +
7706  static int show_vfsmnt(struct seq_file *m, void *v)
7707  {
7708         struct vfsmount *mnt = v;
7709         int err = 0;
7710         static struct proc_fs_info {
7711 -               int flag;
7712 -               char *str;
7713 +               int s_flag;
7714 +               int mnt_flag;
7715 +               char *set_str;
7716 +               char *unset_str;
7717         } fs_info[] = {
7718 -               { MS_SYNCHRONOUS, ",sync" },
7719 -               { MS_DIRSYNC, ",dirsync" },
7720 -               { MS_MANDLOCK, ",mand" },
7721 -               { 0, NULL }
7722 -       };
7723 -       static struct proc_fs_info mnt_info[] = {
7724 -               { MNT_NOSUID, ",nosuid" },
7725 -               { MNT_NODEV, ",nodev" },
7726 -               { MNT_NOEXEC, ",noexec" },
7727 -               { MNT_NOATIME, ",noatime" },
7728 -               { MNT_NODIRATIME, ",nodiratime" },
7729 -               { 0, NULL }
7730 +               { MS_RDONLY, MNT_RDONLY, "ro", "rw" },
7731 +               { MS_SYNCHRONOUS, 0, ",sync", NULL },
7732 +               { MS_DIRSYNC, 0, ",dirsync", NULL },
7733 +               { MS_MANDLOCK, 0, ",mand", NULL },
7734 +               { MS_TAGGED, 0, ",tag", NULL },
7735 +               { MS_NOATIME, MNT_NOATIME, ",noatime", NULL },
7736 +               { MS_NODIRATIME, MNT_NODIRATIME, ",nodiratime", NULL },
7737 +               { 0, MNT_NOSUID, ",nosuid", NULL },
7738 +               { 0, MNT_NODEV, ",nodev", NULL },
7739 +               { 0, MNT_NOEXEC, ",noexec", NULL },
7740 +               { 0, 0, NULL, NULL }
7741         };
7742 -       struct proc_fs_info *fs_infop;
7743 +       struct proc_fs_info *p;
7744 +       unsigned long s_flags = mnt->mnt_sb->s_flags;
7745 +       int mnt_flags = mnt->mnt_flags;
7746  
7747 -       mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
7748 -       seq_putc(m, ' ');
7749 -       seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
7750 -       seq_putc(m, ' ');
7751 -       mangle(m, mnt->mnt_sb->s_type->name);
7752 -       seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
7753 -       for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
7754 -               if (mnt->mnt_sb->s_flags & fs_infop->flag)
7755 -                       seq_puts(m, fs_infop->str);
7756 +       if (vx_flags(VXF_HIDE_MOUNT, 0))
7757 +               return 0;
7758 +       if (!mnt_is_reachable(mnt) && !vx_check(0, VX_WATCH_P))
7759 +               return 0;
7760 +
7761 +       if (!vx_check(0, VX_ADMIN|VX_WATCH) &&
7762 +               mnt == current->fs->rootmnt) {
7763 +               seq_puts(m, "/dev/root / ");
7764 +       } else {
7765 +               mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
7766 +               seq_putc(m, ' ');
7767 +               seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
7768 +               seq_putc(m, ' ');
7769         }
7770 -       for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
7771 -               if (mnt->mnt_flags & fs_infop->flag)
7772 -                       seq_puts(m, fs_infop->str);
7773 +       mangle(m, mnt->mnt_sb->s_type->name);
7774 +       seq_putc(m, ' ');
7775 +       for (p = fs_info; (p->s_flag | p->mnt_flag) ; p++) {
7776 +               if ((s_flags & p->s_flag) || (mnt_flags & p->mnt_flag)) {
7777 +                       if (p->set_str)
7778 +                               seq_puts(m, p->set_str);
7779 +               } else {
7780 +                       if (p->unset_str)
7781 +                               seq_puts(m, p->unset_str);
7782 +               }
7783         }
7784 +       if (mnt->mnt_flags & MNT_TAGID)
7785 +               seq_printf(m, ",tag=%d", mnt->mnt_tag);
7786         if (mnt->mnt_sb->s_op->show_options)
7787                 err = mnt->mnt_sb->s_op->show_options(m, mnt);
7788         seq_puts(m, " 0 0\n");
7789 @@ -404,17 +449,27 @@ static int show_vfsstat(struct seq_file 
7790         struct vfsmount *mnt = v;
7791         int err = 0;
7792  
7793 -       /* device */
7794 -       if (mnt->mnt_devname) {
7795 -               seq_puts(m, "device ");
7796 -               mangle(m, mnt->mnt_devname);
7797 -       } else
7798 -               seq_puts(m, "no device");
7799 +       if (vx_flags(VXF_HIDE_MOUNT, 0))
7800 +               return 0;
7801 +       if (!mnt_is_reachable(mnt) && !vx_check(0, VX_WATCH_P))
7802 +               return 0;
7803  
7804 -       /* mount point */
7805 -       seq_puts(m, " mounted on ");
7806 -       seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
7807 -       seq_putc(m, ' ');
7808 +       if (!vx_check(0, VX_ADMIN|VX_WATCH) &&
7809 +               mnt == current->fs->rootmnt) {
7810 +               seq_puts(m, "device /dev/root mounted on / ");
7811 +       } else {
7812 +               /* device */
7813 +               if (mnt->mnt_devname) {
7814 +                       seq_puts(m, "device ");
7815 +                       mangle(m, mnt->mnt_devname);
7816 +               } else
7817 +                       seq_puts(m, "no device");
7818 +
7819 +               /* mount point */
7820 +               seq_puts(m, " mounted on ");
7821 +               seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
7822 +               seq_putc(m, ' ');
7823 +       }
7824  
7825         /* file system type */
7826         seq_puts(m, "with fstype ");
7827 @@ -597,7 +652,7 @@ static int do_umount(struct vfsmount *mn
7828                 down_write(&sb->s_umount);
7829                 if (!(sb->s_flags & MS_RDONLY)) {
7830                         lock_kernel();
7831 -                       DQUOT_OFF(sb);
7832 +                       DQUOT_OFF(sb->s_dqh);
7833                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
7834                         unlock_kernel();
7835                 }
7836 @@ -646,7 +701,7 @@ asmlinkage long sys_umount(char __user *
7837                 goto dput_and_out;
7838  
7839         retval = -EPERM;
7840 -       if (!capable(CAP_SYS_ADMIN))
7841 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
7842                 goto dput_and_out;
7843  
7844         retval = do_umount(nd.mnt, flags);
7845 @@ -670,7 +725,7 @@ asmlinkage long sys_oldumount(char __use
7846  
7847  static int mount_is_safe(struct nameidata *nd)
7848  {
7849 -       if (capable(CAP_SYS_ADMIN))
7850 +       if (vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
7851                 return 0;
7852         return -EPERM;
7853  #ifdef notyet
7854 @@ -899,11 +954,13 @@ static int do_change_type(struct nameida
7855  /*
7856   * do loopback mount.
7857   */
7858 -static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
7859 +static int do_loopback(struct nameidata *nd, char *old_name, tag_t tag,
7860 +       unsigned long flags, int mnt_flags)
7861  {
7862         struct nameidata old_nd;
7863         struct vfsmount *mnt = NULL;
7864         int err = mount_is_safe(nd);
7865 +       int recurse = flags & MS_REC;
7866         if (err)
7867                 return err;
7868         if (!old_name || !*old_name)
7869 @@ -929,6 +986,12 @@ static int do_loopback(struct nameidata 
7870         if (!mnt)
7871                 goto out;
7872  
7873 +       mnt->mnt_flags = mnt_flags;
7874 +       if (flags & MS_TAGID) {
7875 +               mnt->mnt_tag = tag;
7876 +               mnt->mnt_flags |= MNT_TAGID;
7877 +       }
7878 +
7879         err = graft_tree(mnt, nd);
7880         if (err) {
7881                 LIST_HEAD(umount_list);
7882 @@ -937,6 +1000,7 @@ static int do_loopback(struct nameidata 
7883                 spin_unlock(&vfsmount_lock);
7884                 release_mounts(&umount_list);
7885         }
7886 +       mnt->mnt_flags = mnt_flags;
7887  
7888  out:
7889         up_write(&namespace_sem);
7890 @@ -950,12 +1014,12 @@ out:
7891   * on it - tough luck.
7892   */
7893  static int do_remount(struct nameidata *nd, int flags, int mnt_flags,
7894 -                     void *data)
7895 +                     void *data, xid_t xid)
7896  {
7897         int err;
7898         struct super_block *sb = nd->mnt->mnt_sb;
7899  
7900 -       if (!capable(CAP_SYS_ADMIN))
7901 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_REMOUNT))
7902                 return -EPERM;
7903  
7904         if (!check_mnt(nd->mnt))
7905 @@ -989,7 +1053,7 @@ static int do_move_mount(struct nameidat
7906         struct nameidata old_nd, parent_nd;
7907         struct vfsmount *p;
7908         int err = 0;
7909 -       if (!capable(CAP_SYS_ADMIN))
7910 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
7911                 return -EPERM;
7912         if (!old_name || !*old_name)
7913                 return -EINVAL;
7914 @@ -1069,7 +1133,7 @@ static int do_new_mount(struct nameidata
7915                 return -EINVAL;
7916  
7917         /* we need capabilities... */
7918 -       if (!capable(CAP_SYS_ADMIN))
7919 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
7920                 return -EPERM;
7921  
7922         mnt = do_kern_mount(type, flags, name, data);
7923 @@ -1307,6 +1371,7 @@ long do_mount(char *dev_name, char *dir_
7924         struct nameidata nd;
7925         int retval = 0;
7926         int mnt_flags = 0;
7927 +       tag_t tag = 0;
7928  
7929         /* Discard magic */
7930         if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
7931 @@ -1322,7 +1387,19 @@ long do_mount(char *dev_name, char *dir_
7932         if (data_page)
7933                 ((char *)data_page)[PAGE_SIZE - 1] = 0;
7934  
7935 +#ifdef CONFIG_PROPAGATE
7936 +       retval = dx_parse_tag(data_page, &tag, 1);
7937 +       if (retval) {
7938 +               mnt_flags |= MNT_TAGID;
7939 +               /* bind and re-mounts get the tag flag */
7940 +               if (flags & (MS_BIND|MS_REMOUNT))
7941 +                       flags |= MS_TAGID;
7942 +       }
7943 +#endif
7944 +
7945         /* Separate the per-mountpoint flags */
7946 +       if (flags & MS_RDONLY)
7947 +               mnt_flags |= MNT_RDONLY;
7948         if (flags & MS_NOSUID)
7949                 mnt_flags |= MNT_NOSUID;
7950         if (flags & MS_NODEV)
7951 @@ -1334,6 +1411,8 @@ long do_mount(char *dev_name, char *dir_
7952         if (flags & MS_NODIRATIME)
7953                 mnt_flags |= MNT_NODIRATIME;
7954  
7955 +       if (vx_ccaps(VXC_SECURE_MOUNT))
7956 +               mnt_flags |= MNT_NODEV;
7957         flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
7958                    MS_NOATIME | MS_NODIRATIME);
7959  
7960 @@ -1348,9 +1427,9 @@ long do_mount(char *dev_name, char *dir_
7961  
7962         if (flags & MS_REMOUNT)
7963                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
7964 -                                   data_page);
7965 +                                   data_page, tag);
7966         else if (flags & MS_BIND)
7967 -               retval = do_loopback(&nd, dev_name, flags & MS_REC);
7968 +               retval = do_loopback(&nd, dev_name, tag, flags, mnt_flags);
7969         else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
7970                 retval = do_change_type(&nd, flags);
7971         else if (flags & MS_MOVE)
7972 @@ -1448,7 +1527,7 @@ int copy_namespace(int flags, struct tas
7973         if (!(flags & CLONE_NEWNS))
7974                 return 0;
7975  
7976 -       if (!capable(CAP_SYS_ADMIN)) {
7977 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) {
7978                 err = -EPERM;
7979                 goto out;
7980         }
7981 diff -NurpP --minimal linux-2.6.17.11/fs/nfs/dir.c linux-2.6.17.11-vs2.1.1-rc31/fs/nfs/dir.c
7982 --- linux-2.6.17.11/fs/nfs/dir.c        2006-06-18 04:54:38 +0200
7983 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/nfs/dir.c   2006-07-09 17:06:49 +0200
7984 @@ -28,9 +28,11 @@
7985  #include <linux/sunrpc/clnt.h>
7986  #include <linux/nfs_fs.h>
7987  #include <linux/nfs_mount.h>
7988 +#include <linux/mount.h>
7989  #include <linux/pagemap.h>
7990  #include <linux/smp_lock.h>
7991  #include <linux/namei.h>
7992 +#include <linux/vserver/tag.h>
7993  
7994  #include "nfs4_fs.h"
7995  #include "delegation.h"
7996 @@ -904,6 +906,7 @@ static struct dentry *nfs_lookup(struct 
7997         res = (struct dentry *)inode;
7998         if (IS_ERR(res))
7999                 goto out_unlock;
8000 +       dx_propagate_tag(nd, inode);
8001  no_entry:
8002         res = d_add_unique(dentry, inode);
8003         if (res != NULL)
8004 @@ -937,7 +940,8 @@ static int is_atomic_open(struct inode *
8005         if (nd->flags & LOOKUP_DIRECTORY)
8006                 return 0;
8007         /* Are we trying to write to a read only partition? */
8008 -       if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
8009 +       if ((IS_RDONLY(dir) || MNT_IS_RDONLY(nd->mnt)) &&
8010 +               (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
8011                 return 0;
8012         return 1;
8013  }
8014 diff -NurpP --minimal linux-2.6.17.11/fs/nfs/inode.c linux-2.6.17.11-vs2.1.1-rc31/fs/nfs/inode.c
8015 --- linux-2.6.17.11/fs/nfs/inode.c      2006-06-18 04:54:41 +0200
8016 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/nfs/inode.c 2006-07-09 17:06:49 +0200
8017 @@ -36,6 +36,7 @@
8018  #include <linux/mount.h>
8019  #include <linux/nfs_idmap.h>
8020  #include <linux/vfs.h>
8021 +#include <linux/vserver/tag.h>
8022  
8023  #include <asm/system.h>
8024  #include <asm/uaccess.h>
8025 @@ -343,12 +344,16 @@ nfs_sb_init(struct super_block *sb, rpc_
8026         }
8027         server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;
8028  
8029 +       if (server->flags & NFS_MOUNT_TAGGED)
8030 +               sb->s_flags |= MS_TAGGED;
8031 +
8032         sb->s_maxbytes = fsinfo.maxfilesize;
8033         if (sb->s_maxbytes > MAX_LFS_FILESIZE) 
8034                 sb->s_maxbytes = MAX_LFS_FILESIZE; 
8035  
8036         server->client->cl_intr = (server->flags & NFS_MOUNT_INTR) ? 1 : 0;
8037         server->client->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0;
8038 +       server->client->cl_tag = (server->flags & NFS_MOUNT_TAGGED) ? 1 : 0;
8039  
8040         /* We're airborne Set socket buffersize */
8041         rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
8042 @@ -423,6 +428,7 @@ nfs_create_client(struct nfs_server *ser
8043  
8044         clnt->cl_intr     = 1;
8045         clnt->cl_softrtry = 1;
8046 +       clnt->cl_tag      = 1;
8047  
8048         return clnt;
8049  
8050 @@ -602,6 +608,7 @@ static void nfs_show_mount_options(struc
8051                 { NFS_MOUNT_NOAC, ",noac", "" },
8052                 { NFS_MOUNT_NONLM, ",nolock", "" },
8053                 { NFS_MOUNT_NOACL, ",noacl", "" },
8054 +               { NFS_MOUNT_TAGGED, ",tag", "" },
8055                 { 0, NULL, NULL }
8056         };
8057         struct proc_nfs_info *nfs_infop;
8058 @@ -903,8 +910,10 @@ nfs_fhget(struct super_block *sb, struct
8059                         nfsi->change_attr = fattr->change_attr;
8060                 inode->i_size = nfs_size_to_loff_t(fattr->size);
8061                 inode->i_nlink = fattr->nlink;
8062 -               inode->i_uid = fattr->uid;
8063 -               inode->i_gid = fattr->gid;
8064 +               inode->i_uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
8065 +               inode->i_gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
8066 +               inode->i_tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
8067 +                                        /* maybe fattr->xid someday */
8068                 if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
8069                         /*
8070                          * report the blocks in 512byte units
8071 @@ -995,6 +1004,8 @@ void nfs_setattr_update_inode(struct ino
8072                         inode->i_uid = attr->ia_uid;
8073                 if ((attr->ia_valid & ATTR_GID) != 0)
8074                         inode->i_gid = attr->ia_gid;
8075 +               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
8076 +                       inode->i_tag = attr->ia_tag;
8077                 spin_lock(&inode->i_lock);
8078                 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
8079                 spin_unlock(&inode->i_lock);
8080 @@ -1397,6 +1408,9 @@ static int nfs_check_inode_attributes(st
8081         struct nfs_inode *nfsi = NFS_I(inode);
8082         loff_t cur_size, new_isize;
8083         int data_unstable;
8084 +       uid_t uid;
8085 +       gid_t gid;
8086 +       tag_t tag;
8087  
8088  
8089         if ((fattr->valid & NFS_ATTR_FATTR) == 0)
8090 @@ -1434,10 +1448,15 @@ static int nfs_check_inode_attributes(st
8091         if (cur_size != new_isize && nfsi->npages == 0)
8092                 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
8093  
8094 +       uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
8095 +       gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
8096 +       tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
8097 +
8098         /* Have any file permissions changed? */
8099         if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
8100 -                       || inode->i_uid != fattr->uid
8101 -                       || inode->i_gid != fattr->gid)
8102 +                       || inode->i_uid != uid
8103 +                       || inode->i_gid != gid
8104 +                       || inode->i_tag != tag)
8105                 nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
8106  
8107         /* Has the link count changed? */
8108 @@ -1522,6 +1541,9 @@ static int nfs_update_inode(struct inode
8109         loff_t cur_isize, new_isize;
8110         unsigned int    invalid = 0;
8111         int data_stable;
8112 +       uid_t uid;
8113 +       gid_t gid;
8114 +       tag_t tag;
8115  
8116         dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
8117                         __FUNCTION__, inode->i_sb->s_id, inode->i_ino,
8118 @@ -1591,15 +1613,21 @@ static int nfs_update_inode(struct inode
8119         }
8120         memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
8121  
8122 +       uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
8123 +       gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
8124 +       tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
8125 +
8126         if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
8127 -           inode->i_uid != fattr->uid ||
8128 -           inode->i_gid != fattr->gid)
8129 +           inode->i_uid != uid ||
8130 +           inode->i_gid != gid ||
8131 +           inode->i_tag != tag)
8132                 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
8133  
8134         inode->i_mode = fattr->mode;
8135         inode->i_nlink = fattr->nlink;
8136 -       inode->i_uid = fattr->uid;
8137 -       inode->i_gid = fattr->gid;
8138 +       inode->i_uid = uid;
8139 +       inode->i_gid = gid;
8140 +       inode->i_tag = tag;
8141  
8142         if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
8143                 /*
8144 diff -NurpP --minimal linux-2.6.17.11/fs/nfs/nfs3xdr.c linux-2.6.17.11-vs2.1.1-rc31/fs/nfs/nfs3xdr.c
8145 --- linux-2.6.17.11/fs/nfs/nfs3xdr.c    2006-06-18 04:54:41 +0200
8146 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/nfs/nfs3xdr.c       2006-07-09 17:06:49 +0200
8147 @@ -22,6 +22,7 @@
8148  #include <linux/nfs3.h>
8149  #include <linux/nfs_fs.h>
8150  #include <linux/nfsacl.h>
8151 +#include <linux/vserver/tag.h>
8152  
8153  #define NFSDBG_FACILITY                NFSDBG_XDR
8154  
8155 @@ -178,7 +179,7 @@ xdr_decode_fattr(u32 *p, struct nfs_fatt
8156  }
8157  
8158  static inline u32 *
8159 -xdr_encode_sattr(u32 *p, struct iattr *attr)
8160 +xdr_encode_sattr(u32 *p, struct iattr *attr, int tag)
8161  {
8162         if (attr->ia_valid & ATTR_MODE) {
8163                 *p++ = xdr_one;
8164 @@ -186,15 +187,17 @@ xdr_encode_sattr(u32 *p, struct iattr *a
8165         } else {
8166                 *p++ = xdr_zero;
8167         }
8168 -       if (attr->ia_valid & ATTR_UID) {
8169 +       if (attr->ia_valid & ATTR_UID ||
8170 +               (tag && (attr->ia_valid & ATTR_TAG))) {
8171                 *p++ = xdr_one;
8172 -               *p++ = htonl(attr->ia_uid);
8173 +               *p++ = htonl(TAGINO_UID(tag, attr->ia_uid, attr->ia_tag));
8174         } else {
8175                 *p++ = xdr_zero;
8176         }
8177 -       if (attr->ia_valid & ATTR_GID) {
8178 +       if (attr->ia_valid & ATTR_GID ||
8179 +               (tag && (attr->ia_valid & ATTR_TAG))) {
8180                 *p++ = xdr_one;
8181 -               *p++ = htonl(attr->ia_gid);
8182 +               *p++ = htonl(TAGINO_GID(tag, attr->ia_gid, attr->ia_tag));
8183         } else {
8184                 *p++ = xdr_zero;
8185         }
8186 @@ -279,7 +282,8 @@ static int
8187  nfs3_xdr_sattrargs(struct rpc_rqst *req, u32 *p, struct nfs3_sattrargs *args)
8188  {
8189         p = xdr_encode_fhandle(p, args->fh);
8190 -       p = xdr_encode_sattr(p, args->sattr);
8191 +       p = xdr_encode_sattr(p, args->sattr,
8192 +               req->rq_task->tk_client->cl_tag);
8193         *p++ = htonl(args->guard);
8194         if (args->guard)
8195                 p = xdr_encode_time3(p, &args->guardtime);
8196 @@ -370,7 +374,8 @@ nfs3_xdr_createargs(struct rpc_rqst *req
8197                 *p++ = args->verifier[0];
8198                 *p++ = args->verifier[1];
8199         } else
8200 -               p = xdr_encode_sattr(p, args->sattr);
8201 +               p = xdr_encode_sattr(p, args->sattr,
8202 +                       req->rq_task->tk_client->cl_tag);
8203  
8204         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
8205         return 0;
8206 @@ -384,7 +389,8 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req,
8207  {
8208         p = xdr_encode_fhandle(p, args->fh);
8209         p = xdr_encode_array(p, args->name, args->len);
8210 -       p = xdr_encode_sattr(p, args->sattr);
8211 +       p = xdr_encode_sattr(p, args->sattr,
8212 +               req->rq_task->tk_client->cl_tag);
8213         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
8214         return 0;
8215  }
8216 @@ -397,7 +403,8 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *re
8217  {
8218         p = xdr_encode_fhandle(p, args->fromfh);
8219         p = xdr_encode_array(p, args->fromname, args->fromlen);
8220 -       p = xdr_encode_sattr(p, args->sattr);
8221 +       p = xdr_encode_sattr(p, args->sattr,
8222 +               req->rq_task->tk_client->cl_tag);
8223         p = xdr_encode_array(p, args->topath, args->tolen);
8224         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
8225         return 0;
8226 @@ -412,7 +419,8 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req,
8227         p = xdr_encode_fhandle(p, args->fh);
8228         p = xdr_encode_array(p, args->name, args->len);
8229         *p++ = htonl(args->type);
8230 -       p = xdr_encode_sattr(p, args->sattr);
8231 +       p = xdr_encode_sattr(p, args->sattr,
8232 +               req->rq_task->tk_client->cl_tag);
8233         if (args->type == NF3CHR || args->type == NF3BLK) {
8234                 *p++ = htonl(MAJOR(args->rdev));
8235                 *p++ = htonl(MINOR(args->rdev));
8236 diff -NurpP --minimal linux-2.6.17.11/fs/nfs/nfsroot.c linux-2.6.17.11-vs2.1.1-rc31/fs/nfs/nfsroot.c
8237 --- linux-2.6.17.11/fs/nfs/nfsroot.c    2006-02-18 14:40:23 +0100
8238 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/nfs/nfsroot.c       2006-07-09 17:06:49 +0200
8239 @@ -87,6 +87,7 @@
8240  #include <linux/root_dev.h>
8241  #include <net/ipconfig.h>
8242  #include <linux/parser.h>
8243 +#include <linux/vs_cvirt.h>
8244  
8245  /* Define this to allow debugging output */
8246  #undef NFSROOT_DEBUG
8247 @@ -119,12 +120,12 @@ static int mount_port __initdata = 0;             /
8248  enum {
8249         /* Options that take integer arguments */
8250         Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin,
8251 -       Opt_acregmax, Opt_acdirmin, Opt_acdirmax,
8252 +       Opt_acregmax, Opt_acdirmin, Opt_acdirmax, Opt_tagid,
8253         /* Options that take no arguments */
8254         Opt_soft, Opt_hard, Opt_intr,
8255         Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, 
8256         Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
8257 -       Opt_acl, Opt_noacl,
8258 +       Opt_acl, Opt_noacl, Opt_tag, Opt_notag,
8259         /* Error token */
8260         Opt_err
8261  };
8262 @@ -161,6 +162,10 @@ static match_table_t __initdata tokens =
8263         {Opt_tcp, "tcp"},
8264         {Opt_acl, "acl"},
8265         {Opt_noacl, "noacl"},
8266 +       {Opt_tag, "tag"},
8267 +       {Opt_notag, "notag"},
8268 +       {Opt_tagid, "tagid=%u"},
8269 +       {Opt_tag, "tagxid"},
8270         {Opt_err, NULL}
8271         
8272  };
8273 @@ -275,6 +280,20 @@ static int __init root_nfs_parse(char *n
8274                         case Opt_noacl:
8275                                 nfs_data.flags |= NFS_MOUNT_NOACL;
8276                                 break;
8277 +#ifndef CONFIG_TAGGING_NONE
8278 +                       case Opt_tag:
8279 +                               nfs_data.flags |= NFS_MOUNT_TAGGED;
8280 +                               break;
8281 +                       case Opt_notag:
8282 +                               nfs_data.flags &= ~NFS_MOUNT_TAGGED;
8283 +                               break;
8284 +#endif
8285 +#ifdef CONFIG_PROPAGATE
8286 +                       case Opt_tagid:
8287 +                               /* use args[0] */
8288 +                               nfs_data.flags |= NFS_MOUNT_TAGGED;
8289 +                               break;
8290 +#endif
8291                         default:
8292                                 printk(KERN_WARNING "Root-NFS: unknown "
8293                                         "option: %s\n", p);
8294 @@ -312,7 +331,7 @@ static int __init root_nfs_name(char *na
8295         /* Override them by options set on kernel command-line */
8296         root_nfs_parse(name, buf);
8297  
8298 -       cp = system_utsname.nodename;
8299 +       cp = vx_new_uts(nodename);
8300         if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
8301                 printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
8302                 return -1;
8303 diff -NurpP --minimal linux-2.6.17.11/fs/nfsd/auth.c linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/auth.c
8304 --- linux-2.6.17.11/fs/nfsd/auth.c      2006-06-18 04:54:42 +0200
8305 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/auth.c 2006-07-09 17:06:49 +0200
8306 @@ -9,6 +9,7 @@
8307  #include <linux/sunrpc/svc.h>
8308  #include <linux/sunrpc/svcauth.h>
8309  #include <linux/nfsd/nfsd.h>
8310 +#include <linux/vserver/tag.h>
8311  
8312  #define        CAP_NFSD_MASK (CAP_FS_MASK|CAP_TO_MASK(CAP_SYS_RESOURCE))
8313  
8314 @@ -41,19 +42,22 @@ int nfsd_setuser(struct svc_rqst *rqstp,
8315                 get_group_info(cred.cr_group_info);
8316  
8317         if (cred.cr_uid != (uid_t) -1)
8318 -               current->fsuid = cred.cr_uid;
8319 +               current->fsuid = INOTAG_UID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid);
8320         else
8321                 current->fsuid = exp->ex_anon_uid;
8322         if (cred.cr_gid != (gid_t) -1)
8323 -               current->fsgid = cred.cr_gid;
8324 +               current->fsgid = INOTAG_GID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid);
8325         else
8326                 current->fsgid = exp->ex_anon_gid;
8327  
8328 +       /* this desperately needs a tag :) */
8329 +       current->xid = (xid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
8330 +
8331         if (!cred.cr_group_info)
8332                 return -ENOMEM;
8333         ret = set_current_groups(cred.cr_group_info);
8334         put_group_info(cred.cr_group_info);
8335 -       if ((cred.cr_uid)) {
8336 +       if (INOTAG_UID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid)) {
8337                 cap_t(current->cap_effective) &= ~CAP_NFSD_MASK;
8338         } else {
8339                 cap_t(current->cap_effective) |= (CAP_NFSD_MASK &
8340 diff -NurpP --minimal linux-2.6.17.11/fs/nfsd/nfs3xdr.c linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/nfs3xdr.c
8341 --- linux-2.6.17.11/fs/nfsd/nfs3xdr.c   2006-04-09 13:49:54 +0200
8342 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/nfs3xdr.c      2006-07-09 17:06:49 +0200
8343 @@ -21,6 +21,7 @@
8344  #include <linux/sunrpc/svc.h>
8345  #include <linux/nfsd/nfsd.h>
8346  #include <linux/nfsd/xdr3.h>
8347 +#include <linux/vserver/tag.h>
8348  
8349  #define NFSDDBG_FACILITY               NFSDDBG_XDR
8350  
8351 @@ -111,6 +112,8 @@ static inline u32 *
8352  decode_sattr3(u32 *p, struct iattr *iap)
8353  {
8354         u32     tmp;
8355 +       uid_t   uid = 0;
8356 +       gid_t   gid = 0;
8357  
8358         iap->ia_valid = 0;
8359  
8360 @@ -120,12 +123,15 @@ decode_sattr3(u32 *p, struct iattr *iap)
8361         }
8362         if (*p++) {
8363                 iap->ia_valid |= ATTR_UID;
8364 -               iap->ia_uid = ntohl(*p++);
8365 +               uid = ntohl(*p++);
8366         }
8367         if (*p++) {
8368                 iap->ia_valid |= ATTR_GID;
8369 -               iap->ia_gid = ntohl(*p++);
8370 +               gid = ntohl(*p++);
8371         }
8372 +       iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid);
8373 +       iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid);
8374 +       iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0);
8375         if (*p++) {
8376                 u64     newsize;
8377  
8378 @@ -163,8 +169,10 @@ encode_fattr3(struct svc_rqst *rqstp, u3
8379         *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
8380         *p++ = htonl((u32) stat->mode);
8381         *p++ = htonl((u32) stat->nlink);
8382 -       *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
8383 -       *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
8384 +       *p++ = htonl((u32) nfsd_ruid(rqstp,
8385 +               TAGINO_UID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
8386 +       *p++ = htonl((u32) nfsd_rgid(rqstp,
8387 +               TAGINO_GID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
8388         if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
8389                 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
8390         } else {
8391 diff -NurpP --minimal linux-2.6.17.11/fs/nfsd/nfs4recover.c linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/nfs4recover.c
8392 --- linux-2.6.17.11/fs/nfsd/nfs4recover.c       2006-02-18 14:40:23 +0100
8393 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/nfs4recover.c  2006-07-09 17:06:49 +0200
8394 @@ -155,7 +155,7 @@ nfsd4_create_clid_dir(struct nfs4_client
8395                 dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
8396                 goto out_put;
8397         }
8398 -       status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
8399 +       status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU, NULL);
8400  out_put:
8401         dput(dentry);
8402  out_unlock:
8403 @@ -259,7 +259,7 @@ nfsd4_remove_clid_file(struct dentry *di
8404                 return -EINVAL;
8405         }
8406         mutex_lock(&dir->d_inode->i_mutex);
8407 -       status = vfs_unlink(dir->d_inode, dentry);
8408 +       status = vfs_unlink(dir->d_inode, dentry, NULL);
8409         mutex_unlock(&dir->d_inode->i_mutex);
8410         return status;
8411  }
8412 @@ -274,7 +274,7 @@ nfsd4_clear_clid_dir(struct dentry *dir,
8413          * a kernel from the future.... */
8414         nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
8415         mutex_lock(&dir->d_inode->i_mutex);
8416 -       status = vfs_rmdir(dir->d_inode, dentry);
8417 +       status = vfs_rmdir(dir->d_inode, dentry, NULL);
8418         mutex_unlock(&dir->d_inode->i_mutex);
8419         return status;
8420  }
8421 diff -NurpP --minimal linux-2.6.17.11/fs/nfsd/nfs4xdr.c linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/nfs4xdr.c
8422 --- linux-2.6.17.11/fs/nfsd/nfs4xdr.c   2006-06-18 04:54:42 +0200
8423 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/nfs4xdr.c      2006-07-09 17:06:49 +0200
8424 @@ -57,6 +57,7 @@
8425  #include <linux/nfsd_idmap.h>
8426  #include <linux/nfs4.h>
8427  #include <linux/nfs4_acl.h>
8428 +#include <linux/vserver/tag.h>
8429  
8430  #define NFSDDBG_FACILITY               NFSDDBG_XDR
8431  
8432 @@ -1560,14 +1561,18 @@ out_acl:
8433                 WRITE32(stat.nlink);
8434         }
8435         if (bmval1 & FATTR4_WORD1_OWNER) {
8436 -               status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
8437 +               status = nfsd4_encode_user(rqstp,
8438 +                       TAGINO_UID(DX_TAG(dentry->d_inode),
8439 +                       stat.uid, stat.tag), &p, &buflen);
8440                 if (status == nfserr_resource)
8441                         goto out_resource;
8442                 if (status)
8443                         goto out;
8444         }
8445         if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
8446 -               status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
8447 +               status = nfsd4_encode_group(rqstp,
8448 +                       TAGINO_GID(DX_TAG(dentry->d_inode),
8449 +                       stat.gid, stat.tag), &p, &buflen);
8450                 if (status == nfserr_resource)
8451                         goto out_resource;
8452                 if (status)
8453 diff -NurpP --minimal linux-2.6.17.11/fs/nfsd/nfsxdr.c linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/nfsxdr.c
8454 --- linux-2.6.17.11/fs/nfsd/nfsxdr.c    2006-04-09 13:49:54 +0200
8455 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/nfsxdr.c       2006-07-09 17:06:49 +0200
8456 @@ -15,6 +15,7 @@
8457  #include <linux/nfsd/nfsd.h>
8458  #include <linux/nfsd/xdr.h>
8459  #include <linux/mm.h>
8460 +#include <linux/vserver/tag.h>
8461  
8462  #define NFSDDBG_FACILITY               NFSDDBG_XDR
8463  
8464 @@ -102,6 +103,8 @@ static inline u32 *
8465  decode_sattr(u32 *p, struct iattr *iap)
8466  {
8467         u32     tmp, tmp1;
8468 +       uid_t   uid = 0;
8469 +       gid_t   gid = 0;
8470  
8471         iap->ia_valid = 0;
8472  
8473 @@ -115,12 +118,15 @@ decode_sattr(u32 *p, struct iattr *iap)
8474         }
8475         if ((tmp = ntohl(*p++)) != (u32)-1) {
8476                 iap->ia_valid |= ATTR_UID;
8477 -               iap->ia_uid = tmp;
8478 +               uid = tmp;
8479         }
8480         if ((tmp = ntohl(*p++)) != (u32)-1) {
8481                 iap->ia_valid |= ATTR_GID;
8482 -               iap->ia_gid = tmp;
8483 +               gid = tmp;
8484         }
8485 +       iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid);
8486 +       iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid);
8487 +       iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0);
8488         if ((tmp = ntohl(*p++)) != (u32)-1) {
8489                 iap->ia_valid |= ATTR_SIZE;
8490                 iap->ia_size = tmp;
8491 @@ -164,8 +170,10 @@ encode_fattr(struct svc_rqst *rqstp, u32
8492         *p++ = htonl(nfs_ftypes[type >> 12]);
8493         *p++ = htonl((u32) stat->mode);
8494         *p++ = htonl((u32) stat->nlink);
8495 -       *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
8496 -       *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
8497 +       *p++ = htonl((u32) nfsd_ruid(rqstp,
8498 +               TAGINO_UID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
8499 +       *p++ = htonl((u32) nfsd_rgid(rqstp,
8500 +               TAGINO_GID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
8501  
8502         if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
8503                 *p++ = htonl(NFS_MAXPATHLEN);
8504 diff -NurpP --minimal linux-2.6.17.11/fs/nfsd/vfs.c linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/vfs.c
8505 --- linux-2.6.17.11/fs/nfsd/vfs.c       2006-06-18 04:54:42 +0200
8506 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/nfsd/vfs.c  2006-07-09 17:06:49 +0200
8507 @@ -1156,13 +1156,13 @@ nfsd_create(struct svc_rqst *rqstp, stru
8508                 err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
8509                 break;
8510         case S_IFDIR:
8511 -               err = vfs_mkdir(dirp, dchild, iap->ia_mode);
8512 +               err = vfs_mkdir(dirp, dchild, iap->ia_mode, NULL);
8513                 break;
8514         case S_IFCHR:
8515         case S_IFBLK:
8516         case S_IFIFO:
8517         case S_IFSOCK:
8518 -               err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
8519 +               err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev, NULL);
8520                 break;
8521         default:
8522                 printk("nfsd: bad file type %o in nfsd_create\n", type);
8523 @@ -1442,11 +1442,13 @@ nfsd_symlink(struct svc_rqst *rqstp, str
8524                 else {
8525                         strncpy(path_alloced, path, plen);
8526                         path_alloced[plen] = 0;
8527 -                       err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
8528 +                       err = vfs_symlink(dentry->d_inode, dnew,
8529 +                               path_alloced, mode, NULL);
8530                         kfree(path_alloced);
8531                 }
8532         } else
8533 -               err = vfs_symlink(dentry->d_inode, dnew, path, mode);
8534 +               err = vfs_symlink(dentry->d_inode, dnew,
8535 +                       path, mode, NULL);
8536  
8537         if (!err)
8538                 if (EX_ISSYNC(fhp->fh_export))
8539 @@ -1504,7 +1506,7 @@ nfsd_link(struct svc_rqst *rqstp, struct
8540         dold = tfhp->fh_dentry;
8541         dest = dold->d_inode;
8542  
8543 -       err = vfs_link(dold, dirp, dnew);
8544 +       err = vfs_link(dold, dirp, dnew, NULL);
8545         if (!err) {
8546                 if (EX_ISSYNC(ffhp->fh_export)) {
8547                         err = nfserrno(nfsd_sync_dir(ddir));
8548 @@ -1666,9 +1668,9 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
8549                         err = -EPERM;
8550                 } else
8551  #endif
8552 -               err = vfs_unlink(dirp, rdentry);
8553 +               err = vfs_unlink(dirp, rdentry, NULL);
8554         } else { /* It's RMDIR */
8555 -               err = vfs_rmdir(dirp, rdentry);
8556 +               err = vfs_rmdir(dirp, rdentry, NULL);
8557         }
8558  
8559         dput(rdentry);
8560 @@ -1777,7 +1779,8 @@ nfsd_permission(struct svc_export *exp, 
8561          */
8562         if (!(acc & MAY_LOCAL_ACCESS))
8563                 if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
8564 -                       if (EX_RDONLY(exp) || IS_RDONLY(inode))
8565 +                       if (EX_RDONLY(exp) || IS_RDONLY(inode)
8566 +                               || MNT_IS_RDONLY(exp->ex_mnt))
8567                                 return nfserr_rofs;
8568                         if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
8569                                 return nfserr_perm;
8570 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/Makefile linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/Makefile
8571 --- linux-2.6.17.11/fs/ocfs2/Makefile   2006-01-18 06:08:34 +0100
8572 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/Makefile      2006-07-09 17:06:49 +0200
8573 @@ -16,6 +16,7 @@ ocfs2-objs := \
8574         file.o                  \
8575         heartbeat.o             \
8576         inode.o                 \
8577 +       ioctl.o                 \
8578         journal.o               \
8579         localalloc.o            \
8580         mmap.o                  \
8581 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/dlm/dlmfs.c linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/dlm/dlmfs.c
8582 --- linux-2.6.17.11/fs/ocfs2/dlm/dlmfs.c        2006-06-18 04:54:44 +0200
8583 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/dlm/dlmfs.c   2006-07-09 17:06:49 +0200
8584 @@ -44,6 +44,7 @@
8585  #include <linux/string.h>
8586  #include <linux/smp_lock.h>
8587  #include <linux/backing-dev.h>
8588 +#include <linux/vs_tag.h>
8589  
8590  #include <asm/uaccess.h>
8591  
8592 @@ -335,6 +336,7 @@ static struct inode *dlmfs_get_root_inod
8593                 inode->i_mode = mode;
8594                 inode->i_uid = current->fsuid;
8595                 inode->i_gid = current->fsgid;
8596 +               inode->i_tag = dx_current_fstag(sb);
8597                 inode->i_blksize = PAGE_CACHE_SIZE;
8598                 inode->i_blocks = 0;
8599                 inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
8600 @@ -362,6 +364,7 @@ static struct inode *dlmfs_get_inode(str
8601         inode->i_mode = mode;
8602         inode->i_uid = current->fsuid;
8603         inode->i_gid = current->fsgid;
8604 +       inode->i_tag = dx_current_fstag(sb);
8605         inode->i_blksize = PAGE_CACHE_SIZE;
8606         inode->i_blocks = 0;
8607         inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
8608 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/dlmglue.c linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/dlmglue.c
8609 --- linux-2.6.17.11/fs/ocfs2/dlmglue.c  2006-06-18 04:54:44 +0200
8610 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/dlmglue.c     2006-07-09 17:06:49 +0200
8611 @@ -1320,8 +1320,10 @@ static void __ocfs2_stuff_meta_lvb(struc
8612         lvb->lvb_version   = cpu_to_be32(OCFS2_LVB_VERSION);
8613         lvb->lvb_isize     = cpu_to_be64(i_size_read(inode));
8614         lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
8615 +       lvb->lvb_iflags    = cpu_to_be32(oi->ip_flags) & OCFS2_FL_MASK;
8616         lvb->lvb_iuid      = cpu_to_be32(inode->i_uid);
8617         lvb->lvb_igid      = cpu_to_be32(inode->i_gid);
8618 +       lvb->lvb_itag      = cpu_to_be16(inode->i_tag);
8619         lvb->lvb_imode     = cpu_to_be16(inode->i_mode);
8620         lvb->lvb_inlink    = cpu_to_be16(inode->i_nlink);
8621         lvb->lvb_iatime_packed  =
8622 @@ -1367,8 +1369,12 @@ static void ocfs2_refresh_inode_from_lvb
8623                 inode->i_blocks =
8624                         ocfs2_align_bytes_to_sectors(i_size_read(inode));
8625  
8626 +       oi->ip_flags &= ~OCFS2_FL_MASK;
8627 +       oi->ip_flags |= be32_to_cpu(lvb->lvb_iflags) & OCFS2_FL_MASK;
8628 +
8629         inode->i_uid     = be32_to_cpu(lvb->lvb_iuid);
8630         inode->i_gid     = be32_to_cpu(lvb->lvb_igid);
8631 +       inode->i_tag     = be16_to_cpu(lvb->lvb_itag);
8632         inode->i_mode    = be16_to_cpu(lvb->lvb_imode);
8633         inode->i_nlink   = be16_to_cpu(lvb->lvb_inlink);
8634         ocfs2_unpack_timespec(&inode->i_atime,
8635 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/dlmglue.h linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/dlmglue.h
8636 --- linux-2.6.17.11/fs/ocfs2/dlmglue.h  2006-01-18 06:08:34 +0100
8637 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/dlmglue.h     2006-07-09 17:06:49 +0200
8638 @@ -27,7 +27,7 @@
8639  #ifndef DLMGLUE_H
8640  #define DLMGLUE_H
8641  
8642 -#define OCFS2_LVB_VERSION 2
8643 +#define OCFS2_LVB_VERSION 3
8644  
8645  struct ocfs2_meta_lvb {
8646         __be32       lvb_version;
8647 @@ -40,7 +40,9 @@ struct ocfs2_meta_lvb {
8648         __be64       lvb_isize;
8649         __be16       lvb_imode;
8650         __be16       lvb_inlink;
8651 -       __be32       lvb_reserved[3];
8652 +       __be16       lvb_itag;
8653 +       __be32       lvb_iflags;
8654 +       __be32       lvb_reserved[2];
8655  };
8656  
8657  /* ocfs2_meta_lock_full() and ocfs2_data_lock_full() 'arg_flags' flags */
8658 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/file.c linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/file.c
8659 --- linux-2.6.17.11/fs/ocfs2/file.c     2006-06-18 04:54:44 +0200
8660 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/file.c        2006-07-09 17:06:49 +0200
8661 @@ -44,6 +44,7 @@
8662  #include "file.h"
8663  #include "sysfile.h"
8664  #include "inode.h"
8665 +#include "ioctl.h"
8666  #include "journal.h"
8667  #include "mmap.h"
8668  #include "suballoc.h"
8669 @@ -788,13 +789,15 @@ int ocfs2_setattr(struct dentry *dentry,
8670                 mlog(0, "uid change: %d\n", attr->ia_uid);
8671         if (attr->ia_valid & ATTR_GID)
8672                 mlog(0, "gid change: %d\n", attr->ia_gid);
8673 +       if (attr->ia_valid & ATTR_TAG)
8674 +               mlog(0, "tag change: %d\n", attr->ia_tag);
8675         if (attr->ia_valid & ATTR_SIZE)
8676                 mlog(0, "size change...\n");
8677         if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME))
8678                 mlog(0, "time change...\n");
8679  
8680  #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
8681 -                          | ATTR_GID | ATTR_UID | ATTR_MODE)
8682 +                          | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE)
8683         if (!(attr->ia_valid & OCFS2_VALID_ATTRS)) {
8684                 mlog(0, "can't handle attrs: 0x%x\n", attr->ia_valid);
8685                 return 0;
8686 @@ -1210,6 +1213,7 @@ bail:
8687  struct inode_operations ocfs2_file_iops = {
8688         .setattr        = ocfs2_setattr,
8689         .getattr        = ocfs2_getattr,
8690 +       .sync_flags     = ocfs2_sync_flags,
8691  };
8692  
8693  struct inode_operations ocfs2_special_file_iops = {
8694 @@ -1227,10 +1231,12 @@ const struct file_operations ocfs2_fops 
8695         .open           = ocfs2_file_open,
8696         .aio_read       = ocfs2_file_aio_read,
8697         .aio_write      = ocfs2_file_aio_write,
8698 +       .ioctl          = ocfs2_ioctl,
8699  };
8700  
8701  const struct file_operations ocfs2_dops = {
8702         .read           = generic_read_dir,
8703         .readdir        = ocfs2_readdir,
8704         .fsync          = ocfs2_sync_file,
8705 +       .ioctl          = ocfs2_ioctl,
8706  };
8707 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/inode.c linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/inode.c
8708 --- linux-2.6.17.11/fs/ocfs2/inode.c    2006-06-18 04:54:44 +0200
8709 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/inode.c       2006-08-17 01:24:55 +0200
8710 @@ -29,6 +29,7 @@
8711  #include <linux/highmem.h>
8712  #include <linux/pagemap.h>
8713  #include <linux/smp_lock.h>
8714 +#include <linux/vs_tag.h>
8715  
8716  #include <asm/byteorder.h>
8717  
8718 @@ -43,6 +44,7 @@
8719  #include "file.h"
8720  #include "heartbeat.h"
8721  #include "inode.h"
8722 +#include "ioctl.h"
8723  #include "journal.h"
8724  #include "namei.h"
8725  #include "suballoc.h"
8726 @@ -71,6 +73,62 @@ static int ocfs2_truncate_for_delete(str
8727                                     struct inode *inode,
8728                                     struct buffer_head *fe_bh);
8729  
8730 +void ocfs2_set_inode_flags(struct inode *inode)
8731 +{
8732 +       unsigned int flags = OCFS2_I(inode)->ip_flags;
8733 +
8734 +       inode->i_flags &= ~(S_IMMUTABLE |
8735 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
8736 +
8737 +       if (flags & OCFS2_IMMUTABLE_FL)
8738 +               inode->i_flags |= S_IMMUTABLE;
8739 +       if (flags & OCFS2_IUNLINK_FL)
8740 +               inode->i_flags |= S_IUNLINK;
8741 +       if (flags & OCFS2_BARRIER_FL)
8742 +               inode->i_flags |= S_BARRIER;
8743 +
8744 +       if (flags & OCFS2_SYNC_FL)
8745 +               inode->i_flags |= S_SYNC;
8746 +       if (flags & OCFS2_APPEND_FL)
8747 +               inode->i_flags |= S_APPEND;
8748 +       if (flags & OCFS2_NOATIME_FL)
8749 +               inode->i_flags |= S_NOATIME;
8750 +       if (flags & OCFS2_DIRSYNC_FL)
8751 +               inode->i_flags |= S_DIRSYNC;
8752 +}
8753 +
8754 +int ocfs2_sync_flags(struct inode *inode)
8755 +{
8756 +       unsigned int oldflags, newflags;
8757 +
8758 +       oldflags = OCFS2_I(inode)->ip_flags;
8759 +       newflags = oldflags & ~(OCFS2_APPEND_FL |
8760 +               OCFS2_IMMUTABLE_FL | OCFS2_IUNLINK_FL |
8761 +               OCFS2_BARRIER_FL | OCFS2_NOATIME_FL |
8762 +               OCFS2_SYNC_FL | OCFS2_DIRSYNC_FL);
8763 +
8764 +       if (IS_APPEND(inode))
8765 +               newflags |= OCFS2_APPEND_FL;
8766 +       if (IS_IMMUTABLE(inode))
8767 +               newflags |= OCFS2_IMMUTABLE_FL;
8768 +       if (IS_IUNLINK(inode))
8769 +               newflags |= OCFS2_IUNLINK_FL;
8770 +       if (IS_BARRIER(inode))
8771 +               newflags |= OCFS2_BARRIER_FL;
8772 +
8773 +       /* we do not want to copy superblock flags */
8774 +       if (inode->i_flags & S_NOATIME)
8775 +               newflags |= OCFS2_NOATIME_FL;
8776 +       if (inode->i_flags & S_SYNC)
8777 +               newflags |= OCFS2_SYNC_FL;
8778 +       if (inode->i_flags & S_DIRSYNC)
8779 +               newflags |= OCFS2_DIRSYNC_FL;
8780 +
8781 +       if (oldflags ^ newflags)
8782 +               return ocfs2_set_iflags(inode, newflags, OCFS2_FL_MASK);
8783 +       return 0;
8784 +}
8785 +
8786  struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb,
8787                                      u64 blkno,
8788                                      int delete_vote)
8789 @@ -218,6 +276,8 @@ int ocfs2_populate_inode(struct inode *i
8790         struct super_block *sb;
8791         struct ocfs2_super *osb;
8792         int status = -EINVAL;
8793 +       uid_t uid;
8794 +       gid_t gid;
8795  
8796         mlog_entry("(0x%p, size:%llu)\n", inode,
8797                    (unsigned long long)fe->i_size);
8798 @@ -249,8 +309,12 @@ int ocfs2_populate_inode(struct inode *i
8799         inode->i_generation = le32_to_cpu(fe->i_generation);
8800         inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
8801         inode->i_mode = le16_to_cpu(fe->i_mode);
8802 -       inode->i_uid = le32_to_cpu(fe->i_uid);
8803 -       inode->i_gid = le32_to_cpu(fe->i_gid);
8804 +       uid = le32_to_cpu(fe->i_uid);
8805 +       gid = le32_to_cpu(fe->i_gid);
8806 +       inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
8807 +       inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
8808 +       inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
8809 +               /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0);
8810         inode->i_blksize = (u32)osb->s_clustersize;
8811  
8812         /* Fast symlinks will have i_size but no allocated clusters. */
8813 @@ -260,7 +324,6 @@ int ocfs2_populate_inode(struct inode *i
8814                 inode->i_blocks =
8815                         ocfs2_align_bytes_to_sectors(le64_to_cpu(fe->i_size));
8816         inode->i_mapping->a_ops = &ocfs2_aops;
8817 -       inode->i_flags |= S_NOATIME;
8818         inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);
8819         inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
8820         inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime);
8821 @@ -276,6 +339,8 @@ int ocfs2_populate_inode(struct inode *i
8822  
8823         OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
8824         OCFS2_I(inode)->ip_orphaned_slot = OCFS2_INVALID_SLOT;
8825 +       OCFS2_I(inode)->ip_flags &= ~OCFS2_FL_MASK;
8826 +       OCFS2_I(inode)->ip_flags |= le32_to_cpu(fe->i_flags) & OCFS2_FL_MASK;
8827  
8828         if (create_ino)
8829                 inode->i_ino = ino_from_blkno(inode->i_sb,
8830 @@ -329,7 +394,8 @@ int ocfs2_populate_inode(struct inode *i
8831                                   OCFS2_LOCK_TYPE_META, inode);
8832         ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_data_lockres,
8833                                   OCFS2_LOCK_TYPE_DATA, inode);
8834 -
8835 +       ocfs2_set_inode_flags(inode);
8836 +       inode->i_flags |= S_NOATIME;
8837         status = 0;
8838  bail:
8839         mlog_exit(status);
8840 @@ -1131,12 +1197,17 @@ int ocfs2_mark_inode_dirty(struct ocfs2_
8841  
8842         spin_lock(&OCFS2_I(inode)->ip_lock);
8843         fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters);
8844 +       fe->i_flags &= cpu_to_le32(~OCFS2_FL_MASK);
8845 +       fe->i_flags |= cpu_to_le32(OCFS2_I(inode)->ip_flags & OCFS2_FL_MASK);
8846         spin_unlock(&OCFS2_I(inode)->ip_lock);
8847  
8848         fe->i_size = cpu_to_le64(i_size_read(inode));
8849         fe->i_links_count = cpu_to_le16(inode->i_nlink);
8850 -       fe->i_uid = cpu_to_le32(inode->i_uid);
8851 -       fe->i_gid = cpu_to_le32(inode->i_gid);
8852 +       fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode),
8853 +               inode->i_uid, inode->i_tag));
8854 +       fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode),
8855 +               inode->i_gid, inode->i_tag));
8856 +       /* i_tag = = cpu_to_le16(inode->i_tag); */
8857         fe->i_mode = cpu_to_le16(inode->i_mode);
8858         fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
8859         fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
8860 @@ -1165,14 +1236,24 @@ void ocfs2_refresh_inode(struct inode *i
8861                          struct ocfs2_dinode *fe)
8862  {
8863         struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
8864 +       uid_t uid;
8865 +       gid_t gid;
8866  
8867         spin_lock(&OCFS2_I(inode)->ip_lock);
8868  
8869         OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
8870 +       OCFS2_I(inode)->ip_flags &= ~OCFS2_FL_MASK;
8871 +       OCFS2_I(inode)->ip_flags |= le32_to_cpu(fe->i_flags) & OCFS2_FL_MASK;
8872 +       ocfs2_set_inode_flags(inode);
8873 +
8874         i_size_write(inode, le64_to_cpu(fe->i_size));
8875         inode->i_nlink = le16_to_cpu(fe->i_links_count);
8876 -       inode->i_uid = le32_to_cpu(fe->i_uid);
8877 -       inode->i_gid = le32_to_cpu(fe->i_gid);
8878 +       uid = le32_to_cpu(fe->i_uid);
8879 +       gid = le32_to_cpu(fe->i_gid);
8880 +       inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
8881 +       inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
8882 +       inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
8883 +               /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0);
8884         inode->i_mode = le16_to_cpu(fe->i_mode);
8885         inode->i_blksize = (u32) osb->s_clustersize;
8886         if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)
8887 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/inode.h linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/inode.h
8888 --- linux-2.6.17.11/fs/ocfs2/inode.h    2006-04-09 13:49:54 +0200
8889 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/inode.h       2006-07-09 17:06:49 +0200
8890 @@ -142,4 +142,7 @@ int ocfs2_mark_inode_dirty(struct ocfs2_
8891  int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb);
8892  int ocfs2_aio_write(struct file *file, struct kiocb *req, struct iocb *iocb);
8893  
8894 +void ocfs2_set_inode_flags(struct inode *inode);
8895 +int ocfs2_sync_flags(struct inode *inode);
8896 +
8897  #endif /* OCFS2_INODE_H */
8898 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/ioctl.c linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/ioctl.c
8899 --- linux-2.6.17.11/fs/ocfs2/ioctl.c    1970-01-01 01:00:00 +0100
8900 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/ioctl.c       2006-07-09 17:06:49 +0200
8901 @@ -0,0 +1,166 @@
8902 +/*
8903 + * linux/fs/ocfs2/ioctl.c
8904 + *
8905 + * Copyright (C) 2006 Herbert Poetzl
8906 + * adapted from Remy Card's ext2/ioctl.c
8907 + */
8908 +
8909 +#include <linux/fs.h>
8910 +#include <linux/mount.h>
8911 +
8912 +#define MLOG_MASK_PREFIX ML_INODE
8913 +#include <cluster/masklog.h>
8914 +
8915 +#include "ocfs2.h"
8916 +#include "alloc.h"
8917 +#include "dlmglue.h"
8918 +#include "inode.h"
8919 +#include "journal.h"
8920 +
8921 +#include "ocfs2_fs.h"
8922 +#include <linux/ext2_fs.h>
8923 +
8924 +
8925 +static struct {
8926 +       long ocfs2_flag;
8927 +       long ext2_flag;
8928 +} ocfs2_map[] = {
8929 +       {OCFS2_NOATIME_FL, EXT2_NOATIME_FL},
8930 +       {OCFS2_DIRSYNC_FL, EXT2_DIRSYNC_FL},
8931 +       {OCFS2_SYNC_FL, EXT2_SYNC_FL},
8932 +       {OCFS2_SECRM_FL, EXT2_SECRM_FL},
8933 +       {OCFS2_UNRM_FL, EXT2_UNRM_FL},
8934 +       {OCFS2_APPEND_FL, EXT2_APPEND_FL},
8935 +       {OCFS2_IMMUTABLE_FL, EXT2_IMMUTABLE_FL},
8936 +       {0, 0},
8937 +};
8938 +
8939 +static long ocfs2_map_ext2(unsigned long flags, int from)
8940 +{
8941 +       int index=0;
8942 +       long mapped=0;
8943 +
8944 +       while (ocfs2_map[index].ocfs2_flag) {
8945 +               if (from) {
8946 +                       if (ocfs2_map[index].ext2_flag & flags)
8947 +                               mapped |= ocfs2_map[index].ocfs2_flag;
8948 +               } else {
8949 +                       if (ocfs2_map[index].ocfs2_flag & flags)
8950 +                               mapped |= ocfs2_map[index].ext2_flag;
8951 +               }
8952 +               index++;
8953 +       }
8954 +       return mapped;
8955 +}
8956 +
8957 +
8958 +int ocfs2_get_iflags(struct inode *inode, unsigned *flags)
8959 +{
8960 +       int status;
8961 +
8962 +       status = ocfs2_meta_lock(inode, NULL, NULL, 0);
8963 +       if (status < 0) {
8964 +               mlog_errno(status);
8965 +               return status;
8966 +       }
8967 +       *flags = OCFS2_I(inode)->ip_flags;
8968 +       ocfs2_meta_unlock(inode, 0);
8969 +
8970 +       mlog_exit(status);
8971 +       return status;
8972 +}
8973 +
8974 +int ocfs2_set_iflags(struct inode *inode, unsigned flags, unsigned mask)
8975 +{
8976 +       struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
8977 +       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
8978 +       struct ocfs2_journal_handle *handle = NULL;
8979 +       struct buffer_head *bh = NULL;
8980 +       unsigned oldflags;
8981 +       int status;
8982 +
8983 +       status = ocfs2_meta_lock(inode, NULL, &bh, 1);
8984 +       if (status < 0) {
8985 +               mlog_errno(status);
8986 +               goto bail;
8987 +       }
8988 +
8989 +       status = -EROFS;
8990 +       if (IS_RDONLY(inode))
8991 +               goto bail_unlock;
8992 +
8993 +       status = -EACCES;
8994 +       if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
8995 +               goto bail_unlock;
8996 +
8997 +       if (!S_ISDIR(inode->i_mode))
8998 +               flags &= ~OCFS2_DIRSYNC_FL;
8999 +
9000 +       handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS);
9001 +       if (IS_ERR(handle)) {
9002 +               status = PTR_ERR(handle);
9003 +               mlog_errno(status);
9004 +               goto bail_unlock;
9005 +       }
9006 +
9007 +       oldflags = ocfs2_inode->ip_flags;
9008 +       flags = flags & mask;
9009 +       flags |= oldflags & ~mask;
9010 +
9011 +       /*
9012 +        * The IMMUTABLE and APPEND_ONLY flags can only be changed by
9013 +        * the relevant capability.
9014 +        */
9015 +       status = -EPERM;
9016 +       if ((oldflags & OCFS2_IMMUTABLE_FL) || ((flags ^ oldflags) &
9017 +               (OCFS2_APPEND_FL | OCFS2_IMMUTABLE_FL))) {
9018 +               if (!capable(CAP_LINUX_IMMUTABLE))
9019 +                       goto bail_unlock;
9020 +       }
9021 +
9022 +       ocfs2_inode->ip_flags = flags;
9023 +       ocfs2_set_inode_flags(inode);
9024 +
9025 +       status = ocfs2_mark_inode_dirty(handle, inode, bh);
9026 +       if (status < 0)
9027 +               mlog_errno(status);
9028 +
9029 +       ocfs2_commit_trans(handle);
9030 +bail_unlock:
9031 +       ocfs2_meta_unlock(inode, 1);
9032 +bail:
9033 +       if (bh)
9034 +               brelse(bh);
9035 +
9036 +       mlog_exit(status);
9037 +       return status;
9038 +}
9039 +
9040 +
9041 +int ocfs2_ioctl(struct inode * inode, struct file * filp,
9042 +       unsigned int cmd, unsigned long arg)
9043 +{
9044 +       unsigned int flags;
9045 +       int status;
9046 +
9047 +       switch (cmd) {
9048 +       case OCFS2_IOC_GETFLAGS:
9049 +               status = ocfs2_get_iflags(inode, &flags);
9050 +               if (status < 0)
9051 +                       return status;
9052 +
9053 +               flags &= OCFS2_FL_VISIBLE;
9054 +               flags = ocfs2_map_ext2(flags, 0);
9055 +               return put_user(flags, (int __user *) arg);
9056 +       case OCFS2_IOC_SETFLAGS:
9057 +               if (get_user(flags, (int __user *) arg))
9058 +                       return -EFAULT;
9059 +
9060 +               flags = ocfs2_map_ext2(flags, 1);
9061 +               return ocfs2_set_iflags(inode, flags,
9062 +                       OCFS2_FL_MODIFIABLE);
9063 +       default:
9064 +               return -ENOTTY;
9065 +       }
9066 +}
9067 +
9068 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/ioctl.h linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/ioctl.h
9069 --- linux-2.6.17.11/fs/ocfs2/ioctl.h    1970-01-01 01:00:00 +0100
9070 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/ioctl.h       2006-07-09 17:06:49 +0200
9071 @@ -0,0 +1,17 @@
9072 +/*
9073 + * ioctl.h
9074 + *
9075 + * Function prototypes
9076 + *
9077 + * Copyright (C) 2006 Herbert Poetzl
9078 + *
9079 + */
9080 +
9081 +#ifndef OCFS2_IOCTL_H
9082 +#define OCFS2_IOCTL_H
9083 +
9084 +int ocfs2_set_iflags(struct inode *inode, unsigned flags, unsigned mask);
9085 +int ocfs2_ioctl(struct inode * inode, struct file * filp,
9086 +       unsigned int cmd, unsigned long arg);
9087 +
9088 +#endif /* OCFS2_IOCTL_H */
9089 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/namei.c linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/namei.c
9090 --- linux-2.6.17.11/fs/ocfs2/namei.c    2006-06-18 04:54:44 +0200
9091 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/namei.c       2006-07-09 17:06:49 +0200
9092 @@ -40,6 +40,7 @@
9093  #include <linux/types.h>
9094  #include <linux/slab.h>
9095  #include <linux/highmem.h>
9096 +#include <linux/vs_tag.h>
9097  
9098  #define MLOG_MASK_PREFIX ML_NAMEI
9099  #include <cluster/masklog.h>
9100 @@ -469,6 +470,9 @@ static int ocfs2_mknod_locked(struct ocf
9101         u64 fe_blkno = 0;
9102         u16 suballoc_bit;
9103         struct inode *inode = NULL;
9104 +       uid_t uid;
9105 +       gid_t gid;
9106 +       tag_t tag;
9107  
9108         mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
9109                    (unsigned long)dev, dentry->d_name.len,
9110 @@ -528,13 +532,19 @@ static int ocfs2_mknod_locked(struct ocf
9111         fe->i_blkno = cpu_to_le64(fe_blkno);
9112         fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
9113         fe->i_suballoc_slot = cpu_to_le16(osb->slot_num);
9114 -       fe->i_uid = cpu_to_le32(current->fsuid);
9115 +
9116 +       tag = dx_current_fstag(osb->sb);
9117 +       uid = current->fsuid;
9118         if (dir->i_mode & S_ISGID) {
9119 -               fe->i_gid = cpu_to_le32(dir->i_gid);
9120 +               gid = dir->i_gid;
9121                 if (S_ISDIR(mode))
9122                         mode |= S_ISGID;
9123         } else
9124 -               fe->i_gid = cpu_to_le32(current->fsgid);
9125 +               gid = current->fsgid;
9126 +
9127 +       fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode), uid, tag));
9128 +       fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode), gid, tag));
9129 +       inode->i_tag = tag;
9130         fe->i_mode = cpu_to_le16(mode);
9131         if (S_ISCHR(mode) || S_ISBLK(mode))
9132                 fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
9133 @@ -2265,4 +2275,5 @@ struct inode_operations ocfs2_dir_iops =
9134         .rename         = ocfs2_rename,
9135         .setattr        = ocfs2_setattr,
9136         .getattr        = ocfs2_getattr,
9137 +       .sync_flags     = ocfs2_sync_flags,
9138  };
9139 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/ocfs2.h linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/ocfs2.h
9140 --- linux-2.6.17.11/fs/ocfs2/ocfs2.h    2006-06-18 04:54:44 +0200
9141 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/ocfs2.h       2006-07-09 17:06:49 +0200
9142 @@ -174,6 +174,7 @@ enum ocfs2_mount_options
9143         OCFS2_MOUNT_NOINTR  = 1 << 2,   /* Don't catch signals */
9144         OCFS2_MOUNT_ERRORS_PANIC = 1 << 3, /* Panic on errors */
9145         OCFS2_MOUNT_DATA_WRITEBACK = 1 << 4, /* No data ordering */
9146 +       OCFS2_MOUNT_TAGGED = 1 << 8, /* use tagging */
9147  };
9148  
9149  #define OCFS2_OSB_SOFT_RO      0x0001
9150 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/ocfs2_fs.h linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/ocfs2_fs.h
9151 --- linux-2.6.17.11/fs/ocfs2/ocfs2_fs.h 2006-04-09 13:49:54 +0200
9152 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/ocfs2_fs.h    2006-07-09 17:06:49 +0200
9153 @@ -114,6 +114,30 @@
9154  #define OCFS2_CHAIN_FL         (0x00000400)    /* Chain allocator */
9155  #define OCFS2_DEALLOC_FL       (0x00000800)    /* Truncate log */
9156  
9157 +/* Inode attributes */
9158 +#define OCFS2_SECRM_FL         (0x00010000)    /* Secure deletion */
9159 +#define OCFS2_UNRM_FL          (0x00020000)    /* Undelete */
9160 +#define OCFS2_COMPR_FL         (0x00040000)    /* Compress file */
9161 +#define OCFS2_SYNC_FL          (0x00080000)    /* Synchronous updates */
9162 +#define OCFS2_IMMUTABLE_FL     (0x00100000)    /* Immutable file */
9163 +#define OCFS2_APPEND_FL                (0x00200000)    /* writes to file may only append */
9164 +#define OCFS2_NODUMP_FL                (0x00400000)    /* do not dump file */
9165 +#define OCFS2_NOATIME_FL       (0x00800000)    /* do not update atime */
9166 +#define OCFS2_DIRSYNC_FL       (0x01000000)    /* dirsync behaviour (directories only) */
9167 +
9168 +#define OCFS2_BARRIER_FL       (0x04000000)    /* Barrier for chroot() */
9169 +#define OCFS2_IUNLINK_FL       (0x08000000)    /* Immutable unlink */
9170 +
9171 +#define OCFS2_FL_VISIBLE       (0x01FF0000)    /* User visible flags */
9172 +#define OCFS2_FL_MODIFIABLE    (0x01FF0000)    /* User modifiable flags */
9173 +#define OCFS2_FL_MASK          (0x0FFF0000)    /* ext2 flag mask */
9174 +
9175 +/*
9176 + * ioctl commands
9177 + */
9178 +#define OCFS2_IOC_GETFLAGS     _IOR('f', 1, long)
9179 +#define OCFS2_IOC_SETFLAGS     _IOW('f', 2, long)
9180 +
9181  /*
9182   * Journal Flags (ocfs2_dinode.id1.journal1.i_flags)
9183   */
9184 diff -NurpP --minimal linux-2.6.17.11/fs/ocfs2/super.c linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/super.c
9185 --- linux-2.6.17.11/fs/ocfs2/super.c    2006-06-18 04:54:44 +0200
9186 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ocfs2/super.c       2006-07-09 17:06:49 +0200
9187 @@ -148,6 +148,7 @@ enum {
9188         Opt_hb_local,
9189         Opt_data_ordered,
9190         Opt_data_writeback,
9191 +       Opt_tag, Opt_notag, Opt_tagid,
9192         Opt_err,
9193  };
9194  
9195 @@ -161,6 +162,10 @@ static match_table_t tokens = {
9196         {Opt_hb_local, OCFS2_HB_LOCAL},
9197         {Opt_data_ordered, "data=ordered"},
9198         {Opt_data_writeback, "data=writeback"},
9199 +       {Opt_tag, "tag"},
9200 +       {Opt_tag, "tagxid"},
9201 +       {Opt_notag, "notag"},
9202 +       {Opt_tagid, "tagid=%u"},
9203         {Opt_err, NULL}
9204  };
9205  
9206 @@ -369,6 +374,14 @@ static int ocfs2_remount(struct super_bl
9207                 goto out;
9208         }
9209  
9210 +       printk("ocfs2_remount: %lx,%lx\n", osb->s_mount_opt, sb->s_flags);
9211 +       if ((parsed_options & OCFS2_MOUNT_TAGGED) &&
9212 +               !(sb->s_flags & MS_TAGGED)) {
9213 +               ret = -EINVAL;
9214 +               mlog(ML_ERROR, "Cannot change tagging on remount\n");
9215 +               goto out;
9216 +       }
9217 +
9218         if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) !=
9219             (parsed_options & OCFS2_MOUNT_HB_LOCAL)) {
9220                 ret = -EINVAL;
9221 @@ -642,6 +655,9 @@ static int ocfs2_fill_super(struct super
9222  
9223         ocfs2_complete_mount_recovery(osb);
9224  
9225 +       if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
9226 +               sb->s_flags |= MS_TAGGED;
9227 +
9228         printk("ocfs2: Mounting device (%u,%u) on (node %d, slot %d) with %s "
9229                "data mode.\n",
9230                MAJOR(sb->s_dev), MINOR(sb->s_dev), osb->node_num,
9231 @@ -753,6 +769,20 @@ static int ocfs2_parse_options(struct su
9232                 case Opt_data_writeback:
9233                         *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK;
9234                         break;
9235 +#ifndef CONFIG_TAGGING_NONE
9236 +               case Opt_tag:
9237 +                       *mount_opt |= OCFS2_MOUNT_TAGGED;
9238 +                       break;
9239 +               case Opt_notag:
9240 +                       *mount_opt &= ~OCFS2_MOUNT_TAGGED;
9241 +                       break;
9242 +#endif
9243 +#ifdef CONFIG_PROPAGATE
9244 +               case Opt_tagid:
9245 +                       /* use args[0] */
9246 +                       *mount_opt |= OCFS2_MOUNT_TAGGED;
9247 +                       break;
9248 +#endif
9249                 default:
9250                         mlog(ML_ERROR,
9251                              "Unrecognized mount option \"%s\" "
9252 diff -NurpP --minimal linux-2.6.17.11/fs/open.c linux-2.6.17.11-vs2.1.1-rc31/fs/open.c
9253 --- linux-2.6.17.11/fs/open.c   2006-06-18 04:54:44 +0200
9254 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/open.c      2006-07-09 17:06:49 +0200
9255 @@ -28,6 +28,9 @@
9256  #include <linux/syscalls.h>
9257  #include <linux/rcupdate.h>
9258  #include <linux/audit.h>
9259 +#include <linux/vs_limit.h>
9260 +#include <linux/vs_dlimit.h>
9261 +#include <linux/vserver/tag.h>
9262  
9263  #include <asm/unistd.h>
9264  
9265 @@ -46,6 +49,8 @@ int vfs_statfs(struct super_block *sb, s
9266                         if (retval == 0 && buf->f_frsize == 0)
9267                                 buf->f_frsize = buf->f_bsize;
9268                 }
9269 +               if (!vx_check(0, VX_ADMIN|VX_WATCH))
9270 +                       vx_vsi_statfs(sb, buf);
9271         }
9272         return retval;
9273  }
9274 @@ -249,7 +254,7 @@ static long do_sys_truncate(const char _
9275                 goto dput_and_out;
9276  
9277         error = -EROFS;
9278 -       if (IS_RDONLY(inode))
9279 +       if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
9280                 goto dput_and_out;
9281  
9282         error = -EPERM;
9283 @@ -379,7 +384,7 @@ asmlinkage long sys_utime(char __user * 
9284         inode = nd.dentry->d_inode;
9285  
9286         error = -EROFS;
9287 -       if (IS_RDONLY(inode))
9288 +       if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
9289                 goto dput_and_out;
9290  
9291         /* Don't worry, the checks are done in inode_change_ok() */
9292 @@ -436,7 +441,7 @@ long do_utimes(int dfd, char __user *fil
9293         inode = nd.dentry->d_inode;
9294  
9295         error = -EROFS;
9296 -       if (IS_RDONLY(inode))
9297 +       if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
9298                 goto dput_and_out;
9299  
9300         /* Don't worry, the checks are done in inode_change_ok() */
9301 @@ -523,7 +528,8 @@ asmlinkage long sys_faccessat(int dfd, c
9302         if (!res) {
9303                 res = vfs_permission(&nd, mode);
9304                 /* SuS v2 requires we report a read only fs too */
9305 -               if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
9306 +               if(!res && (mode & S_IWOTH)
9307 +                  && (IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
9308                    && !special_file(nd.dentry->d_inode->i_mode))
9309                         res = -EROFS;
9310                 path_release(&nd);
9311 @@ -636,7 +642,7 @@ asmlinkage long sys_fchmod(unsigned int 
9312         audit_inode(NULL, inode, 0);
9313  
9314         err = -EROFS;
9315 -       if (IS_RDONLY(inode))
9316 +       if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt))
9317                 goto out_putf;
9318         err = -EPERM;
9319         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9320 @@ -669,7 +675,7 @@ asmlinkage long sys_fchmodat(int dfd, co
9321         inode = nd.dentry->d_inode;
9322  
9323         error = -EROFS;
9324 -       if (IS_RDONLY(inode))
9325 +       if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
9326                 goto dput_and_out;
9327  
9328         error = -EPERM;
9329 @@ -695,7 +701,8 @@ asmlinkage long sys_chmod(const char __u
9330         return sys_fchmodat(AT_FDCWD, filename, mode);
9331  }
9332  
9333 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
9334 +static int chown_common(struct dentry *dentry, struct vfsmount *mnt,
9335 +       uid_t user, gid_t group)
9336  {
9337         struct inode * inode;
9338         int error;
9339 @@ -707,7 +714,7 @@ static int chown_common(struct dentry * 
9340                 goto out;
9341         }
9342         error = -EROFS;
9343 -       if (IS_RDONLY(inode))
9344 +       if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
9345                 goto out;
9346         error = -EPERM;
9347         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9348 @@ -715,11 +722,11 @@ static int chown_common(struct dentry * 
9349         newattrs.ia_valid =  ATTR_CTIME;
9350         if (user != (uid_t) -1) {
9351                 newattrs.ia_valid |= ATTR_UID;
9352 -               newattrs.ia_uid = user;
9353 +               newattrs.ia_uid = dx_map_uid(user);
9354         }
9355         if (group != (gid_t) -1) {
9356                 newattrs.ia_valid |= ATTR_GID;
9357 -               newattrs.ia_gid = group;
9358 +               newattrs.ia_gid = dx_map_gid(group);
9359         }
9360         if (!S_ISDIR(inode->i_mode))
9361                 newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
9362 @@ -737,7 +744,7 @@ asmlinkage long sys_chown(const char __u
9363  
9364         error = user_path_walk(filename, &nd);
9365         if (!error) {
9366 -               error = chown_common(nd.dentry, user, group);
9367 +               error = chown_common(nd.dentry, nd.mnt, user, group);
9368                 path_release(&nd);
9369         }
9370         return error;
9371 @@ -756,7 +763,7 @@ asmlinkage long sys_fchownat(int dfd, co
9372         follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
9373         error = __user_walk_fd(dfd, filename, follow, &nd);
9374         if (!error) {
9375 -               error = chown_common(nd.dentry, user, group);
9376 +               error = chown_common(nd.dentry, nd.mnt, user, group);
9377                 path_release(&nd);
9378         }
9379  out:
9380 @@ -770,7 +777,7 @@ asmlinkage long sys_lchown(const char __
9381  
9382         error = user_path_walk_link(filename, &nd);
9383         if (!error) {
9384 -               error = chown_common(nd.dentry, user, group);
9385 +               error = chown_common(nd.dentry, nd.mnt, user, group);
9386                 path_release(&nd);
9387         }
9388         return error;
9389 @@ -787,7 +794,7 @@ asmlinkage long sys_fchown(unsigned int 
9390                 struct dentry * dentry;
9391                 dentry = file->f_dentry;
9392                 audit_inode(NULL, dentry->d_inode, 0);
9393 -               error = chown_common(dentry, user, group);
9394 +               error = chown_common(dentry, file->f_vfsmnt, user, group);
9395                 fput(file);
9396         }
9397         return error;
9398 @@ -1015,6 +1022,7 @@ repeat:
9399         FD_SET(fd, fdt->open_fds);
9400         FD_CLR(fd, fdt->close_on_exec);
9401         files->next_fd = fd + 1;
9402 +       vx_openfd_inc(fd);
9403  #if 1
9404         /* Sanity check */
9405         if (fdt->fd[fd] != NULL) {
9406 @@ -1037,6 +1045,7 @@ static void __put_unused_fd(struct files
9407         __FD_CLR(fd, fdt->open_fds);
9408         if (fd < files->next_fd)
9409                 files->next_fd = fd;
9410 +       vx_openfd_dec(fd);
9411  }
9412  
9413  void fastcall put_unused_fd(unsigned int fd)
9414 diff -NurpP --minimal linux-2.6.17.11/fs/proc/array.c linux-2.6.17.11-vs2.1.1-rc31/fs/proc/array.c
9415 --- linux-2.6.17.11/fs/proc/array.c     2006-06-18 04:54:45 +0200
9416 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/proc/array.c        2006-08-19 19:46:49 +0200
9417 @@ -75,6 +75,9 @@
9418  #include <linux/times.h>
9419  #include <linux/cpuset.h>
9420  #include <linux/rcupdate.h>
9421 +#include <linux/vs_context.h>
9422 +#include <linux/vs_network.h>
9423 +#include <linux/vs_pid.h>
9424  
9425  #include <asm/uaccess.h>
9426  #include <asm/pgtable.h>
9427 @@ -135,7 +138,9 @@ static const char *task_state_array[] = 
9428         "T (stopped)",          /*  4 */
9429         "T (tracing stop)",     /*  8 */
9430         "Z (zombie)",           /* 16 */
9431 -       "X (dead)"              /* 32 */
9432 +       "X (dead)",             /* 32 */
9433 +       "N (noninteractive)",   /* 64 */
9434 +       "H (on hold)"           /* 128 */
9435  };
9436  
9437  static inline const char * get_task_state(struct task_struct *tsk)
9438 @@ -144,7 +149,8 @@ static inline const char * get_task_stat
9439                                             TASK_INTERRUPTIBLE |
9440                                             TASK_UNINTERRUPTIBLE |
9441                                             TASK_STOPPED |
9442 -                                           TASK_TRACED)) |
9443 +                                          TASK_TRACED |
9444 +                                          TASK_ONHOLD)) |
9445                         (tsk->exit_state & (EXIT_ZOMBIE |
9446                                             EXIT_DEAD));
9447         const char **p = &task_state_array[0];
9448 @@ -161,8 +167,13 @@ static inline char * task_state(struct t
9449         struct group_info *group_info;
9450         int g;
9451         struct fdtable *fdt = NULL;
9452 +       pid_t pid, ptgid, tppid, tgid;
9453  
9454         read_lock(&tasklist_lock);
9455 +       tgid = vx_map_tgid(p->tgid);
9456 +       pid = vx_map_pid(p->pid);
9457 +       ptgid = vx_map_pid(p->group_leader->real_parent->tgid);
9458 +       tppid = vx_map_pid(p->parent->pid);
9459         buffer += sprintf(buffer,
9460                 "State:\t%s\n"
9461                 "SleepAVG:\t%lu%%\n"
9462 @@ -174,9 +185,8 @@ static inline char * task_state(struct t
9463                 "Gid:\t%d\t%d\t%d\t%d\n",
9464                 get_task_state(p),
9465                 (p->sleep_avg/1024)*100/(1020000000/1024),
9466 -               p->tgid,
9467 -               p->pid, pid_alive(p) ? p->group_leader->real_parent->tgid : 0,
9468 -               pid_alive(p) && p->ptrace ? p->parent->pid : 0,
9469 +               tgid, pid, (pid > 1) ? ptgid : 0,
9470 +               pid_alive(p) && p->ptrace ? tppid : 0,
9471                 p->uid, p->euid, p->suid, p->fsuid,
9472                 p->gid, p->egid, p->sgid, p->fsgid);
9473         read_unlock(&tasklist_lock);
9474 @@ -285,17 +295,26 @@ static inline char * task_sig(struct tas
9475  
9476  static inline char *task_cap(struct task_struct *p, char *buffer)
9477  {
9478 -    return buffer + sprintf(buffer, "CapInh:\t%016x\n"
9479 -                           "CapPrm:\t%016x\n"
9480 -                           "CapEff:\t%016x\n",
9481 -                           cap_t(p->cap_inheritable),
9482 -                           cap_t(p->cap_permitted),
9483 -                           cap_t(p->cap_effective));
9484 +       struct vx_info *vxi = p->vx_info;
9485 +
9486 +       return buffer + sprintf(buffer,
9487 +               "CapInh:\t%016x\n"
9488 +               "CapPrm:\t%016x\n"
9489 +               "CapEff:\t%016x\n",
9490 +               (unsigned)vx_info_mbcap(vxi, p->cap_inheritable),
9491 +               (unsigned)vx_info_mbcap(vxi, p->cap_permitted),
9492 +               (unsigned)vx_info_mbcap(vxi, p->cap_effective));
9493  }
9494  
9495  int proc_pid_status(struct task_struct *task, char * buffer)
9496  {
9497         char * orig = buffer;
9498 +#ifdef CONFIG_VSERVER_LEGACY
9499 +       struct vx_info *vxi;
9500 +#endif
9501 +#ifdef CONFIG_VSERVER_LEGACYNET
9502 +       struct nx_info *nxi;
9503 +#endif
9504         struct mm_struct *mm = get_task_mm(task);
9505  
9506         buffer = task_name(task, buffer);
9507 @@ -308,6 +327,46 @@ int proc_pid_status(struct task_struct *
9508         buffer = task_sig(task, buffer);
9509         buffer = task_cap(task, buffer);
9510         buffer = cpuset_task_status_allowed(task, buffer);
9511 +
9512 +       if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
9513 +               goto skip;
9514 +#ifdef CONFIG_VSERVER_LEGACY
9515 +       buffer += sprintf (buffer,"s_context: %d\n", vx_task_xid(task));
9516 +       vxi = task_get_vx_info(task);
9517 +       if (vxi) {
9518 +               buffer += sprintf (buffer,"ctxflags: %08llx\n"
9519 +                       ,(unsigned long long)vxi->vx_flags);
9520 +               buffer += sprintf (buffer,"initpid: %d\n"
9521 +                       ,vxi->vx_initpid);
9522 +       } else {
9523 +               buffer += sprintf (buffer,"ctxflags: none\n");
9524 +               buffer += sprintf (buffer,"initpid: none\n");
9525 +       }
9526 +       put_vx_info(vxi);
9527 +#else
9528 +       buffer += sprintf (buffer,"VxID: %d\n", vx_task_xid(task));
9529 +#endif
9530 +#ifdef CONFIG_VSERVER_LEGACYNET
9531 +       nxi = task_get_nx_info(task);
9532 +       if (nxi) {
9533 +               int i;
9534 +
9535 +               buffer += sprintf (buffer,"ipv4root:");
9536 +               for (i=0; i<nxi->nbipv4; i++){
9537 +                       buffer += sprintf (buffer," %08x/%08x"
9538 +                               ,nxi->ipv4[i]
9539 +                               ,nxi->mask[i]);
9540 +               }
9541 +               *buffer++ = '\n';
9542 +               buffer += sprintf (buffer,"ipv4root_bcast: %08x\n"
9543 +                       ,nxi->v4_bcast);
9544 +       } else {
9545 +               buffer += sprintf (buffer,"ipv4root: 0\n");
9546 +               buffer += sprintf (buffer,"ipv4root_bcast: 0\n");
9547 +       }
9548 +       put_nx_info(nxi);
9549 +#endif
9550 +skip:
9551  #if defined(CONFIG_S390)
9552         buffer = task_show_regs(task, buffer);
9553  #endif
9554 @@ -322,7 +381,7 @@ static int do_task_stat(struct task_stru
9555         sigset_t sigign, sigcatch;
9556         char state;
9557         int res;
9558 -       pid_t ppid, pgid = -1, sid = -1;
9559 +       pid_t pid, ppid, pgid = -1, sid = -1;
9560         int num_threads = 0;
9561         struct mm_struct *mm;
9562         unsigned long long start_time;
9563 @@ -386,7 +445,11 @@ static int do_task_stat(struct task_stru
9564                         stime = cputime_add(stime, task->signal->stime);
9565                 }
9566         }
9567 -       ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0;
9568 +       pid = vx_info_map_pid(task->vx_info, pid_alive(task) ? task->pid : 0);
9569 +       ppid = (!(pid > 1)) ? 0 : vx_info_map_tgid(task->vx_info,
9570 +               task->group_leader->real_parent->tgid);
9571 +       pgid = vx_info_map_pid(task->vx_info, pgid);
9572 +
9573         read_unlock(&tasklist_lock);
9574  
9575         if (!whole || num_threads<2)
9576 @@ -410,10 +473,21 @@ static int do_task_stat(struct task_stru
9577         /* convert nsec -> ticks */
9578         start_time = nsec_to_clock_t(start_time);
9579  
9580 +       /* fixup start time for virt uptime */
9581 +       if (vx_flags(VXF_VIRT_UPTIME, 0)) {
9582 +               unsigned long long bias =
9583 +                       current->vx_info->cvirt.bias_clock;
9584 +
9585 +               if (start_time > bias)
9586 +                       start_time -= bias;
9587 +               else
9588 +                       start_time = 0;
9589 +       }
9590 +
9591         res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
9592  %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
9593  %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu\n",
9594 -               task->pid,
9595 +               pid,
9596                 tcomm,
9597                 state,
9598                 ppid,
9599 diff -NurpP --minimal linux-2.6.17.11/fs/proc/base.c linux-2.6.17.11-vs2.1.1-rc31/fs/proc/base.c
9600 --- linux-2.6.17.11/fs/proc/base.c      2006-08-25 00:25:37 +0200
9601 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/proc/base.c 2006-08-25 21:33:32 +0200
9602 @@ -72,6 +72,9 @@
9603  #include <linux/cpuset.h>
9604  #include <linux/audit.h>
9605  #include <linux/poll.h>
9606 +#include <linux/vs_context.h>
9607 +#include <linux/vs_network.h>
9608 +#include <linux/vs_pid.h>
9609  #include "internal.h"
9610  
9611  /*
9612 @@ -122,6 +125,8 @@ enum pid_directory_inos {
9613         PROC_TGID_ATTR_EXEC,
9614         PROC_TGID_ATTR_FSCREATE,
9615  #endif
9616 +       PROC_TGID_VX_INFO,
9617 +       PROC_TGID_IP_INFO,
9618  #ifdef CONFIG_AUDITSYSCALL
9619         PROC_TGID_LOGINUID,
9620  #endif
9621 @@ -163,6 +168,8 @@ enum pid_directory_inos {
9622         PROC_TID_ATTR_EXEC,
9623         PROC_TID_ATTR_FSCREATE,
9624  #endif
9625 +       PROC_TID_VX_INFO,
9626 +       PROC_TID_IP_INFO,
9627  #ifdef CONFIG_AUDITSYSCALL
9628         PROC_TID_LOGINUID,
9629  #endif
9630 @@ -219,6 +226,8 @@ static struct pid_entry tgid_base_stuff[
9631  #ifdef CONFIG_CPUSETS
9632         E(PROC_TGID_CPUSET,    "cpuset",  S_IFREG|S_IRUGO),
9633  #endif
9634 +       E(PROC_TGID_VX_INFO,   "vinfo",   S_IFREG|S_IRUGO),
9635 +       E(PROC_TGID_IP_INFO,   "ninfo",   S_IFREG|S_IRUGO),
9636         E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
9637         E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
9638  #ifdef CONFIG_AUDITSYSCALL
9639 @@ -261,6 +270,8 @@ static struct pid_entry tid_base_stuff[]
9640  #ifdef CONFIG_CPUSETS
9641         E(PROC_TID_CPUSET,     "cpuset",  S_IFREG|S_IRUGO),
9642  #endif
9643 +       E(PROC_TID_VX_INFO,    "vinfo",   S_IFREG|S_IRUGO),
9644 +       E(PROC_TID_IP_INFO,    "ninfo",   S_IFREG|S_IRUGO),
9645         E(PROC_TID_OOM_SCORE,  "oom_score",S_IFREG|S_IRUGO),
9646         E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
9647  #ifdef CONFIG_AUDITSYSCALL
9648 @@ -547,6 +558,10 @@ static int proc_check_chroot(struct dent
9649         struct vfsmount *our_vfsmnt, *mnt;
9650         int res = 0;
9651  
9652 +       /* context admin override */
9653 +       if (capable(CAP_CONTEXT))
9654 +               goto override;
9655 +
9656         read_lock(&current->fs->lock);
9657         our_vfsmnt = mntget(current->fs->rootmnt);
9658         base = dget(current->fs->root);
9659 @@ -570,6 +585,7 @@ static int proc_check_chroot(struct dent
9660  exit:
9661         dput(base);
9662         mntput(our_vfsmnt);
9663 +override:
9664         dput(root);
9665         mntput(vfsmnt);
9666         return res;
9667 @@ -1286,7 +1302,7 @@ static int proc_pident_readdir(struct fi
9668         struct inode *inode = dentry->d_inode;
9669         struct pid_entry *p;
9670         ino_t ino;
9671 -       int ret;
9672 +       int ret, hide;
9673  
9674         ret = -ENOENT;
9675         if (!pid_alive(proc_task(inode)))
9676 @@ -1317,11 +1333,20 @@ static int proc_pident_readdir(struct fi
9677                         goto out;
9678                 }
9679                 p = ents + i;
9680 +               hide = vx_flags(VXF_HIDE_VINFO, 0);
9681                 while (p->name) {
9682 +                       if (hide) {
9683 +                               switch (p->type) {
9684 +                               case PROC_TGID_VX_INFO:
9685 +                               case PROC_TGID_IP_INFO:
9686 +                                       goto skip;
9687 +                               }
9688 +                       }
9689                         if (filldir(dirent, p->name, p->len, filp->f_pos,
9690                                     fake_ino(pid, p->type), p->mode >> 12) < 0)
9691                                 goto out;
9692                         filp->f_pos++;
9693 +               skip:
9694                         p++;
9695                 }
9696         }
9697 @@ -1396,6 +1421,8 @@ static struct inode *proc_pid_make_inode
9698                 inode->i_uid = task->euid;
9699                 inode->i_gid = task->egid;
9700         }
9701 +       /* procfs is xid tagged */
9702 +       inode->i_tag = (tag_t)vx_task_xid(task);
9703         security_task_to_inode(task, inode);
9704  
9705  out:
9706 @@ -1421,7 +1448,11 @@ static int pid_revalidate(struct dentry 
9707  {
9708         struct inode *inode = dentry->d_inode;
9709         struct task_struct *task = proc_task(inode);
9710 +
9711         if (pid_alive(task)) {
9712 +               if (!vx_check(vx_task_xid(task), VX_IDENT))
9713 +                       goto out_drop;
9714 +
9715                 if (proc_type(inode) == PROC_TGID_INO || proc_type(inode) == PROC_TID_INO || task_dumpable(task)) {
9716                         inode->i_uid = task->euid;
9717                         inode->i_gid = task->egid;
9718 @@ -1433,6 +1464,7 @@ static int pid_revalidate(struct dentry 
9719                 security_task_to_inode(task, inode);
9720                 return 1;
9721         }
9722 +out_drop:
9723         d_drop(dentry);
9724         return 0;
9725  }
9726 @@ -1675,6 +1707,9 @@ static struct file_operations proc_tgid_
9727  static struct inode_operations proc_tgid_attr_inode_operations;
9728  #endif
9729  
9730 +extern int proc_pid_vx_info(struct task_struct *, char *);
9731 +extern int proc_pid_nx_info(struct task_struct *, char *);
9732 +
9733  static int get_tid_list(int index, unsigned int *tids, struct inode *dir);
9734  
9735  /* SMP-safe */
9736 @@ -1866,15 +1901,33 @@ static struct dentry *proc_pident_lookup
9737                         inode->i_fop = &proc_loginuid_operations;
9738                         break;
9739  #endif
9740 +               case PROC_TID_VX_INFO:
9741 +               case PROC_TGID_VX_INFO:
9742 +                       if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
9743 +                               goto out_noent;
9744 +                       inode->i_fop = &proc_info_file_operations;
9745 +                       ei->op.proc_read = proc_pid_vx_info;
9746 +                       break;
9747 +               case PROC_TID_IP_INFO:
9748 +               case PROC_TGID_IP_INFO:
9749 +                       if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
9750 +                               goto out_noent;
9751 +                       inode->i_fop = &proc_info_file_operations;
9752 +                       ei->op.proc_read = proc_pid_nx_info;
9753 +                       break;
9754                 default:
9755                         printk("procfs: impossible type (%d)",p->type);
9756 -                       iput(inode);
9757 -                       return ERR_PTR(-EINVAL);
9758 +                       error = -EINVAL;
9759 +                       goto out_put;
9760         }
9761         dentry->d_op = &pid_dentry_operations;
9762         d_add(dentry, inode);
9763         return NULL;
9764  
9765 +out_noent:
9766 +       error=-ENOENT;
9767 +out_put:
9768 +       iput(inode);
9769  out:
9770         return ERR_PTR(error);
9771  }
9772 @@ -1962,14 +2015,14 @@ static int proc_self_readlink(struct den
9773                               int buflen)
9774  {
9775         char tmp[30];
9776 -       sprintf(tmp, "%d", current->tgid);
9777 +       sprintf(tmp, "%d", vx_map_tgid(current->tgid));
9778         return vfs_readlink(dentry,buffer,buflen,tmp);
9779  }
9780  
9781  static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
9782  {
9783         char tmp[30];
9784 -       sprintf(tmp, "%d", current->tgid);
9785 +       sprintf(tmp, "%d", vx_map_tgid(current->tgid));
9786         return ERR_PTR(vfs_follow_link(nd,tmp));
9787  }      
9788  
9789 @@ -2033,6 +2086,20 @@ void proc_pid_flush(struct dentry *proc_
9790         }
9791  }
9792  
9793 +#define VXF_FAKE_INIT  (VXF_INFO_INIT|VXF_STATE_INIT)
9794 +
9795 +static inline int proc_pid_visible(struct task_struct *task, int pid)
9796 +{
9797 +       if ((pid == 1) &&
9798 +               !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
9799 +               goto visible;
9800 +       if (vx_check(vx_task_xid(task), VX_WATCH|VX_IDENT))
9801 +               goto visible;
9802 +       return 0;
9803 +visible:
9804 +       return 1;
9805 +}
9806 +
9807  /* SMP-safe */
9808  struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
9809  {
9810 @@ -2069,13 +2136,14 @@ struct dentry *proc_pid_lookup(struct in
9811         if (!task)
9812                 goto out;
9813  
9814 -       inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
9815 +       /* check for context visibility */
9816 +       if (!proc_pid_visible(task, tgid))
9817 +               goto out_drop_task;
9818  
9819 +       inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO);
9820 +       if (!inode)
9821 +               goto out_drop_task;
9822  
9823 -       if (!inode) {
9824 -               put_task_struct(task);
9825 -               goto out;
9826 -       }
9827         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
9828         inode->i_op = &proc_tgid_base_inode_operations;
9829         inode->i_fop = &proc_tgid_base_operations;
9830 @@ -2104,6 +2172,8 @@ struct dentry *proc_pid_lookup(struct in
9831                 goto out;
9832         }
9833         return NULL;
9834 +out_drop_task:
9835 +       put_task_struct(task);
9836  out:
9837         return ERR_PTR(-ENOENT);
9838  }
9839 @@ -2119,6 +2189,8 @@ static struct dentry *proc_task_lookup(s
9840         tid = name_to_int(dentry);
9841         if (tid == ~0U)
9842                 goto out;
9843 +       if (vx_current_initpid(tid))
9844 +               goto out;
9845  
9846         read_lock(&tasklist_lock);
9847         task = find_task_by_pid(tid);
9848 @@ -2130,11 +2202,14 @@ static struct dentry *proc_task_lookup(s
9849         if (leader->tgid != task->tgid)
9850                 goto out_drop_task;
9851  
9852 -       inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);
9853 -
9854 +       /* check for context visibility */
9855 +       if (!proc_pid_visible(task, tid))
9856 +               goto out_drop_task;
9857  
9858 +       inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO);
9859         if (!inode)
9860                 goto out_drop_task;
9861 +
9862         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
9863         inode->i_op = &proc_tid_base_inode_operations;
9864         inode->i_fop = &proc_tid_base_operations;
9865 @@ -2174,7 +2249,7 @@ static int get_tgid_list(int index, unsi
9866         read_lock(&tasklist_lock);
9867         p = NULL;
9868         if (version) {
9869 -               p = find_task_by_pid(version);
9870 +               p = find_task_by_real_pid(version);
9871                 if (p && !thread_group_leader(p))
9872                         p = NULL;
9873         }
9874 @@ -2186,11 +2261,15 @@ static int get_tgid_list(int index, unsi
9875  
9876         for ( ; p != &init_task; p = next_task(p)) {
9877                 int tgid = p->pid;
9878 +
9879                 if (!pid_alive(p))
9880                         continue;
9881 +               /* check for context visibility */
9882 +               if (!proc_pid_visible(p, tgid))
9883 +                       continue;
9884                 if (--index >= 0)
9885                         continue;
9886 -               tgids[nr_tgids] = tgid;
9887 +               tgids[nr_tgids] = vx_map_tgid(tgid);
9888                 nr_tgids++;
9889                 if (nr_tgids >= PROC_MAXPIDS)
9890                         break;
9891 @@ -2220,10 +2299,13 @@ static int get_tid_list(int index, unsig
9892         if (pid_alive(task)) do {
9893                 int tid = task->pid;
9894  
9895 +               /* check for context visibility */
9896 +               if (!proc_pid_visible(task, tid))
9897 +                       continue;
9898                 if (--index >= 0)
9899                         continue;
9900                 if (tids != NULL)
9901 -                       tids[nr_tids] = tid;
9902 +                       tids[nr_tids] = vx_map_pid(tid);
9903                 nr_tids++;
9904                 if (nr_tids >= PROC_MAXPIDS)
9905                         break;
9906 @@ -2299,11 +2381,14 @@ static int proc_task_readdir(struct file
9907         unsigned int nr_tids, i;
9908         struct dentry *dentry = filp->f_dentry;
9909         struct inode *inode = dentry->d_inode;
9910 +       struct task_struct *task = proc_task(inode);
9911         int retval = -ENOENT;
9912         ino_t ino;
9913         unsigned long pos = filp->f_pos;  /* avoiding "long long" filp->f_pos */
9914  
9915 -       if (!pid_alive(proc_task(inode)))
9916 +       if (!vx_check(vx_task_xid(task), VX_WATCH|VX_IDENT))
9917 +               goto out;
9918 +       if (!pid_alive(task))
9919                 goto out;
9920         retval = 0;
9921  
9922 diff -NurpP --minimal linux-2.6.17.11/fs/proc/generic.c linux-2.6.17.11-vs2.1.1-rc31/fs/proc/generic.c
9923 --- linux-2.6.17.11/fs/proc/generic.c   2006-06-18 04:54:45 +0200
9924 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/proc/generic.c      2006-07-09 17:06:49 +0200
9925 @@ -20,6 +20,7 @@
9926  #include <linux/namei.h>
9927  #include <linux/bitops.h>
9928  #include <linux/spinlock.h>
9929 +#include <linux/vserver/inode.h>
9930  #include <asm/uaccess.h>
9931  
9932  #include "internal.h"
9933 @@ -395,12 +396,16 @@ struct dentry *proc_lookup(struct inode 
9934                 for (de = de->subdir; de ; de = de->next) {
9935                         if (de->namelen != dentry->d_name.len)
9936                                 continue;
9937 +                       if (!vx_hide_check(0, de->vx_flags))
9938 +                               continue;
9939                         if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
9940                                 unsigned int ino = de->low_ino;
9941  
9942                                 spin_unlock(&proc_subdir_lock);
9943                                 error = -EINVAL;
9944                                 inode = proc_get_inode(dir->i_sb, ino, de);
9945 +                               /* generic proc entries belong to the host */
9946 +                               inode->i_tag = 0;
9947                                 spin_lock(&proc_subdir_lock);
9948                                 break;
9949                         }
9950 @@ -476,12 +481,15 @@ int proc_readdir(struct file * filp,
9951                         }
9952  
9953                         do {
9954 +                               if (!vx_hide_check(0, de->vx_flags))
9955 +                                       goto skip;
9956                                 /* filldir passes info to user space */
9957                                 spin_unlock(&proc_subdir_lock);
9958                                 if (filldir(dirent, de->name, de->namelen, filp->f_pos,
9959                                             de->low_ino, de->mode >> 12) < 0)
9960                                         goto out;
9961                                 spin_lock(&proc_subdir_lock);
9962 +                       skip:
9963                                 filp->f_pos++;
9964                                 de = de->next;
9965                         } while (de);
9966 @@ -604,6 +612,7 @@ static struct proc_dir_entry *proc_creat
9967         ent->namelen = len;
9968         ent->mode = mode;
9969         ent->nlink = nlink;
9970 +       ent->vx_flags = IATTR_PROC_DEFAULT;
9971   out:
9972         return ent;
9973  }
9974 @@ -624,7 +633,8 @@ struct proc_dir_entry *proc_symlink(cons
9975                                 kfree(ent->data);
9976                                 kfree(ent);
9977                                 ent = NULL;
9978 -                       }
9979 +                       } else
9980 +                               ent->vx_flags = IATTR_PROC_SYMLINK;
9981                 } else {
9982                         kfree(ent);
9983                         ent = NULL;
9984 diff -NurpP --minimal linux-2.6.17.11/fs/proc/inode.c linux-2.6.17.11-vs2.1.1-rc31/fs/proc/inode.c
9985 --- linux-2.6.17.11/fs/proc/inode.c     2006-06-18 04:54:46 +0200
9986 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/proc/inode.c        2006-07-09 17:06:49 +0200
9987 @@ -171,6 +171,8 @@ struct inode *proc_get_inode(struct supe
9988                         inode->i_uid = de->uid;
9989                         inode->i_gid = de->gid;
9990                 }
9991 +               if (de->vx_flags)
9992 +                       PROC_I(inode)->vx_flags = de->vx_flags;
9993                 if (de->size)
9994                         inode->i_size = de->size;
9995                 if (de->nlink)
9996 diff -NurpP --minimal linux-2.6.17.11/fs/proc/proc_misc.c linux-2.6.17.11-vs2.1.1-rc31/fs/proc/proc_misc.c
9997 --- linux-2.6.17.11/fs/proc/proc_misc.c 2006-06-18 04:54:47 +0200
9998 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/proc/proc_misc.c    2006-07-09 17:06:49 +0200
9999 @@ -53,6 +53,8 @@
10000  #include <asm/div64.h>
10001  #include "internal.h"
10002  
10003 +#include <linux/vs_cvirt.h>
10004 +
10005  #define LOAD_INT(x) ((x) >> FSHIFT)
10006  #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
10007  /*
10008 @@ -82,17 +84,32 @@ static int proc_calc_metrics(char *page,
10009  static int loadavg_read_proc(char *page, char **start, off_t off,
10010                                  int count, int *eof, void *data)
10011  {
10012 +       unsigned int running, threads;
10013         int a, b, c;
10014         int len;
10015  
10016 -       a = avenrun[0] + (FIXED_1/200);
10017 -       b = avenrun[1] + (FIXED_1/200);
10018 -       c = avenrun[2] + (FIXED_1/200);
10019 -       len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
10020 +       if (vx_flags(VXF_VIRT_LOAD, 0)) {
10021 +               struct vx_info *vxi = current->vx_info;
10022 +
10023 +               a = vxi->cvirt.load[0] + (FIXED_1/200);
10024 +               b = vxi->cvirt.load[1] + (FIXED_1/200);
10025 +               c = vxi->cvirt.load[2] + (FIXED_1/200);
10026 +
10027 +               running = atomic_read(&vxi->cvirt.nr_running);
10028 +               threads = atomic_read(&vxi->cvirt.nr_threads);
10029 +       } else {
10030 +               a = avenrun[0] + (FIXED_1/200);
10031 +               b = avenrun[1] + (FIXED_1/200);
10032 +               c = avenrun[2] + (FIXED_1/200);
10033 +
10034 +               running = nr_running();
10035 +               threads = nr_threads;
10036 +       }
10037 +       len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
10038                 LOAD_INT(a), LOAD_FRAC(a),
10039                 LOAD_INT(b), LOAD_FRAC(b),
10040                 LOAD_INT(c), LOAD_FRAC(c),
10041 -               nr_running(), nr_threads, last_pid);
10042 +               running, threads, last_pid);
10043         return proc_calc_metrics(page, start, off, count, eof, len);
10044  }
10045  
10046 @@ -106,6 +123,9 @@ static int uptime_read_proc(char *page, 
10047  
10048         do_posix_clock_monotonic_gettime(&uptime);
10049         cputime_to_timespec(idletime, &idle);
10050 +       if (vx_flags(VXF_VIRT_UPTIME, 0))
10051 +               vx_vsi_uptime(&uptime, &idle);
10052 +
10053         len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
10054                         (unsigned long) uptime.tv_sec,
10055                         (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
10056 @@ -143,7 +163,7 @@ static int meminfo_read_proc(char *page,
10057                 * sysctl_overcommit_ratio / 100) + total_swap_pages;
10058  
10059         cached = get_page_cache_size() - total_swapcache_pages - i.bufferram;
10060 -       if (cached < 0)
10061 +       if (cached < 0 || vx_flags(VXF_VIRT_MEM, 0))
10062                 cached = 0;
10063  
10064         get_vmalloc_info(&vmi);
10065 @@ -238,8 +258,9 @@ static int version_read_proc(char *page,
10066  {
10067         int len;
10068  
10069 -       strcpy(page, linux_banner);
10070 -       len = strlen(page);
10071 +       len = sprintf(page, vx_linux_banner,
10072 +               vx_new_uts(release),
10073 +               vx_new_uts(version));
10074         return proc_calc_metrics(page, start, off, count, eof, len);
10075  }
10076  
10077 diff -NurpP --minimal linux-2.6.17.11/fs/proc/root.c linux-2.6.17.11-vs2.1.1-rc31/fs/proc/root.c
10078 --- linux-2.6.17.11/fs/proc/root.c      2006-04-09 13:49:54 +0200
10079 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/proc/root.c 2006-07-09 17:06:50 +0200
10080 @@ -25,6 +25,9 @@ struct proc_dir_entry *proc_net, *proc_n
10081  #ifdef CONFIG_SYSCTL
10082  struct proc_dir_entry *proc_sys_root;
10083  #endif
10084 +struct proc_dir_entry *proc_virtual;
10085 +
10086 +extern void proc_vx_init(void);
10087  
10088  static struct super_block *proc_get_sb(struct file_system_type *fs_type,
10089         int flags, const char *dev_name, void *data)
10090 @@ -78,6 +81,7 @@ void __init proc_root_init(void)
10091         proc_device_tree_init();
10092  #endif
10093         proc_bus = proc_mkdir("bus", NULL);
10094 +       proc_vx_init();
10095  }
10096  
10097  static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
10098 diff -NurpP --minimal linux-2.6.17.11/fs/quota.c linux-2.6.17.11-vs2.1.1-rc31/fs/quota.c
10099 --- linux-2.6.17.11/fs/quota.c  2006-06-18 04:54:47 +0200
10100 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/quota.c     2006-08-25 21:19:45 +0200
10101 @@ -17,47 +17,122 @@
10102  #include <linux/buffer_head.h>
10103  #include <linux/capability.h>
10104  #include <linux/quotaops.h>
10105 +#include <linux/major.h>
10106 +#include <linux/blkdev.h>
10107 +#include <linux/vserver/debug.h>
10108 +
10109 +
10110 +/* Dquota Hash Management Functions */
10111 +
10112 +static LIST_HEAD(dqhash_list);
10113 +
10114 +struct dqhash *new_dqhash(struct super_block *sb, unsigned int id)
10115 +{
10116 +       struct dqhash *hash;
10117 +       int err;
10118 +
10119 +       err = -ENOMEM;
10120 +       hash = kmalloc(sizeof(struct dqhash),  GFP_USER);
10121 +       if (!hash)
10122 +               goto out;
10123 +
10124 +       memset(hash, 0, sizeof(struct dqhash));
10125 +       hash->dqh_id = id;
10126 +       atomic_set(&hash->dqh_count, 1);
10127 +
10128 +       INIT_LIST_HEAD(&hash->dqh_list);
10129 +
10130 +       mutex_init(&hash->dqh_dqopt.dqio_mutex);
10131 +       mutex_init(&hash->dqh_dqopt.dqonoff_mutex);
10132 +       init_rwsem(&hash->dqh_dqopt.dqptr_sem);
10133 +       hash->dqh_qop = sb->s_qop;
10134 +       hash->dqh_qcop = sb->s_qcop;
10135 +       hash->dqh_sb = sb;
10136 +
10137 +       lock_kernel();
10138 +       list_add(&hash->dqh_list, &dqhash_list);
10139 +       unlock_kernel();
10140 +       vxdprintk(VXD_CBIT(misc, 0),
10141 +               "new_dqhash: %p [#0x%08x]", hash, hash->dqh_id);
10142 +       return hash;
10143 +
10144 +       // kfree(hash);
10145 +out:
10146 +       return ERR_PTR(err);
10147 +}
10148 +
10149 +void destroy_dqhash(struct dqhash *hash)
10150 +{
10151 +       vxdprintk(VXD_CBIT(misc, 0),
10152 +               "destroy_dqhash: %p [#0x%08x] c=%d",
10153 +               hash, hash->dqh_id, atomic_read(&hash->dqh_count));
10154 +       lock_kernel();
10155 +       list_del_init(&hash->dqh_list);
10156 +       unlock_kernel();
10157 +       kfree(hash);
10158 +}
10159 +
10160 +
10161 +struct dqhash *find_dqhash(unsigned int id)
10162 +{
10163 +       struct list_head *head;
10164 +       struct dqhash *hash;
10165 +
10166 +       lock_kernel();
10167 +       list_for_each(head, &dqhash_list) {
10168 +               hash = list_entry(head, struct dqhash, dqh_list);
10169 +               if (hash->dqh_id == id)
10170 +                       goto dqh_found;
10171 +       }
10172 +       unlock_kernel();
10173 +       return NULL;
10174 +
10175 +dqh_found:
10176 +       unlock_kernel();
10177 +       return dqhget(hash);
10178 +}
10179 +
10180  
10181  /* Check validity of generic quotactl commands */
10182 -static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
10183 +static int generic_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id)
10184  {
10185         if (type >= MAXQUOTAS)
10186                 return -EINVAL;
10187 -       if (!sb && cmd != Q_SYNC)
10188 +       if (!hash && cmd != Q_SYNC)
10189                 return -ENODEV;
10190         /* Is operation supported? */
10191 -       if (sb && !sb->s_qcop)
10192 +       if (hash && !hash->dqh_qcop)
10193                 return -ENOSYS;
10194  
10195         switch (cmd) {
10196                 case Q_GETFMT:
10197                         break;
10198                 case Q_QUOTAON:
10199 -                       if (!sb->s_qcop->quota_on)
10200 +                       if (!hash->dqh_qcop->quota_on)
10201                                 return -ENOSYS;
10202                         break;
10203                 case Q_QUOTAOFF:
10204 -                       if (!sb->s_qcop->quota_off)
10205 +                       if (!hash->dqh_qcop->quota_off)
10206                                 return -ENOSYS;
10207                         break;
10208                 case Q_SETINFO:
10209 -                       if (!sb->s_qcop->set_info)
10210 +                       if (!hash->dqh_qcop->set_info)
10211                                 return -ENOSYS;
10212                         break;
10213                 case Q_GETINFO:
10214 -                       if (!sb->s_qcop->get_info)
10215 +                       if (!hash->dqh_qcop->get_info)
10216                                 return -ENOSYS;
10217                         break;
10218                 case Q_SETQUOTA:
10219 -                       if (!sb->s_qcop->set_dqblk)
10220 +                       if (!hash->dqh_qcop->set_dqblk)
10221                                 return -ENOSYS;
10222                         break;
10223                 case Q_GETQUOTA:
10224 -                       if (!sb->s_qcop->get_dqblk)
10225 +                       if (!hash->dqh_qcop->get_dqblk)
10226                                 return -ENOSYS;
10227                         break;
10228                 case Q_SYNC:
10229 -                       if (sb && !sb->s_qcop->quota_sync)
10230 +                       if (hash && !hash->dqh_qcop->quota_sync)
10231                                 return -ENOSYS;
10232                         break;
10233                 default:
10234 @@ -73,7 +148,7 @@ static int generic_quotactl_valid(struct
10235                 case Q_SETQUOTA:
10236                 case Q_GETQUOTA:
10237                         /* This is just informative test so we are satisfied without a lock */
10238 -                       if (!sb_has_quota_enabled(sb, type))
10239 +                       if (!dqh_has_quota_enabled(hash, type))
10240                                 return -ESRCH;
10241         }
10242  
10243 @@ -81,47 +156,47 @@ static int generic_quotactl_valid(struct
10244         if (cmd == Q_GETQUOTA) {
10245                 if (((type == USRQUOTA && current->euid != id) ||
10246                      (type == GRPQUOTA && !in_egroup_p(id))) &&
10247 -                   !capable(CAP_SYS_ADMIN))
10248 +                   !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10249                         return -EPERM;
10250         }
10251         else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO)
10252 -               if (!capable(CAP_SYS_ADMIN))
10253 +               if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10254                         return -EPERM;
10255  
10256         return 0;
10257  }
10258  
10259  /* Check validity of XFS Quota Manager commands */
10260 -static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
10261 +static int xqm_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id)
10262  {
10263         if (type >= XQM_MAXQUOTAS)
10264                 return -EINVAL;
10265 -       if (!sb)
10266 +       if (!hash)
10267                 return -ENODEV;
10268 -       if (!sb->s_qcop)
10269 +       if (!hash->dqh_qcop)
10270                 return -ENOSYS;
10271  
10272         switch (cmd) {
10273                 case Q_XQUOTAON:
10274                 case Q_XQUOTAOFF:
10275                 case Q_XQUOTARM:
10276 -                       if (!sb->s_qcop->set_xstate)
10277 +                       if (!hash->dqh_qcop->set_xstate)
10278                                 return -ENOSYS;
10279                         break;
10280                 case Q_XGETQSTAT:
10281 -                       if (!sb->s_qcop->get_xstate)
10282 +                       if (!hash->dqh_qcop->get_xstate)
10283                                 return -ENOSYS;
10284                         break;
10285                 case Q_XSETQLIM:
10286 -                       if (!sb->s_qcop->set_xquota)
10287 +                       if (!hash->dqh_qcop->set_xquota)
10288                                 return -ENOSYS;
10289                         break;
10290                 case Q_XGETQUOTA:
10291 -                       if (!sb->s_qcop->get_xquota)
10292 +                       if (!hash->dqh_qcop->get_xquota)
10293                                 return -ENOSYS;
10294                         break;
10295                 case Q_XQUOTASYNC:
10296 -                       if (!sb->s_qcop->quota_sync)
10297 +                       if (!hash->dqh_qcop->quota_sync)
10298                                 return -ENOSYS;
10299                         break;
10300                 default:
10301 @@ -132,57 +207,68 @@ static int xqm_quotactl_valid(struct sup
10302         if (cmd == Q_XGETQUOTA) {
10303                 if (((type == XQM_USRQUOTA && current->euid != id) ||
10304                      (type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
10305 -                    !capable(CAP_SYS_ADMIN))
10306 +                    !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10307                         return -EPERM;
10308         } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) {
10309 -               if (!capable(CAP_SYS_ADMIN))
10310 +               if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10311                         return -EPERM;
10312         }
10313  
10314         return 0;
10315  }
10316  
10317 -static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
10318 +static int check_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id)
10319  {
10320         int error;
10321  
10322         if (XQM_COMMAND(cmd))
10323 -               error = xqm_quotactl_valid(sb, type, cmd, id);
10324 +               error = xqm_quotactl_valid(hash, type, cmd, id);
10325         else
10326 -               error = generic_quotactl_valid(sb, type, cmd, id);
10327 +               error = generic_quotactl_valid(hash, type, cmd, id);
10328         if (!error)
10329 -               error = security_quotactl(cmd, type, id, sb);
10330 +               error = security_quotactl(cmd, type, id, hash);
10331         return error;
10332  }
10333  
10334 -static void quota_sync_sb(struct super_block *sb, int type)
10335 +static void quota_sync_sb(struct super_block *sb)
10336  {
10337 -       int cnt;
10338 -       struct inode *discard[MAXQUOTAS];
10339 -
10340 -       sb->s_qcop->quota_sync(sb, type);
10341         /* This is not very clever (and fast) but currently I don't know about
10342          * any other simple way of getting quota data to disk and we must get
10343          * them there for userspace to be visible... */
10344         if (sb->s_op->sync_fs)
10345                 sb->s_op->sync_fs(sb, 1);
10346         sync_blockdev(sb->s_bdev);
10347 +}
10348 +
10349 +static void quota_sync_dqh(struct dqhash *hash, int type)
10350 +{
10351 +       int cnt;
10352 +       struct inode *discard[MAXQUOTAS];
10353 +
10354 +       vxdprintk(VXD_CBIT(quota, 1),
10355 +               "quota_sync_dqh(%p,%d)", hash, type);
10356 +       hash->dqh_qcop->quota_sync(hash, type);
10357 +
10358 +       quota_sync_sb(hash->dqh_sb);
10359  
10360         /* Now when everything is written we can discard the pagecache so
10361          * that userspace sees the changes. We need i_mutex and so we could
10362          * not do it inside dqonoff_mutex. Moreover we need to be carefull
10363          * about races with quotaoff() (that is the reason why we have own
10364          * reference to inode). */
10365 -       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
10366 +       mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
10367         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
10368                 discard[cnt] = NULL;
10369                 if (type != -1 && cnt != type)
10370                         continue;
10371 -               if (!sb_has_quota_enabled(sb, cnt))
10372 +               if (!dqh_has_quota_enabled(hash, cnt))
10373                         continue;
10374 -               discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]);
10375 +               vxdprintk(VXD_CBIT(quota, 0),
10376 +                       "quota_sync_dqh(%p,%d) discard inode %p",
10377 +                       hash, type, dqh_dqopt(hash)->files[cnt]);
10378 +               discard[cnt] = igrab(dqh_dqopt(hash)->files[cnt]);
10379         }
10380 -       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
10381 +       mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
10382         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
10383                 if (discard[cnt]) {
10384                         mutex_lock(&discard[cnt]->i_mutex);
10385 @@ -193,67 +279,59 @@ static void quota_sync_sb(struct super_b
10386         }
10387  }
10388  
10389 -void sync_dquots(struct super_block *sb, int type)
10390 +void sync_dquots_dqh(struct dqhash *hash, int type)
10391  {
10392 -       int cnt, dirty;
10393 +       vxdprintk(VXD_CBIT(quota, 1),
10394 +               "sync_dquots_dqh(%p,%d)", hash, type);
10395  
10396 -       if (sb) {
10397 -               if (sb->s_qcop->quota_sync)
10398 -                       quota_sync_sb(sb, type);
10399 -               return;
10400 -       }
10401 +       if (hash->dqh_qcop->quota_sync)
10402 +               quota_sync_dqh(hash, type);
10403 +}
10404  
10405 -       spin_lock(&sb_lock);
10406 -restart:
10407 -       list_for_each_entry(sb, &super_blocks, s_list) {
10408 -               /* This test just improves performance so it needn't be reliable... */
10409 -               for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
10410 -                       if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
10411 -                           && info_any_dirty(&sb_dqopt(sb)->info[cnt]))
10412 -                               dirty = 1;
10413 -               if (!dirty)
10414 -                       continue;
10415 -               sb->s_count++;
10416 -               spin_unlock(&sb_lock);
10417 -               down_read(&sb->s_umount);
10418 -               if (sb->s_root && sb->s_qcop->quota_sync)
10419 -                       quota_sync_sb(sb, type);
10420 -               up_read(&sb->s_umount);
10421 -               spin_lock(&sb_lock);
10422 -               if (__put_super_and_need_restart(sb))
10423 -                       goto restart;
10424 +void sync_dquots(struct dqhash *hash, int type)
10425 +
10426 +{
10427 +       vxdprintk(VXD_CBIT(quota, 1),
10428 +               "sync_dquots(%p,%d)", hash, type);
10429 +
10430 +       if (hash) {
10431 +               if (hash->dqh_qcop->quota_sync)
10432 +                       quota_sync_dqh(hash, type);
10433 +               return;
10434         }
10435 -       spin_unlock(&sb_lock);
10436  }
10437  
10438  /* Copy parameters and call proper function */
10439 -static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void __user *addr)
10440 +static int do_quotactl(struct dqhash *hash, int type, int cmd, qid_t id, void __user *addr)
10441  {
10442         int ret;
10443  
10444 +       vxdprintk(VXD_CBIT(quota, 3),
10445 +               "do_quotactl(%p,%d,cmd=%d,id=%d,%p)", hash, type, cmd, id, addr);
10446 +
10447         switch (cmd) {
10448                 case Q_QUOTAON: {
10449                         char *pathname;
10450  
10451                         if (IS_ERR(pathname = getname(addr)))
10452                                 return PTR_ERR(pathname);
10453 -                       ret = sb->s_qcop->quota_on(sb, type, id, pathname);
10454 +                       ret = hash->dqh_qcop->quota_on(hash, type, id, pathname);
10455                         putname(pathname);
10456                         return ret;
10457                 }
10458                 case Q_QUOTAOFF:
10459 -                       return sb->s_qcop->quota_off(sb, type);
10460 +                       return hash->dqh_qcop->quota_off(hash, type);
10461  
10462                 case Q_GETFMT: {
10463                         __u32 fmt;
10464  
10465 -                       down_read(&sb_dqopt(sb)->dqptr_sem);
10466 -                       if (!sb_has_quota_enabled(sb, type)) {
10467 -                               up_read(&sb_dqopt(sb)->dqptr_sem);
10468 +                       down_read(&dqh_dqopt(hash)->dqptr_sem);
10469 +                       if (!dqh_has_quota_enabled(hash, type)) {
10470 +                               up_read(&dqh_dqopt(hash)->dqptr_sem);
10471                                 return -ESRCH;
10472                         }
10473 -                       fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
10474 -                       up_read(&sb_dqopt(sb)->dqptr_sem);
10475 +                       fmt = dqh_dqopt(hash)->info[type].dqi_format->qf_fmt_id;
10476 +                       up_read(&dqh_dqopt(hash)->dqptr_sem);
10477                         if (copy_to_user(addr, &fmt, sizeof(fmt)))
10478                                 return -EFAULT;
10479                         return 0;
10480 @@ -261,7 +339,7 @@ static int do_quotactl(struct super_bloc
10481                 case Q_GETINFO: {
10482                         struct if_dqinfo info;
10483  
10484 -                       if ((ret = sb->s_qcop->get_info(sb, type, &info)))
10485 +                       if ((ret = hash->dqh_qcop->get_info(hash, type, &info)))
10486                                 return ret;
10487                         if (copy_to_user(addr, &info, sizeof(info)))
10488                                 return -EFAULT;
10489 @@ -272,12 +350,12 @@ static int do_quotactl(struct super_bloc
10490  
10491                         if (copy_from_user(&info, addr, sizeof(info)))
10492                                 return -EFAULT;
10493 -                       return sb->s_qcop->set_info(sb, type, &info);
10494 +                       return hash->dqh_qcop->set_info(hash, type, &info);
10495                 }
10496                 case Q_GETQUOTA: {
10497                         struct if_dqblk idq;
10498  
10499 -                       if ((ret = sb->s_qcop->get_dqblk(sb, type, id, &idq)))
10500 +                       if ((ret = hash->dqh_qcop->get_dqblk(hash, type, id, &idq)))
10501                                 return ret;
10502                         if (copy_to_user(addr, &idq, sizeof(idq)))
10503                                 return -EFAULT;
10504 @@ -288,10 +366,10 @@ static int do_quotactl(struct super_bloc
10505  
10506                         if (copy_from_user(&idq, addr, sizeof(idq)))
10507                                 return -EFAULT;
10508 -                       return sb->s_qcop->set_dqblk(sb, type, id, &idq);
10509 +                       return hash->dqh_qcop->set_dqblk(hash, type, id, &idq);
10510                 }
10511                 case Q_SYNC:
10512 -                       sync_dquots(sb, type);
10513 +                       sync_dquots_dqh(hash, type);
10514                         return 0;
10515  
10516                 case Q_XQUOTAON:
10517 @@ -301,12 +379,12 @@ static int do_quotactl(struct super_bloc
10518  
10519                         if (copy_from_user(&flags, addr, sizeof(flags)))
10520                                 return -EFAULT;
10521 -                       return sb->s_qcop->set_xstate(sb, flags, cmd);
10522 +                       return hash->dqh_qcop->set_xstate(hash, flags, cmd);
10523                 }
10524                 case Q_XGETQSTAT: {
10525                         struct fs_quota_stat fqs;
10526                 
10527 -                       if ((ret = sb->s_qcop->get_xstate(sb, &fqs)))
10528 +                       if ((ret = hash->dqh_qcop->get_xstate(hash, &fqs)))
10529                                 return ret;
10530                         if (copy_to_user(addr, &fqs, sizeof(fqs)))
10531                                 return -EFAULT;
10532 @@ -317,19 +395,19 @@ static int do_quotactl(struct super_bloc
10533  
10534                         if (copy_from_user(&fdq, addr, sizeof(fdq)))
10535                                 return -EFAULT;
10536 -                      return sb->s_qcop->set_xquota(sb, type, id, &fdq);
10537 +                      return hash->dqh_qcop->set_xquota(hash, type, id, &fdq);
10538                 }
10539                 case Q_XGETQUOTA: {
10540                         struct fs_disk_quota fdq;
10541  
10542 -                       if ((ret = sb->s_qcop->get_xquota(sb, type, id, &fdq)))
10543 +                       if ((ret = hash->dqh_qcop->get_xquota(hash, type, id, &fdq)))
10544                                 return ret;
10545                         if (copy_to_user(addr, &fdq, sizeof(fdq)))
10546                                 return -EFAULT;
10547                         return 0;
10548                 }
10549                 case Q_XQUOTASYNC:
10550 -                       return sb->s_qcop->quota_sync(sb, type);
10551 +                       return hash->dqh_qcop->quota_sync(hash, type);
10552                 /* We never reach here unless validity check is broken */
10553                 default:
10554                         BUG();
10555 @@ -337,6 +415,43 @@ static int do_quotactl(struct super_bloc
10556         return 0;
10557  }
10558  
10559 +#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
10560 +
10561 +#include <linux/vroot.h>
10562 +#include <linux/kallsyms.h>
10563 +
10564 +static vroot_grb_func *vroot_get_real_bdev = NULL;
10565 +
10566 +static spinlock_t vroot_grb_lock = SPIN_LOCK_UNLOCKED;
10567 +
10568 +int register_vroot_grb(vroot_grb_func *func) {
10569 +       int ret = -EBUSY;
10570 +
10571 +       spin_lock(&vroot_grb_lock);
10572 +       if (!vroot_get_real_bdev) {
10573 +               vroot_get_real_bdev = func;
10574 +               ret = 0;
10575 +       }
10576 +       spin_unlock(&vroot_grb_lock);
10577 +       return ret;
10578 +}
10579 +EXPORT_SYMBOL(register_vroot_grb);
10580 +
10581 +int unregister_vroot_grb(vroot_grb_func *func) {
10582 +       int ret = -EINVAL;
10583 +
10584 +       spin_lock(&vroot_grb_lock);
10585 +       if (vroot_get_real_bdev) {
10586 +               vroot_get_real_bdev = NULL;
10587 +               ret = 0;
10588 +       }
10589 +       spin_unlock(&vroot_grb_lock);
10590 +       return ret;
10591 +}
10592 +EXPORT_SYMBOL(unregister_vroot_grb);
10593 +
10594 +#endif
10595 +
10596  /*
10597   * This is the system call interface. This communicates with
10598   * the user-level programs. Currently this only supports diskquota
10599 @@ -347,6 +462,7 @@ asmlinkage long sys_quotactl(unsigned in
10600  {
10601         uint cmds, type;
10602         struct super_block *sb = NULL;
10603 +       struct dqhash *dqh = NULL;
10604         struct block_device *bdev;
10605         char *tmp;
10606         int ret;
10607 @@ -362,15 +478,33 @@ asmlinkage long sys_quotactl(unsigned in
10608                 putname(tmp);
10609                 if (IS_ERR(bdev))
10610                         return PTR_ERR(bdev);
10611 +#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
10612 +               if (bdev && bdev->bd_inode &&
10613 +                       imajor(bdev->bd_inode) == VROOT_MAJOR) {
10614 +                       struct block_device *bdnew = (void *)-EINVAL;
10615 +
10616 +                       if (vroot_get_real_bdev)
10617 +                               bdnew = vroot_get_real_bdev(bdev);
10618 +                       else
10619 +                               vxdprintk(VXD_CBIT(misc, 0),
10620 +                                       "vroot_get_real_bdev not set");
10621 +
10622 +                       bdput(bdev);
10623 +                       if (IS_ERR(bdnew))
10624 +                               return PTR_ERR(bdnew);
10625 +                       bdev = bdnew;
10626 +               }
10627 +#endif
10628                 sb = get_super(bdev);
10629                 bdput(bdev);
10630                 if (!sb)
10631                         return -ENODEV;
10632         }
10633 -
10634 -       ret = check_quotactl_valid(sb, type, cmds, id);
10635 +       if (sb)
10636 +               dqh = sb->s_dqh;
10637 +       ret = check_quotactl_valid(dqh, type, cmds, id);
10638         if (ret >= 0)
10639 -               ret = do_quotactl(sb, type, cmds, id, addr);
10640 +               ret = do_quotactl(dqh, type, cmds, id, addr);
10641         if (sb)
10642                 drop_super(sb);
10643  
10644 diff -NurpP --minimal linux-2.6.17.11/fs/quota_v1.c linux-2.6.17.11-vs2.1.1-rc31/fs/quota_v1.c
10645 --- linux-2.6.17.11/fs/quota_v1.c       2005-03-02 12:38:45 +0100
10646 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/quota_v1.c  2006-07-09 17:06:50 +0200
10647 @@ -42,12 +42,13 @@ static int v1_read_dqblk(struct dquot *d
10648         int type = dquot->dq_type;
10649         struct v1_disk_dqblk dqblk;
10650  
10651 -       if (!sb_dqopt(dquot->dq_sb)->files[type])
10652 +       if (!dqh_dqopt(dquot->dq_dqh)->files[type])
10653                 return -EINVAL;
10654  
10655         /* Set structure to 0s in case read fails/is after end of file */
10656         memset(&dqblk, 0, sizeof(struct v1_disk_dqblk));
10657 -       dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10658 +       dquot->dq_dqh->dqh_sb->s_op->quota_read(dquot->dq_dqh, type,
10659 +               (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10660  
10661         v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk);
10662         if (dquot->dq_dqb.dqb_bhardlimit == 0 && dquot->dq_dqb.dqb_bsoftlimit == 0 &&
10663 @@ -66,16 +67,16 @@ static int v1_commit_dqblk(struct dquot 
10664  
10665         v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb);
10666         if (dquot->dq_id == 0) {
10667 -               dqblk.dqb_btime = sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace;
10668 -               dqblk.dqb_itime = sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace;
10669 +               dqblk.dqb_btime = dqh_dqopt(dquot->dq_dqh)->info[type].dqi_bgrace;
10670 +               dqblk.dqb_itime = dqh_dqopt(dquot->dq_dqh)->info[type].dqi_igrace;
10671         }
10672         ret = 0;
10673 -       if (sb_dqopt(dquot->dq_sb)->files[type])
10674 -               ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, (char *)&dqblk,
10675 -                                       sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10676 +       if (dqh_dqopt(dquot->dq_dqh)->files[type])
10677 +               ret = dquot->dq_dqh->dqh_sb->s_op->quota_write(dquot->dq_dqh, type,
10678 +                       (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10679         if (ret != sizeof(struct v1_disk_dqblk)) {
10680                 printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
10681 -                       dquot->dq_sb->s_id);
10682 +                       dquot->dq_dqh->dqh_sb->s_id);
10683                 if (ret >= 0)
10684                         ret = -EIO;
10685                 goto out;
10686 @@ -100,9 +101,9 @@ struct v2_disk_dqheader {
10687         __le32 dqh_version;      /* File version */
10688  };
10689  
10690 -static int v1_check_quota_file(struct super_block *sb, int type)
10691 +static int v1_check_quota_file(struct dqhash *hash, int type)
10692  {
10693 -       struct inode *inode = sb_dqopt(sb)->files[type];
10694 +       struct inode *inode = dqh_dqopt(hash)->files[type];
10695         ulong blocks;
10696         size_t off; 
10697         struct v2_disk_dqheader dqhead;
10698 @@ -118,22 +119,26 @@ static int v1_check_quota_file(struct su
10699         if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % sizeof(struct v1_disk_dqblk))
10700                 return 0;
10701         /* Doublecheck whether we didn't get file with new format - with old quotactl() this could happen */
10702 -       size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10703 +       size = hash->dqh_sb->s_op->quota_read(hash, type,
10704 +               (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10705         if (size != sizeof(struct v2_disk_dqheader))
10706                 return 1;       /* Probably not new format */
10707         if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type])
10708                 return 1;       /* Definitely not new format */
10709 -       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);
10710 +       printk(KERN_INFO "VFS: %s: Refusing to turn on old quota format on given file."
10711 +               " It probably contains newer quota format.\n", hash->dqh_sb->s_id);
10712          return 0;              /* Seems like a new format file -> refuse it */
10713  }
10714  
10715 -static int v1_read_file_info(struct super_block *sb, int type)
10716 +static int v1_read_file_info(struct dqhash *hash, int type)
10717  {
10718 -       struct quota_info *dqopt = sb_dqopt(sb);
10719 +       struct quota_info *dqopt = dqh_dqopt(hash);
10720         struct v1_disk_dqblk dqblk;
10721         int ret;
10722  
10723 -       if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
10724 +       if ((ret = hash->dqh_sb->s_op->quota_read(hash, type,
10725 +               (char *)&dqblk, sizeof(struct v1_disk_dqblk),
10726 +               v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
10727                 if (ret >= 0)
10728                         ret = -EIO;
10729                 goto out;
10730 @@ -145,14 +150,14 @@ out:
10731         return ret;
10732  }
10733  
10734 -static int v1_write_file_info(struct super_block *sb, int type)
10735 +static int v1_write_file_info(struct dqhash *hash, int type)
10736  {
10737 -       struct quota_info *dqopt = sb_dqopt(sb);
10738 +       struct quota_info *dqopt = dqh_dqopt(hash);
10739         struct v1_disk_dqblk dqblk;
10740         int ret;
10741  
10742         dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY;
10743 -       if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk,
10744 +       if ((ret = hash->dqh_sb->s_op->quota_read(hash, type, (char *)&dqblk,
10745             sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
10746                 if (ret >= 0)
10747                         ret = -EIO;
10748 @@ -160,7 +165,7 @@ static int v1_write_file_info(struct sup
10749         }
10750         dqblk.dqb_itime = dqopt->info[type].dqi_igrace;
10751         dqblk.dqb_btime = dqopt->info[type].dqi_bgrace;
10752 -       ret = sb->s_op->quota_write(sb, type, (char *)&dqblk,
10753 +       ret = hash->dqh_sb->s_op->quota_write(hash, type, (char *)&dqblk,
10754               sizeof(struct v1_disk_dqblk), v1_dqoff(0));
10755         if (ret == sizeof(struct v1_disk_dqblk))
10756                 ret = 0;
10757 diff -NurpP --minimal linux-2.6.17.11/fs/quota_v2.c linux-2.6.17.11-vs2.1.1-rc31/fs/quota_v2.c
10758 --- linux-2.6.17.11/fs/quota_v2.c       2006-06-18 04:54:47 +0200
10759 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/quota_v2.c  2006-07-09 17:06:50 +0200
10760 @@ -26,14 +26,15 @@ typedef char *dqbuf_t;
10761  #define GETENTRIES(buf) ((struct v2_disk_dqblk *)(((char *)buf)+sizeof(struct v2_disk_dqdbheader)))
10762  
10763  /* Check whether given file is really vfsv0 quotafile */
10764 -static int v2_check_quota_file(struct super_block *sb, int type)
10765 +static int v2_check_quota_file(struct dqhash *hash, int type)
10766  {
10767         struct v2_disk_dqheader dqhead;
10768         ssize_t size;
10769         static const uint quota_magics[] = V2_INITQMAGICS;
10770         static const uint quota_versions[] = V2_INITQVERSIONS;
10771   
10772 -       size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10773 +       size = hash->dqh_sb->s_op->quota_read(hash, type,
10774 +               (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10775         if (size != sizeof(struct v2_disk_dqheader)) {
10776                 printk("quota_v2: failed read expected=%zd got=%zd\n",
10777                         sizeof(struct v2_disk_dqheader), size);
10778 @@ -46,17 +47,17 @@ static int v2_check_quota_file(struct su
10779  }
10780  
10781  /* Read information header from quota file */
10782 -static int v2_read_file_info(struct super_block *sb, int type)
10783 +static int v2_read_file_info(struct dqhash *hash, int type)
10784  {
10785         struct v2_disk_dqinfo dinfo;
10786 -       struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
10787 +       struct mem_dqinfo *info = dqh_dqopt(hash)->info+type;
10788         ssize_t size;
10789  
10790 -       size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
10791 -              sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
10792 +       size = hash->dqh_sb->s_op->quota_read(hash, type,
10793 +               (char *)&dinfo, sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
10794         if (size != sizeof(struct v2_disk_dqinfo)) {
10795                 printk(KERN_WARNING "Can't read info structure on device %s.\n",
10796 -                       sb->s_id);
10797 +                       hash->dqh_sb->s_id);
10798                 return -1;
10799         }
10800         info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
10801 @@ -69,10 +70,10 @@ static int v2_read_file_info(struct supe
10802  }
10803  
10804  /* Write information header to quota file */
10805 -static int v2_write_file_info(struct super_block *sb, int type)
10806 +static int v2_write_file_info(struct dqhash *hash, int type)
10807  {
10808         struct v2_disk_dqinfo dinfo;
10809 -       struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
10810 +       struct mem_dqinfo *info = dqh_dqopt(hash)->info+type;
10811         ssize_t size;
10812  
10813         spin_lock(&dq_data_lock);
10814 @@ -84,11 +85,11 @@ static int v2_write_file_info(struct sup
10815         dinfo.dqi_blocks = cpu_to_le32(info->u.v2_i.dqi_blocks);
10816         dinfo.dqi_free_blk = cpu_to_le32(info->u.v2_i.dqi_free_blk);
10817         dinfo.dqi_free_entry = cpu_to_le32(info->u.v2_i.dqi_free_entry);
10818 -       size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
10819 +       size = hash->dqh_sb->s_op->quota_write(hash, type, (char *)&dinfo,
10820                sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
10821         if (size != sizeof(struct v2_disk_dqinfo)) {
10822                 printk(KERN_WARNING "Can't write info structure on device %s.\n",
10823 -                       sb->s_id);
10824 +                       hash->dqh_sb->s_id);
10825                 return -1;
10826         }
10827         return 0;
10828 @@ -132,24 +133,24 @@ static inline void freedqbuf(dqbuf_t buf
10829         kfree(buf);
10830  }
10831  
10832 -static inline ssize_t read_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
10833 +static inline ssize_t read_blk(struct dqhash *hash, int type, uint blk, dqbuf_t buf)
10834  {
10835         memset(buf, 0, V2_DQBLKSIZE);
10836 -       return sb->s_op->quota_read(sb, type, (char *)buf,
10837 -              V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10838 +       return hash->dqh_sb->s_op->quota_read(hash, type,
10839 +               (char *)buf, V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10840  }
10841  
10842 -static inline ssize_t write_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
10843 +static inline ssize_t write_blk(struct dqhash *hash, int type, uint blk, dqbuf_t buf)
10844  {
10845 -       return sb->s_op->quota_write(sb, type, (char *)buf,
10846 -              V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10847 +       return hash->dqh_sb->s_op->quota_write(hash, type,
10848 +               (char *)buf, V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10849  }
10850  
10851  /* Remove empty block from list and return it */
10852 -static int get_free_dqblk(struct super_block *sb, int type)
10853 +static int get_free_dqblk(struct dqhash *hash, int type)
10854  {
10855         dqbuf_t buf = getdqbuf();
10856 -       struct mem_dqinfo *info = sb_dqinfo(sb, type);
10857 +       struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10858         struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10859         int ret, blk;
10860  
10861 @@ -157,18 +158,18 @@ static int get_free_dqblk(struct super_b
10862                 return -ENOMEM;
10863         if (info->u.v2_i.dqi_free_blk) {
10864                 blk = info->u.v2_i.dqi_free_blk;
10865 -               if ((ret = read_blk(sb, type, blk, buf)) < 0)
10866 +               if ((ret = read_blk(hash, type, blk, buf)) < 0)
10867                         goto out_buf;
10868                 info->u.v2_i.dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
10869         }
10870         else {
10871                 memset(buf, 0, V2_DQBLKSIZE);
10872                 /* Assure block allocation... */
10873 -               if ((ret = write_blk(sb, type, info->u.v2_i.dqi_blocks, buf)) < 0)
10874 +               if ((ret = write_blk(hash, type, info->u.v2_i.dqi_blocks, buf)) < 0)
10875                         goto out_buf;
10876                 blk = info->u.v2_i.dqi_blocks++;
10877         }
10878 -       mark_info_dirty(sb, type);
10879 +       mark_info_dirty(hash, type);
10880         ret = blk;
10881  out_buf:
10882         freedqbuf(buf);
10883 @@ -176,9 +177,9 @@ out_buf:
10884  }
10885  
10886  /* Insert empty block to the list */
10887 -static int put_free_dqblk(struct super_block *sb, int type, dqbuf_t buf, uint blk)
10888 +static int put_free_dqblk(struct dqhash *hash, int type, dqbuf_t buf, uint blk)
10889  {
10890 -       struct mem_dqinfo *info = sb_dqinfo(sb, type);
10891 +       struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10892         struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10893         int err;
10894  
10895 @@ -186,18 +187,18 @@ static int put_free_dqblk(struct super_b
10896         dh->dqdh_prev_free = cpu_to_le32(0);
10897         dh->dqdh_entries = cpu_to_le16(0);
10898         info->u.v2_i.dqi_free_blk = blk;
10899 -       mark_info_dirty(sb, type);
10900 +       mark_info_dirty(hash, type);
10901         /* Some strange block. We had better leave it... */
10902 -       if ((err = write_blk(sb, type, blk, buf)) < 0)
10903 +       if ((err = write_blk(hash, type, blk, buf)) < 0)
10904                 return err;
10905         return 0;
10906  }
10907  
10908  /* Remove given block from the list of blocks with free entries */
10909 -static int remove_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
10910 +static int remove_free_dqentry(struct dqhash *hash, int type, dqbuf_t buf, uint blk)
10911  {
10912         dqbuf_t tmpbuf = getdqbuf();
10913 -       struct mem_dqinfo *info = sb_dqinfo(sb, type);
10914 +       struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10915         struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10916         uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = le32_to_cpu(dh->dqdh_prev_free);
10917         int err;
10918 @@ -205,27 +206,27 @@ static int remove_free_dqentry(struct su
10919         if (!tmpbuf)
10920                 return -ENOMEM;
10921         if (nextblk) {
10922 -               if ((err = read_blk(sb, type, nextblk, tmpbuf)) < 0)
10923 +               if ((err = read_blk(hash, type, nextblk, tmpbuf)) < 0)
10924                         goto out_buf;
10925                 ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = dh->dqdh_prev_free;
10926 -               if ((err = write_blk(sb, type, nextblk, tmpbuf)) < 0)
10927 +               if ((err = write_blk(hash, type, nextblk, tmpbuf)) < 0)
10928                         goto out_buf;
10929         }
10930         if (prevblk) {
10931 -               if ((err = read_blk(sb, type, prevblk, tmpbuf)) < 0)
10932 +               if ((err = read_blk(hash, type, prevblk, tmpbuf)) < 0)
10933                         goto out_buf;
10934                 ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_next_free = dh->dqdh_next_free;
10935 -               if ((err = write_blk(sb, type, prevblk, tmpbuf)) < 0)
10936 +               if ((err = write_blk(hash, type, prevblk, tmpbuf)) < 0)
10937                         goto out_buf;
10938         }
10939         else {
10940                 info->u.v2_i.dqi_free_entry = nextblk;
10941 -               mark_info_dirty(sb, type);
10942 +               mark_info_dirty(hash, type);
10943         }
10944         freedqbuf(tmpbuf);
10945         dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
10946         /* No matter whether write succeeds block is out of list */
10947 -       if (write_blk(sb, type, blk, buf) < 0)
10948 +       if (write_blk(hash, type, blk, buf) < 0)
10949                 printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk);
10950         return 0;
10951  out_buf:
10952 @@ -234,10 +235,10 @@ out_buf:
10953  }
10954  
10955  /* Insert given block to the beginning of list with free entries */
10956 -static int insert_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
10957 +static int insert_free_dqentry(struct dqhash *hash, int type, dqbuf_t buf, uint blk)
10958  {
10959         dqbuf_t tmpbuf = getdqbuf();
10960 -       struct mem_dqinfo *info = sb_dqinfo(sb, type);
10961 +       struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10962         struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10963         int err;
10964  
10965 @@ -245,18 +246,18 @@ static int insert_free_dqentry(struct su
10966                 return -ENOMEM;
10967         dh->dqdh_next_free = cpu_to_le32(info->u.v2_i.dqi_free_entry);
10968         dh->dqdh_prev_free = cpu_to_le32(0);
10969 -       if ((err = write_blk(sb, type, blk, buf)) < 0)
10970 +       if ((err = write_blk(hash, type, blk, buf)) < 0)
10971                 goto out_buf;
10972         if (info->u.v2_i.dqi_free_entry) {
10973 -               if ((err = read_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10974 +               if ((err = read_blk(hash, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10975                         goto out_buf;
10976                 ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = cpu_to_le32(blk);
10977 -               if ((err = write_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10978 +               if ((err = write_blk(hash, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10979                         goto out_buf;
10980         }
10981         freedqbuf(tmpbuf);
10982         info->u.v2_i.dqi_free_entry = blk;
10983 -       mark_info_dirty(sb, type);
10984 +       mark_info_dirty(hash, type);
10985         return 0;
10986  out_buf:
10987         freedqbuf(tmpbuf);
10988 @@ -266,8 +267,9 @@ out_buf:
10989  /* Find space for dquot */
10990  static uint find_free_dqentry(struct dquot *dquot, int *err)
10991  {
10992 -       struct super_block *sb = dquot->dq_sb;
10993 -       struct mem_dqinfo *info = sb_dqopt(sb)->info+dquot->dq_type;
10994 +       // struct super_block *sb = dquot->dq_sb;
10995 +       struct dqhash *dqh = dquot->dq_dqh;
10996 +       struct mem_dqinfo *info = dqh_dqopt(dqh)->info+dquot->dq_type;
10997         uint blk, i;
10998         struct v2_disk_dqdbheader *dh;
10999         struct v2_disk_dqblk *ddquot;
11000 @@ -283,11 +285,11 @@ static uint find_free_dqentry(struct dqu
11001         ddquot = GETENTRIES(buf);
11002         if (info->u.v2_i.dqi_free_entry) {
11003                 blk = info->u.v2_i.dqi_free_entry;
11004 -               if ((*err = read_blk(sb, dquot->dq_type, blk, buf)) < 0)
11005 +               if ((*err = read_blk(dqh, dquot->dq_type, blk, buf)) < 0)
11006                         goto out_buf;
11007         }
11008         else {
11009 -               blk = get_free_dqblk(sb, dquot->dq_type);
11010 +               blk = get_free_dqblk(dqh, dquot->dq_type);
11011                 if ((int)blk < 0) {
11012                         *err = blk;
11013                         freedqbuf(buf);
11014 @@ -296,10 +298,10 @@ static uint find_free_dqentry(struct dqu
11015                 memset(buf, 0, V2_DQBLKSIZE);
11016                 /* This is enough as block is already zeroed and entry list is empty... */
11017                 info->u.v2_i.dqi_free_entry = blk;
11018 -               mark_info_dirty(sb, dquot->dq_type);
11019 +               mark_info_dirty(dqh, dquot->dq_type);
11020         }
11021         if (le16_to_cpu(dh->dqdh_entries)+1 >= V2_DQSTRINBLK)   /* Block will be full? */
11022 -               if ((*err = remove_free_dqentry(sb, dquot->dq_type, buf, blk)) < 0) {
11023 +               if ((*err = remove_free_dqentry(dqh, dquot->dq_type, buf, blk)) < 0) {
11024                         printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk);
11025                         goto out_buf;
11026                 }
11027 @@ -314,7 +316,7 @@ static uint find_free_dqentry(struct dqu
11028                 goto out_buf;
11029         }
11030  #endif
11031 -       if ((*err = write_blk(sb, dquot->dq_type, blk, buf)) < 0) {
11032 +       if ((*err = write_blk(dqh, dquot->dq_type, blk, buf)) < 0) {
11033                 printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota data block %u.\n", blk);
11034                 goto out_buf;
11035         }
11036 @@ -329,7 +331,7 @@ out_buf:
11037  /* Insert reference to structure into the trie */
11038  static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth)
11039  {
11040 -       struct super_block *sb = dquot->dq_sb;
11041 +       struct dqhash *dqh = dquot->dq_dqh;
11042         dqbuf_t buf;
11043         int ret = 0, newson = 0, newact = 0;
11044         __le32 *ref;
11045 @@ -338,7 +340,7 @@ static int do_insert_tree(struct dquot *
11046         if (!(buf = getdqbuf()))
11047                 return -ENOMEM;
11048         if (!*treeblk) {
11049 -               ret = get_free_dqblk(sb, dquot->dq_type);
11050 +               ret = get_free_dqblk(dqh, dquot->dq_type);
11051                 if (ret < 0)
11052                         goto out_buf;
11053                 *treeblk = ret;
11054 @@ -346,7 +348,7 @@ static int do_insert_tree(struct dquot *
11055                 newact = 1;
11056         }
11057         else {
11058 -               if ((ret = read_blk(sb, dquot->dq_type, *treeblk, buf)) < 0) {
11059 +               if ((ret = read_blk(dqh, dquot->dq_type, *treeblk, buf)) < 0) {
11060                         printk(KERN_ERR "VFS: Can't read tree quota block %u.\n", *treeblk);
11061                         goto out_buf;
11062                 }
11063 @@ -369,10 +371,10 @@ static int do_insert_tree(struct dquot *
11064                 ret = do_insert_tree(dquot, &newblk, depth+1);
11065         if (newson && ret >= 0) {
11066                 ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk);
11067 -               ret = write_blk(sb, dquot->dq_type, *treeblk, buf);
11068 +               ret = write_blk(dqh, dquot->dq_type, *treeblk, buf);
11069         }
11070         else if (newact && ret < 0)
11071 -               put_free_dqblk(sb, dquot->dq_type, buf, *treeblk);
11072 +               put_free_dqblk(dqh, dquot->dq_type, buf, *treeblk);
11073  out_buf:
11074         freedqbuf(buf);
11075         return ret;
11076 @@ -409,10 +411,11 @@ static int v2_write_dquot(struct dquot *
11077         if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
11078                 ddquot.dqb_itime = cpu_to_le64(1);
11079         spin_unlock(&dq_data_lock);
11080 -       ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,
11081 +       ret = dquot->dq_dqh->dqh_sb->s_op->quota_write(dquot->dq_dqh, type,
11082               (char *)&ddquot, sizeof(struct v2_disk_dqblk), dquot->dq_off);
11083         if (ret != sizeof(struct v2_disk_dqblk)) {
11084 -               printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", dquot->dq_sb->s_id);
11085 +               printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
11086 +                       dquot->dq_dqh->dqh_sb->s_id);
11087                 if (ret >= 0)
11088                         ret = -ENOSPC;
11089         }
11090 @@ -426,7 +429,8 @@ static int v2_write_dquot(struct dquot *
11091  /* Free dquot entry in data block */
11092  static int free_dqentry(struct dquot *dquot, uint blk)
11093  {
11094 -       struct super_block *sb = dquot->dq_sb;
11095 +       // struct super_block *sb = dquot->dq_sb;
11096 +       struct dqhash *dqh = dquot->dq_dqh;
11097         int type = dquot->dq_type;
11098         struct v2_disk_dqdbheader *dh;
11099         dqbuf_t buf = getdqbuf();
11100 @@ -440,15 +444,15 @@ static int free_dqentry(struct dquot *dq
11101                   (uint)(dquot->dq_off >> V2_DQBLKSIZE_BITS));
11102                 goto out_buf;
11103         }
11104 -       if ((ret = read_blk(sb, type, blk, buf)) < 0) {
11105 +       if ((ret = read_blk(dqh, type, blk, buf)) < 0) {
11106                 printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk);
11107                 goto out_buf;
11108         }
11109         dh = (struct v2_disk_dqdbheader *)buf;
11110         dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)-1);
11111         if (!le16_to_cpu(dh->dqdh_entries)) {   /* Block got free? */
11112 -               if ((ret = remove_free_dqentry(sb, type, buf, blk)) < 0 ||
11113 -                   (ret = put_free_dqblk(sb, type, buf, blk)) < 0) {
11114 +               if ((ret = remove_free_dqentry(dqh, type, buf, blk)) < 0 ||
11115 +                   (ret = put_free_dqblk(dqh, type, buf, blk)) < 0) {
11116                         printk(KERN_ERR "VFS: Can't move quota data block (%u) "
11117                           "to free list.\n", blk);
11118                         goto out_buf;
11119 @@ -459,13 +463,13 @@ static int free_dqentry(struct dquot *dq
11120                   sizeof(struct v2_disk_dqblk));
11121                 if (le16_to_cpu(dh->dqdh_entries) == V2_DQSTRINBLK-1) {
11122                         /* Insert will write block itself */
11123 -                       if ((ret = insert_free_dqentry(sb, type, buf, blk)) < 0) {
11124 +                       if ((ret = insert_free_dqentry(dqh, type, buf, blk)) < 0) {
11125                                 printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk);
11126                                 goto out_buf;
11127                         }
11128                 }
11129                 else
11130 -                       if ((ret = write_blk(sb, type, blk, buf)) < 0) {
11131 +                       if ((ret = write_blk(dqh, type, blk, buf)) < 0) {
11132                                 printk(KERN_ERR "VFS: Can't write quota data "
11133                                   "block %u\n", blk);
11134                                 goto out_buf;
11135 @@ -480,7 +484,7 @@ out_buf:
11136  /* Remove reference to dquot from tree */
11137  static int remove_tree(struct dquot *dquot, uint *blk, int depth)
11138  {
11139 -       struct super_block *sb = dquot->dq_sb;
11140 +       struct dqhash *dqh = dquot->dq_dqh;
11141         int type = dquot->dq_type;
11142         dqbuf_t buf = getdqbuf();
11143         int ret = 0;
11144 @@ -489,7 +493,7 @@ static int remove_tree(struct dquot *dqu
11145         
11146         if (!buf)
11147                 return -ENOMEM;
11148 -       if ((ret = read_blk(sb, type, *blk, buf)) < 0) {
11149 +       if ((ret = read_blk(dqh, type, *blk, buf)) < 0) {
11150                 printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk);
11151                 goto out_buf;
11152         }
11153 @@ -506,11 +510,11 @@ static int remove_tree(struct dquot *dqu
11154                 for (i = 0; i < V2_DQBLKSIZE && !buf[i]; i++);  /* Block got empty? */
11155                 /* Don't put the root block into the free block list */
11156                 if (i == V2_DQBLKSIZE && *blk != V2_DQTREEOFF) {
11157 -                       put_free_dqblk(sb, type, buf, *blk);
11158 +                       put_free_dqblk(dqh, type, buf, *blk);
11159                         *blk = 0;
11160                 }
11161                 else
11162 -                       if ((ret = write_blk(sb, type, *blk, buf)) < 0)
11163 +                       if ((ret = write_blk(dqh, type, *blk, buf)) < 0)
11164                                 printk(KERN_ERR "VFS: Can't write quota tree "
11165                                   "block %u.\n", *blk);
11166         }
11167 @@ -539,7 +543,7 @@ static loff_t find_block_dqentry(struct 
11168  
11169         if (!buf)
11170                 return -ENOMEM;
11171 -       if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
11172 +       if ((ret = read_blk(dquot->dq_dqh, dquot->dq_type, blk, buf)) < 0) {
11173                 printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
11174                 goto out_buf;
11175         }
11176 @@ -578,7 +582,7 @@ static loff_t find_tree_dqentry(struct d
11177  
11178         if (!buf)
11179                 return -ENOMEM;
11180 -       if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
11181 +       if ((ret = read_blk(dquot->dq_dqh, dquot->dq_type, blk, buf)) < 0) {
11182                 printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
11183                 goto out_buf;
11184         }
11185 @@ -610,7 +614,7 @@ static int v2_read_dquot(struct dquot *d
11186  
11187  #ifdef __QUOTA_V2_PARANOIA
11188         /* Invalidated quota? */
11189 -       if (!dquot->dq_sb || !sb_dqopt(dquot->dq_sb)->files[type]) {
11190 +       if (!dquot->dq_dqh || !dqh_dqopt(dquot->dq_dqh)->files[type]) {
11191                 printk(KERN_ERR "VFS: Quota invalidated while reading!\n");
11192                 return -EIO;
11193         }
11194 @@ -627,7 +631,7 @@ static int v2_read_dquot(struct dquot *d
11195         }
11196         else {
11197                 dquot->dq_off = offset;
11198 -               if ((ret = dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type,
11199 +               if ((ret = dquot->dq_dqh->dqh_sb->s_op->quota_read(dquot->dq_dqh, type,
11200                     (char *)&ddquot, sizeof(struct v2_disk_dqblk), offset))
11201                     != sizeof(struct v2_disk_dqblk)) {
11202                         if (ret >= 0)
11203 diff -NurpP --minimal linux-2.6.17.11/fs/read_write.c linux-2.6.17.11-vs2.1.1-rc31/fs/read_write.c
11204 --- linux-2.6.17.11/fs/read_write.c     2006-06-18 04:54:47 +0200
11205 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/read_write.c        2006-07-09 17:06:50 +0200
11206 @@ -636,12 +636,77 @@ sys_writev(unsigned long fd, const struc
11207         return ret;
11208  }
11209  
11210 +ssize_t vfs_sendfile(struct file *out_file, struct file *in_file, loff_t *ppos,
11211 +                    size_t count, loff_t max)
11212 +{
11213 +       struct inode * in_inode, * out_inode;
11214 +       loff_t pos;
11215 +       ssize_t ret;
11216 +
11217 +       /* verify in_file */
11218 +       in_inode = in_file->f_dentry->d_inode;
11219 +       if (!in_inode)
11220 +               return -EINVAL;
11221 +       if (!in_file->f_op || !in_file->f_op->sendfile)
11222 +               return -EINVAL;
11223 +
11224 +       if (!ppos)
11225 +               ppos = &in_file->f_pos;
11226 +       else
11227 +               if (!(in_file->f_mode & FMODE_PREAD))
11228 +                       return -ESPIPE;
11229 +
11230 +       ret = rw_verify_area(READ, in_file, ppos, count);
11231 +       if (ret < 0)
11232 +               return ret;
11233 +       count = ret;
11234 +
11235 +       /* verify out_file */
11236 +       out_inode = out_file->f_dentry->d_inode;
11237 +       if (!out_inode)
11238 +               return -EINVAL;
11239 +       if (!out_file->f_op || !out_file->f_op->sendpage)
11240 +               return -EINVAL;
11241 +
11242 +       ret = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
11243 +       if (ret < 0)
11244 +               return ret;
11245 +       count = ret;
11246 +
11247 +       ret = security_file_permission (out_file, MAY_WRITE);
11248 +       if (ret)
11249 +               return ret;
11250 +
11251 +       if (!max)
11252 +               max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
11253 +
11254 +       pos = *ppos;
11255 +       if (unlikely(pos < 0))
11256 +               return -EINVAL;
11257 +       if (unlikely(pos + count > max)) {
11258 +               if (pos >= max)
11259 +                       return -EOVERFLOW;
11260 +               count = max - pos;
11261 +       }
11262 +
11263 +       ret = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
11264 +
11265 +       if (ret > 0) {
11266 +               current->rchar += ret;
11267 +               current->wchar += ret;
11268 +       }
11269 +
11270 +       if (*ppos > max)
11271 +               return -EOVERFLOW;
11272 +       return ret;
11273 +}
11274 +
11275 +EXPORT_SYMBOL(vfs_sendfile);
11276 +
11277  static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
11278                            size_t count, loff_t max)
11279  {
11280         struct file * in_file, * out_file;
11281 -       struct inode * in_inode, * out_inode;
11282 -       loff_t pos;
11283         ssize_t retval;
11284         int fput_needed_in, fput_needed_out;
11285  
11286 @@ -654,22 +719,6 @@ static ssize_t do_sendfile(int out_fd, i
11287                 goto out;
11288         if (!(in_file->f_mode & FMODE_READ))
11289                 goto fput_in;
11290 -       retval = -EINVAL;
11291 -       in_inode = in_file->f_dentry->d_inode;
11292 -       if (!in_inode)
11293 -               goto fput_in;
11294 -       if (!in_file->f_op || !in_file->f_op->sendfile)
11295 -               goto fput_in;
11296 -       retval = -ESPIPE;
11297 -       if (!ppos)
11298 -               ppos = &in_file->f_pos;
11299 -       else
11300 -               if (!(in_file->f_mode & FMODE_PREAD))
11301 -                       goto fput_in;
11302 -       retval = rw_verify_area(READ, in_file, ppos, count);
11303 -       if (retval < 0)
11304 -               goto fput_in;
11305 -       count = retval;
11306  
11307         retval = security_file_permission (in_file, MAY_READ);
11308         if (retval)
11309 @@ -684,45 +733,12 @@ static ssize_t do_sendfile(int out_fd, i
11310                 goto fput_in;
11311         if (!(out_file->f_mode & FMODE_WRITE))
11312                 goto fput_out;
11313 -       retval = -EINVAL;
11314 -       if (!out_file->f_op || !out_file->f_op->sendpage)
11315 -               goto fput_out;
11316 -       out_inode = out_file->f_dentry->d_inode;
11317 -       retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
11318 -       if (retval < 0)
11319 -               goto fput_out;
11320 -       count = retval;
11321 -
11322 -       retval = security_file_permission (out_file, MAY_WRITE);
11323 -       if (retval)
11324 -               goto fput_out;
11325 -
11326 -       if (!max)
11327 -               max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
11328 -
11329 -       pos = *ppos;
11330 -       retval = -EINVAL;
11331 -       if (unlikely(pos < 0))
11332 -               goto fput_out;
11333 -       if (unlikely(pos + count > max)) {
11334 -               retval = -EOVERFLOW;
11335 -               if (pos >= max)
11336 -                       goto fput_out;
11337 -               count = max - pos;
11338 -       }
11339  
11340 -       retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
11341 +       retval = vfs_sendfile(out_file, in_file, ppos, count, max);
11342  
11343 -       if (retval > 0) {
11344 -               current->rchar += retval;
11345 -               current->wchar += retval;
11346 -       }
11347         current->syscr++;
11348         current->syscw++;
11349  
11350 -       if (*ppos > max)
11351 -               retval = -EOVERFLOW;
11352 -
11353  fput_out:
11354         fput_light(out_file, fput_needed_out);
11355  fput_in:
11356 diff -NurpP --minimal linux-2.6.17.11/fs/reiserfs/bitmap.c linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/bitmap.c
11357 --- linux-2.6.17.11/fs/reiserfs/bitmap.c        2005-08-29 22:25:33 +0200
11358 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/bitmap.c   2006-08-17 01:24:55 +0200
11359 @@ -13,6 +13,7 @@
11360  #include <linux/reiserfs_fs_sb.h>
11361  #include <linux/reiserfs_fs_i.h>
11362  #include <linux/quotaops.h>
11363 +#include <linux/vs_dlimit.h>
11364  
11365  #define PREALLOCATION_SIZE 9
11366  
11367 @@ -411,8 +412,10 @@ static void _reiserfs_free_block(struct 
11368         set_sb_free_blocks(rs, sb_free_blocks(rs) + 1);
11369  
11370         journal_mark_dirty(th, s, sbh);
11371 -       if (for_unformatted)
11372 +       if (for_unformatted) {
11373 +               DLIMIT_FREE_BLOCK(inode, 1);
11374                 DQUOT_FREE_BLOCK_NODIRTY(inode, 1);
11375 +       }
11376  }
11377  
11378  void reiserfs_free_block(struct reiserfs_transaction_handle *th,
11379 @@ -1021,6 +1024,7 @@ static inline int blocknrs_and_prealloc_
11380         int passno = 0;
11381         int nr_allocated = 0;
11382         int bigalloc = 0;
11383 +       int blocks;
11384  
11385         determine_prealloc_size(hint);
11386         if (!hint->formatted_node) {
11387 @@ -1030,19 +1034,30 @@ static inline int blocknrs_and_prealloc_
11388                                "reiserquota: allocating %d blocks id=%u",
11389                                amount_needed, hint->inode->i_uid);
11390  #endif
11391 -               quota_ret =
11392 -                   DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed);
11393 -               if (quota_ret)  /* Quota exceeded? */
11394 +               quota_ret = DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode,
11395 +                       amount_needed);
11396 +               if (quota_ret)
11397                         return QUOTA_EXCEEDED;
11398 +               if (DLIMIT_ALLOC_BLOCK(hint->inode, amount_needed)) {
11399 +                       DQUOT_FREE_BLOCK_NODIRTY(hint->inode,
11400 +                               amount_needed);
11401 +                       return NO_DISK_SPACE;
11402 +               }
11403 +
11404                 if (hint->preallocate && hint->prealloc_size) {
11405  #ifdef REISERQUOTA_DEBUG
11406                         reiserfs_debug(s, REISERFS_DEBUG_CODE,
11407                                        "reiserquota: allocating (prealloc) %d blocks id=%u",
11408                                        hint->prealloc_size, hint->inode->i_uid);
11409  #endif
11410 -                       quota_ret =
11411 -                           DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
11412 -                                                        hint->prealloc_size);
11413 +                       quota_ret = DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
11414 +                               hint->prealloc_size);
11415 +                       if (!quota_ret &&
11416 +                               DLIMIT_ALLOC_BLOCK(hint->inode, hint->prealloc_size)) {
11417 +                               DQUOT_FREE_BLOCK_NODIRTY(hint->inode,
11418 +                                       hint->prealloc_size);
11419 +                               quota_ret = 1;
11420 +                       }
11421                         if (quota_ret)
11422                                 hint->preallocate = hint->prealloc_size = 0;
11423                 }
11424 @@ -1093,7 +1108,10 @@ static inline int blocknrs_and_prealloc_
11425                                                nr_allocated,
11426                                                hint->inode->i_uid);
11427  #endif
11428 -                               DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated);      /* Free not allocated blocks */
11429 +                               /* Free not allocated blocks */
11430 +                               blocks = amount_needed + hint->prealloc_size - nr_allocated;
11431 +                               DLIMIT_FREE_BLOCK(hint->inode, blocks);
11432 +                               DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks);
11433                         }
11434                         while (nr_allocated--)
11435                                 reiserfs_free_block(hint->th, hint->inode,
11436 @@ -1125,10 +1143,10 @@ static inline int blocknrs_and_prealloc_
11437                                REISERFS_I(hint->inode)->i_prealloc_count,
11438                                hint->inode->i_uid);
11439  #endif
11440 -               DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed +
11441 -                                        hint->prealloc_size - nr_allocated -
11442 -                                        REISERFS_I(hint->inode)->
11443 -                                        i_prealloc_count);
11444 +               blocks = amount_needed + hint->prealloc_size - nr_allocated -
11445 +                       REISERFS_I(hint->inode)->i_prealloc_count;
11446 +               DLIMIT_FREE_BLOCK(hint->inode, blocks);
11447 +               DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks);
11448         }
11449  
11450         return CARRY_ON;
11451 diff -NurpP --minimal linux-2.6.17.11/fs/reiserfs/file.c linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/file.c
11452 --- linux-2.6.17.11/fs/reiserfs/file.c  2006-06-18 04:54:47 +0200
11453 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/file.c     2006-07-09 17:06:50 +0200
11454 @@ -1574,6 +1574,7 @@ const struct file_operations reiserfs_fi
11455         .release = reiserfs_file_release,
11456         .fsync = reiserfs_sync_file,
11457         .sendfile = generic_file_sendfile,
11458 +       .sendpage = generic_file_sendpage,
11459         .aio_read = generic_file_aio_read,
11460         .aio_write = reiserfs_aio_write,
11461         .splice_read = generic_file_splice_read,
11462 @@ -1588,4 +1589,5 @@ struct inode_operations reiserfs_file_in
11463         .listxattr = reiserfs_listxattr,
11464         .removexattr = reiserfs_removexattr,
11465         .permission = reiserfs_permission,
11466 +       .sync_flags = reiserfs_sync_flags,
11467  };
11468 diff -NurpP --minimal linux-2.6.17.11/fs/reiserfs/inode.c linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/inode.c
11469 --- linux-2.6.17.11/fs/reiserfs/inode.c 2006-06-18 04:54:47 +0200
11470 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/inode.c    2006-07-09 17:06:50 +0200
11471 @@ -17,6 +17,8 @@
11472  #include <linux/mpage.h>
11473  #include <linux/writeback.h>
11474  #include <linux/quotaops.h>
11475 +#include <linux/vs_dlimit.h>
11476 +#include <linux/vserver/tag.h>
11477  
11478  extern int reiserfs_default_io_size;   /* default io size devuned in super.c */
11479  
11480 @@ -57,6 +59,7 @@ void reiserfs_delete_inode(struct inode 
11481                  * stat data deletion */
11482                 if (!err) 
11483                         DQUOT_FREE_INODE(inode);
11484 +               DLIMIT_FREE_INODE(inode);
11485  
11486                 if (journal_end(&th, inode->i_sb, jbegin_count)) {
11487                         mutex_unlock(&inode->i_mutex);
11488 @@ -1125,6 +1128,8 @@ static void init_inode(struct inode *ino
11489         struct buffer_head *bh;
11490         struct item_head *ih;
11491         __u32 rdev;
11492 +       uid_t uid;
11493 +       gid_t gid;
11494         //int version = ITEM_VERSION_1;
11495  
11496         bh = PATH_PLAST_BUFFER(path);
11497 @@ -1148,12 +1153,13 @@ static void init_inode(struct inode *ino
11498                     (struct stat_data_v1 *)B_I_PITEM(bh, ih);
11499                 unsigned long blocks;
11500  
11501 +               uid = sd_v1_uid(sd);
11502 +               gid = sd_v1_gid(sd);
11503 +
11504                 set_inode_item_key_version(inode, KEY_FORMAT_3_5);
11505                 set_inode_sd_version(inode, STAT_DATA_V1);
11506                 inode->i_mode = sd_v1_mode(sd);
11507                 inode->i_nlink = sd_v1_nlink(sd);
11508 -               inode->i_uid = sd_v1_uid(sd);
11509 -               inode->i_gid = sd_v1_gid(sd);
11510                 inode->i_size = sd_v1_size(sd);
11511                 inode->i_atime.tv_sec = sd_v1_atime(sd);
11512                 inode->i_mtime.tv_sec = sd_v1_mtime(sd);
11513 @@ -1195,11 +1201,12 @@ static void init_inode(struct inode *ino
11514                 // (directories and symlinks)
11515                 struct stat_data *sd = (struct stat_data *)B_I_PITEM(bh, ih);
11516  
11517 +               uid    = sd_v2_uid(sd);
11518 +               gid    = sd_v2_gid(sd);
11519 +
11520                 inode->i_mode = sd_v2_mode(sd);
11521                 inode->i_nlink = sd_v2_nlink(sd);
11522 -               inode->i_uid = sd_v2_uid(sd);
11523                 inode->i_size = sd_v2_size(sd);
11524 -               inode->i_gid = sd_v2_gid(sd);
11525                 inode->i_mtime.tv_sec = sd_v2_mtime(sd);
11526                 inode->i_atime.tv_sec = sd_v2_atime(sd);
11527                 inode->i_ctime.tv_sec = sd_v2_ctime(sd);
11528 @@ -1229,6 +1236,10 @@ static void init_inode(struct inode *ino
11529                 sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode);
11530         }
11531  
11532 +       inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
11533 +       inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
11534 +       inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid, 0);
11535 +
11536         pathrelse(path);
11537         if (S_ISREG(inode->i_mode)) {
11538                 inode->i_op = &reiserfs_file_inode_operations;
11539 @@ -1251,13 +1262,15 @@ static void init_inode(struct inode *ino
11540  static void inode2sd(void *sd, struct inode *inode, loff_t size)
11541  {
11542         struct stat_data *sd_v2 = (struct stat_data *)sd;
11543 +       uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
11544 +       gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
11545         __u16 flags;
11546  
11547 +       set_sd_v2_uid(sd_v2, uid);
11548 +       set_sd_v2_gid(sd_v2, gid);
11549         set_sd_v2_mode(sd_v2, inode->i_mode);
11550         set_sd_v2_nlink(sd_v2, inode->i_nlink);
11551 -       set_sd_v2_uid(sd_v2, inode->i_uid);
11552         set_sd_v2_size(sd_v2, size);
11553 -       set_sd_v2_gid(sd_v2, inode->i_gid);
11554         set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec);
11555         set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec);
11556         set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec);
11557 @@ -1788,6 +1801,10 @@ int reiserfs_new_inode(struct reiserfs_t
11558  
11559         BUG_ON(!th->t_trans_id);
11560  
11561 +       if (DLIMIT_ALLOC_INODE(inode)) {
11562 +               err = -ENOSPC;
11563 +               goto out_bad_dlimit;
11564 +       }
11565         if (DQUOT_ALLOC_INODE(inode)) {
11566                 err = -EDQUOT;
11567                 goto out_end_trans;
11568 @@ -1973,6 +1990,9 @@ int reiserfs_new_inode(struct reiserfs_t
11569         DQUOT_FREE_INODE(inode);
11570  
11571        out_end_trans:
11572 +       DLIMIT_FREE_INODE(inode);
11573 +
11574 +      out_bad_dlimit:
11575         journal_end(th, th->t_super, th->t_blocks_allocated);
11576         /* Drop can be outside and it needs more credits so it's better to have it outside */
11577         DQUOT_DROP(inode);
11578 @@ -2700,6 +2720,14 @@ void sd_attrs_to_i_attrs(__u16 sd_attrs,
11579                         inode->i_flags |= S_IMMUTABLE;
11580                 else
11581                         inode->i_flags &= ~S_IMMUTABLE;
11582 +               if (sd_attrs & REISERFS_IUNLINK_FL)
11583 +                       inode->i_flags |= S_IUNLINK;
11584 +               else
11585 +                       inode->i_flags &= ~S_IUNLINK;
11586 +               if (sd_attrs & REISERFS_BARRIER_FL)
11587 +                       inode->i_flags |= S_BARRIER;
11588 +               else
11589 +                       inode->i_flags &= ~S_BARRIER;
11590                 if (sd_attrs & REISERFS_APPEND_FL)
11591                         inode->i_flags |= S_APPEND;
11592                 else
11593 @@ -2722,6 +2750,14 @@ void i_attrs_to_sd_attrs(struct inode *i
11594                         *sd_attrs |= REISERFS_IMMUTABLE_FL;
11595                 else
11596                         *sd_attrs &= ~REISERFS_IMMUTABLE_FL;
11597 +               if (inode->i_flags & S_IUNLINK)
11598 +                       *sd_attrs |= REISERFS_IUNLINK_FL;
11599 +               else
11600 +                       *sd_attrs &= ~REISERFS_IUNLINK_FL;
11601 +               if (inode->i_flags & S_BARRIER)
11602 +                       *sd_attrs |= REISERFS_BARRIER_FL;
11603 +               else
11604 +                       *sd_attrs &= ~REISERFS_BARRIER_FL;
11605                 if (inode->i_flags & S_SYNC)
11606                         *sd_attrs |= REISERFS_SYNC_FL;
11607                 else
11608 @@ -2901,6 +2937,22 @@ static ssize_t reiserfs_direct_IO(int rw
11609                                   reiserfs_get_blocks_direct_io, NULL);
11610  }
11611  
11612 +int reiserfs_sync_flags(struct inode *inode)
11613 +{
11614 +       u16 oldflags, newflags;
11615 +
11616 +       oldflags = REISERFS_I(inode)->i_attrs;
11617 +       newflags = oldflags;
11618 +       i_attrs_to_sd_attrs(inode, &newflags);
11619 +
11620 +       if (oldflags ^ newflags) {
11621 +               REISERFS_I(inode)->i_attrs = newflags;
11622 +               inode->i_ctime = CURRENT_TIME_SEC;
11623 +               mark_inode_dirty(inode);
11624 +       }
11625 +       return 0;
11626 +}
11627 +
11628  int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
11629  {
11630         struct inode *inode = dentry->d_inode;
11631 @@ -2945,9 +2997,11 @@ int reiserfs_setattr(struct dentry *dent
11632         }
11633  
11634         error = inode_change_ok(inode, attr);
11635 +
11636         if (!error) {
11637                 if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
11638 -                   (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
11639 +                   (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
11640 +                   (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
11641                         error = reiserfs_chown_xattrs(inode, attr);
11642  
11643                         if (!error) {
11644 @@ -2977,6 +3031,9 @@ int reiserfs_setattr(struct dentry *dent
11645                                         inode->i_uid = attr->ia_uid;
11646                                 if (attr->ia_valid & ATTR_GID)
11647                                         inode->i_gid = attr->ia_gid;
11648 +                               if ((attr->ia_valid & ATTR_TAG) &&
11649 +                                       IS_TAGGED(inode))
11650 +                                       inode->i_tag = attr->ia_tag;
11651                                 mark_inode_dirty(inode);
11652                                 error =
11653                                     journal_end(&th, inode->i_sb, jbegin_count);
11654 diff -NurpP --minimal linux-2.6.17.11/fs/reiserfs/ioctl.c linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/ioctl.c
11655 --- linux-2.6.17.11/fs/reiserfs/ioctl.c 2006-04-09 13:49:55 +0200
11656 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/ioctl.c    2006-07-09 17:06:50 +0200
11657 @@ -4,6 +4,7 @@
11658  
11659  #include <linux/capability.h>
11660  #include <linux/fs.h>
11661 +#include <linux/mount.h>
11662  #include <linux/reiserfs_fs.h>
11663  #include <linux/time.h>
11664  #include <asm/uaccess.h>
11665 @@ -23,7 +24,7 @@ static int reiserfs_unpack(struct inode 
11666  int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
11667                    unsigned long arg)
11668  {
11669 -       unsigned int flags;
11670 +       unsigned int flags, oldflags;
11671  
11672         switch (cmd) {
11673         case REISERFS_IOC_UNPACK:
11674 @@ -42,12 +43,14 @@ int reiserfs_ioctl(struct inode *inode, 
11675  
11676                 flags = REISERFS_I(inode)->i_attrs;
11677                 i_attrs_to_sd_attrs(inode, (__u16 *) & flags);
11678 +               flags &= REISERFS_FL_USER_VISIBLE;
11679                 return put_user(flags, (int __user *)arg);
11680         case REISERFS_IOC_SETFLAGS:{
11681                         if (!reiserfs_attrs(inode->i_sb))
11682                                 return -ENOTTY;
11683  
11684 -                       if (IS_RDONLY(inode))
11685 +                       if (IS_RDONLY(inode) ||
11686 +                               (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
11687                                 return -EROFS;
11688  
11689                         if ((current->fsuid != inode->i_uid)
11690 @@ -57,10 +60,12 @@ int reiserfs_ioctl(struct inode *inode, 
11691                         if (get_user(flags, (int __user *)arg))
11692                                 return -EFAULT;
11693  
11694 -                       if (((flags ^ REISERFS_I(inode)->
11695 -                             i_attrs) & (REISERFS_IMMUTABLE_FL |
11696 -                                         REISERFS_APPEND_FL))
11697 -                           && !capable(CAP_LINUX_IMMUTABLE))
11698 +                       oldflags = REISERFS_I(inode) -> i_attrs;
11699 +                       if (((oldflags & REISERFS_IMMUTABLE_FL) ||
11700 +                               ((flags ^ oldflags) &
11701 +                               (REISERFS_IMMUTABLE_FL | REISERFS_IUNLINK_FL |
11702 +                                REISERFS_APPEND_FL))) &&
11703 +                               !capable(CAP_LINUX_IMMUTABLE))
11704                                 return -EPERM;
11705  
11706                         if ((flags & REISERFS_NOTAIL_FL) &&
11707 @@ -71,6 +76,9 @@ int reiserfs_ioctl(struct inode *inode, 
11708                                 if (result)
11709                                         return result;
11710                         }
11711 +
11712 +                       flags = flags & REISERFS_FL_USER_MODIFIABLE;
11713 +                       flags |= oldflags & ~REISERFS_FL_USER_MODIFIABLE;
11714                         sd_attrs_to_i_attrs(flags, inode);
11715                         REISERFS_I(inode)->i_attrs = flags;
11716                         inode->i_ctime = CURRENT_TIME_SEC;
11717 @@ -82,7 +90,8 @@ int reiserfs_ioctl(struct inode *inode, 
11718         case REISERFS_IOC_SETVERSION:
11719                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
11720                         return -EPERM;
11721 -               if (IS_RDONLY(inode))
11722 +               if (IS_RDONLY(inode) ||
11723 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
11724                         return -EROFS;
11725                 if (get_user(inode->i_generation, (int __user *)arg))
11726                         return -EFAULT;
11727 diff -NurpP --minimal linux-2.6.17.11/fs/reiserfs/namei.c linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/namei.c
11728 --- linux-2.6.17.11/fs/reiserfs/namei.c 2006-04-09 13:49:55 +0200
11729 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/namei.c    2006-07-09 17:06:50 +0200
11730 @@ -19,6 +19,7 @@
11731  #include <linux/reiserfs_xattr.h>
11732  #include <linux/smp_lock.h>
11733  #include <linux/quotaops.h>
11734 +#include <linux/vs_tag.h>
11735  
11736  #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
11737  #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--;
11738 @@ -365,6 +366,7 @@ static struct dentry *reiserfs_lookup(st
11739                         reiserfs_write_unlock(dir->i_sb);
11740                         return ERR_PTR(-EACCES);
11741                 }
11742 +               dx_propagate_tag(nd, inode);
11743  
11744                 /* Propogate the priv_object flag so we know we're in the priv tree */
11745                 if (is_reiserfs_priv_object(dir))
11746 @@ -600,6 +602,7 @@ static int new_inode_init(struct inode *
11747         } else {
11748                 inode->i_gid = current->fsgid;
11749         }
11750 +       inode->i_tag = dx_current_fstag(inode->i_sb);
11751         DQUOT_INIT(inode);
11752         return 0;
11753  }
11754 @@ -1546,6 +1549,7 @@ struct inode_operations reiserfs_dir_ino
11755         .listxattr = reiserfs_listxattr,
11756         .removexattr = reiserfs_removexattr,
11757         .permission = reiserfs_permission,
11758 +       .sync_flags = reiserfs_sync_flags,
11759  };
11760  
11761  /*
11762 @@ -1562,6 +1566,7 @@ struct inode_operations reiserfs_symlink
11763         .listxattr = reiserfs_listxattr,
11764         .removexattr = reiserfs_removexattr,
11765         .permission = reiserfs_permission,
11766 +       .sync_flags = reiserfs_sync_flags,
11767  
11768  };
11769  
11770 @@ -1575,5 +1580,6 @@ struct inode_operations reiserfs_special
11771         .listxattr = reiserfs_listxattr,
11772         .removexattr = reiserfs_removexattr,
11773         .permission = reiserfs_permission,
11774 +       .sync_flags = reiserfs_sync_flags,
11775  
11776  };
11777 diff -NurpP --minimal linux-2.6.17.11/fs/reiserfs/stree.c linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/stree.c
11778 --- linux-2.6.17.11/fs/reiserfs/stree.c 2006-06-18 04:54:48 +0200
11779 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/stree.c    2006-07-09 17:06:50 +0200
11780 @@ -57,6 +57,7 @@
11781  #include <linux/smp_lock.h>
11782  #include <linux/buffer_head.h>
11783  #include <linux/quotaops.h>
11784 +#include <linux/vs_dlimit.h>
11785  
11786  /* Does the buffer contain a disk block which is in the tree. */
11787  inline int B_IS_IN_TREE(const struct buffer_head *p_s_bh)
11788 @@ -1298,6 +1299,7 @@ int reiserfs_delete_item(struct reiserfs
11789                        "reiserquota delete_item(): freeing %u, id=%u type=%c",
11790                        quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih));
11791  #endif
11792 +       DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes);
11793         DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
11794  
11795         /* Return deleted body length */
11796 @@ -1386,6 +1388,7 @@ void reiserfs_delete_solid_item(struct r
11797  #endif
11798                                 DQUOT_FREE_SPACE_NODIRTY(inode,
11799                                                          quota_cut_bytes);
11800 +                               DLIMIT_FREE_SPACE(inode, quota_cut_bytes);
11801                         }
11802                         break;
11803                 }
11804 @@ -1741,6 +1744,7 @@ int reiserfs_cut_from_item(struct reiser
11805                        "reiserquota cut_from_item(): freeing %u id=%u type=%c",
11806                        quota_cut_bytes, p_s_inode->i_uid, '?');
11807  #endif
11808 +       DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes);
11809         DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
11810         return n_ret_value;
11811  }
11812 @@ -1982,6 +1986,11 @@ int reiserfs_paste_into_item(struct reis
11813                 pathrelse(p_s_search_path);
11814                 return -EDQUOT;
11815         }
11816 +       if (DLIMIT_ALLOC_SPACE(inode, n_pasted_size)) {
11817 +               DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
11818 +               pathrelse(p_s_search_path);
11819 +               return -ENOSPC;
11820 +       }
11821         init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path,
11822                        n_pasted_size);
11823  #ifdef DISPLACE_NEW_PACKING_LOCALITIES
11824 @@ -2034,6 +2043,7 @@ int reiserfs_paste_into_item(struct reis
11825                        n_pasted_size, inode->i_uid,
11826                        key2type(&(p_s_key->on_disk_key)));
11827  #endif
11828 +       DLIMIT_FREE_SPACE(inode, n_pasted_size);
11829         DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
11830         return retval;
11831  }
11832 @@ -2071,6 +2081,11 @@ int reiserfs_insert_item(struct reiserfs
11833                         pathrelse(p_s_path);
11834                         return -EDQUOT;
11835                 }
11836 +               if (DLIMIT_ALLOC_SPACE(inode, quota_bytes)) {
11837 +                       DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
11838 +                       pathrelse(p_s_path);
11839 +                       return -ENOSPC;
11840 +               }
11841         }
11842         init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path,
11843                        IH_SIZE + ih_item_len(p_s_ih));
11844 @@ -2118,7 +2133,9 @@ int reiserfs_insert_item(struct reiserfs
11845                        "reiserquota insert_item(): freeing %u id=%u type=%c",
11846                        quota_bytes, inode->i_uid, head2type(p_s_ih));
11847  #endif
11848 -       if (inode)
11849 +       if (inode) {
11850 +               DLIMIT_FREE_SPACE(inode, quota_bytes);
11851                 DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
11852 +       }
11853         return retval;
11854  }
11855 diff -NurpP --minimal linux-2.6.17.11/fs/reiserfs/super.c linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/super.c
11856 --- linux-2.6.17.11/fs/reiserfs/super.c 2006-06-18 04:54:48 +0200
11857 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/super.c    2006-07-09 17:06:50 +0200
11858 @@ -138,7 +138,7 @@ static int remove_save_link_only(struct 
11859  }
11860  
11861  #ifdef CONFIG_QUOTA
11862 -static int reiserfs_quota_on_mount(struct super_block *, int);
11863 +static int reiserfs_quota_on_mount(struct dqhash *, int);
11864  #endif
11865  
11866  /* look for uncompleted unlinks and truncates and complete them */
11867 @@ -178,7 +178,7 @@ static int finish_unfinished(struct supe
11868         /* Turn on quotas so that they are updated correctly */
11869         for (i = 0; i < MAXQUOTAS; i++) {
11870                 if (REISERFS_SB(s)->s_qf_names[i]) {
11871 -                       int ret = reiserfs_quota_on_mount(s, i);
11872 +                       int ret = reiserfs_quota_on_mount(s->s_dqh, i);
11873                         if (ret < 0)
11874                                 reiserfs_warning(s,
11875                                                  "reiserfs: cannot turn on journalled quota: error %d",
11876 @@ -292,8 +292,8 @@ static int finish_unfinished(struct supe
11877  #ifdef CONFIG_QUOTA
11878         /* Turn quotas off */
11879         for (i = 0; i < MAXQUOTAS; i++) {
11880 -               if (sb_dqopt(s)->files[i])
11881 -                       vfs_quota_off_mount(s, i);
11882 +               if (dqh_dqopt(s->s_dqh)->files[i])
11883 +                       vfs_quota_off_mount(s->s_dqh, i);
11884         }
11885         if (ms_active_set)
11886                 /* Restore the flag back */
11887 @@ -579,9 +579,9 @@ static void reiserfs_clear_inode(struct 
11888  }
11889  
11890  #ifdef CONFIG_QUOTA
11891 -static ssize_t reiserfs_quota_write(struct super_block *, int, const char *,
11892 +static ssize_t reiserfs_quota_write(struct dqhash *, int, const char *,
11893                                     size_t, loff_t);
11894 -static ssize_t reiserfs_quota_read(struct super_block *, int, char *, size_t,
11895 +static ssize_t reiserfs_quota_read(struct dqhash *, int, char *, size_t,
11896                                    loff_t);
11897  #endif
11898  
11899 @@ -614,8 +614,8 @@ static int reiserfs_write_dquot(struct d
11900  static int reiserfs_acquire_dquot(struct dquot *);
11901  static int reiserfs_release_dquot(struct dquot *);
11902  static int reiserfs_mark_dquot_dirty(struct dquot *);
11903 -static int reiserfs_write_info(struct super_block *, int);
11904 -static int reiserfs_quota_on(struct super_block *, int, int, char *);
11905 +static int reiserfs_write_info(struct dqhash *, int);
11906 +static int reiserfs_quota_on(struct dqhash *, int, int, char *);
11907  
11908  static struct dquot_operations reiserfs_quota_operations = {
11909         .initialize = reiserfs_dquot_initialize,
11910 @@ -883,6 +883,14 @@ static int reiserfs_parse_options(struct
11911                 {"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},
11912                 {"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},
11913  #endif
11914 +#ifndef CONFIG_TAGGING_NONE
11915 +               {"tagxid",.setmask = 1 << REISERFS_TAGGED},
11916 +               {"tag",.setmask = 1 << REISERFS_TAGGED},
11917 +               {"notag",.clrmask = 1 << REISERFS_TAGGED},
11918 +#endif
11919 +#ifdef CONFIG_PROPAGATE
11920 +               {"tag",.arg_required = 'T',.values = NULL},
11921 +#endif
11922  #ifdef CONFIG_REISERFS_FS_POSIX_ACL
11923                 {"acl",.setmask = 1 << REISERFS_POSIXACL},
11924                 {"noacl",.clrmask = 1 << REISERFS_POSIXACL},
11925 @@ -990,7 +998,7 @@ static int reiserfs_parse_options(struct
11926                 if (c == 'u' || c == 'g') {
11927                         int qtype = c == 'u' ? USRQUOTA : GRPQUOTA;
11928  
11929 -                       if (sb_any_quota_enabled(s)) {
11930 +                       if (dqh_any_quota_enabled(s->s_dqh)) {
11931                                 reiserfs_warning(s,
11932                                                  "reiserfs_parse_options: cannot change journalled quota options when quota turned on.");
11933                                 return 0;
11934 @@ -1053,7 +1061,7 @@ static int reiserfs_parse_options(struct
11935         }
11936         /* This checking is not precise wrt the quota type but for our purposes it is sufficient */
11937         if (!(*mount_options & (1 << REISERFS_QUOTA))
11938 -           && sb_any_quota_enabled(s)) {
11939 +           && dqh_any_quota_enabled(s->s_dqh)) {
11940                 reiserfs_warning(s,
11941                                  "reiserfs_parse_options: quota options must be present when quota is turned on.");
11942                 return 0;
11943 @@ -1155,6 +1163,12 @@ static int reiserfs_remount(struct super
11944                 return -EINVAL;
11945         }
11946  
11947 +       if ((mount_options & (1 << REISERFS_TAGGED)) &&
11948 +               !(s->s_flags & MS_TAGGED)) {
11949 +               reiserfs_warning(s, "reiserfs: tagging not permitted on remount.");
11950 +               return -EINVAL;
11951 +       }
11952 +
11953         handle_attrs(s);
11954  
11955         /* Add options that are safe here */
11956 @@ -1457,7 +1471,7 @@ static int read_super_block(struct super
11957         s->s_export_op = &reiserfs_export_ops;
11958  #ifdef CONFIG_QUOTA
11959         s->s_qcop = &reiserfs_qctl_operations;
11960 -       s->dq_op = &reiserfs_quota_operations;
11961 +       s->s_qop = &reiserfs_quota_operations;
11962  #endif
11963  
11964         /* new format is limited by the 32 bit wide i_blocks field, want to
11965 @@ -1730,6 +1744,10 @@ static int reiserfs_fill_super(struct su
11966                 goto error;
11967         }
11968  
11969 +       /* map mount option tagxid */
11970 +       if (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_TAGGED))
11971 +               s->s_flags |= MS_TAGGED;
11972 +
11973         rs = SB_DISK_SUPER_BLOCK(s);
11974         /* Let's do basic sanity check to verify that underlying device is not
11975            smaller than the filesystem. If the check fails then abort and scream,
11976 @@ -2004,16 +2022,16 @@ static int reiserfs_write_dquot(struct d
11977         struct reiserfs_transaction_handle th;
11978         int ret, err;
11979  
11980 -       reiserfs_write_lock(dquot->dq_sb);
11981 +       reiserfs_write_lock(dquot->dq_dqh->dqh_sb);
11982         ret =
11983 -           journal_begin(&th, dquot->dq_sb,
11984 -                         REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
11985 +           journal_begin(&th, dquot->dq_dqh->dqh_sb,
11986 +               REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb));
11987         if (ret)
11988                 goto out;
11989         ret = dquot_commit(dquot);
11990         err =
11991 -           journal_end(&th, dquot->dq_sb,
11992 -                       REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
11993 +           journal_end(&th, dquot->dq_dqh->dqh_sb,
11994 +               REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb));
11995         if (!ret && err)
11996                 ret = err;
11997        out:
11998 @@ -2026,20 +2044,20 @@ static int reiserfs_acquire_dquot(struct
11999         struct reiserfs_transaction_handle th;
12000         int ret, err;
12001  
12002 -       reiserfs_write_lock(dquot->dq_sb);
12003 +       reiserfs_write_lock(dquot->dq_dqh->dqh_sb);
12004         ret =
12005 -           journal_begin(&th, dquot->dq_sb,
12006 -                         REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
12007 +           journal_begin(&th, dquot->dq_dqh->dqh_sb,
12008 +               REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb));
12009         if (ret)
12010                 goto out;
12011         ret = dquot_acquire(dquot);
12012         err =
12013 -           journal_end(&th, dquot->dq_sb,
12014 -                       REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
12015 +           journal_end(&th, dquot->dq_dqh->dqh_sb,
12016 +               REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb));
12017         if (!ret && err)
12018                 ret = err;
12019        out:
12020 -       reiserfs_write_unlock(dquot->dq_sb);
12021 +       reiserfs_write_unlock(dquot->dq_dqh->dqh_sb);
12022         return ret;
12023  }
12024  
12025 @@ -2048,37 +2066,38 @@ static int reiserfs_release_dquot(struct
12026         struct reiserfs_transaction_handle th;
12027         int ret, err;
12028  
12029 -       reiserfs_write_lock(dquot->dq_sb);
12030 +       reiserfs_write_lock(dquot->dq_dqh->dqh_sb);
12031         ret =
12032 -           journal_begin(&th, dquot->dq_sb,
12033 -                         REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
12034 +           journal_begin(&th, dquot->dq_dqh->dqh_sb,
12035 +               REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb));
12036         if (ret)
12037                 goto out;
12038         ret = dquot_release(dquot);
12039         err =
12040 -           journal_end(&th, dquot->dq_sb,
12041 -                       REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
12042 +           journal_end(&th, dquot->dq_dqh->dqh_sb,
12043 +               REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb));
12044         if (!ret && err)
12045                 ret = err;
12046        out:
12047 -       reiserfs_write_unlock(dquot->dq_sb);
12048 +       reiserfs_write_unlock(dquot->dq_dqh->dqh_sb);
12049         return ret;
12050  }
12051  
12052  static int reiserfs_mark_dquot_dirty(struct dquot *dquot)
12053  {
12054         /* Are we journalling quotas? */
12055 -       if (REISERFS_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
12056 -           REISERFS_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
12057 +       if (REISERFS_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[USRQUOTA] ||
12058 +           REISERFS_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[GRPQUOTA]) {
12059                 dquot_mark_dquot_dirty(dquot);
12060                 return reiserfs_write_dquot(dquot);
12061         } else
12062                 return dquot_mark_dquot_dirty(dquot);
12063  }
12064  
12065 -static int reiserfs_write_info(struct super_block *sb, int type)
12066 +static int reiserfs_write_info(struct dqhash *hash, int type)
12067  {
12068         struct reiserfs_transaction_handle th;
12069 +       struct super_block *sb = hash->dqh_sb;
12070         int ret, err;
12071  
12072         /* Data block + inode block */
12073 @@ -2086,7 +2105,7 @@ static int reiserfs_write_info(struct su
12074         ret = journal_begin(&th, sb, 2);
12075         if (ret)
12076                 goto out;
12077 -       ret = dquot_commit_info(sb, type);
12078 +       ret = dquot_commit_info(hash, type);
12079         err = journal_end(&th, sb, 2);
12080         if (!ret && err)
12081                 ret = err;
12082 @@ -2098,18 +2117,21 @@ static int reiserfs_write_info(struct su
12083  /*
12084   * Turn on quotas during mount time - we need to find the quota file and such...
12085   */
12086 -static int reiserfs_quota_on_mount(struct super_block *sb, int type)
12087 +static int reiserfs_quota_on_mount(struct dqhash *hash, int type)
12088  {
12089 -       return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type],
12090 +       struct super_block *sb = hash->dqh_sb;
12091 +
12092 +       return vfs_quota_on_mount(hash, REISERFS_SB(sb)->s_qf_names[type],
12093                                   REISERFS_SB(sb)->s_jquota_fmt, type);
12094  }
12095  
12096  /*
12097   * Standard function to be called on quota_on
12098   */
12099 -static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
12100 +static int reiserfs_quota_on(struct dqhash *hash, int type, int format_id,
12101                              char *path)
12102  {
12103 +       struct super_block *sb = hash->dqh_sb;
12104         int err;
12105         struct nameidata nd;
12106  
12107 @@ -2134,7 +2156,7 @@ static int reiserfs_quota_on(struct supe
12108         if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&
12109             !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) {
12110                 path_release(&nd);
12111 -               return vfs_quota_on(sb, type, format_id, path);
12112 +               return vfs_quota_on(hash, type, format_id, path);
12113         }
12114         /* Quotafile not of fs root? */
12115         if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
12116 @@ -2142,17 +2164,18 @@ static int reiserfs_quota_on(struct supe
12117                                  "reiserfs: Quota file not on filesystem root. "
12118                                  "Journalled quota will not work.");
12119         path_release(&nd);
12120 -       return vfs_quota_on(sb, type, format_id, path);
12121 +       return vfs_quota_on(hash, type, format_id, path);
12122  }
12123  
12124  /* Read data from quotafile - avoid pagecache and such because we cannot afford
12125   * acquiring the locks... As quota files are never truncated and quota code
12126   * itself serializes the operations (and noone else should touch the files)
12127   * we don't have to be afraid of races */
12128 -static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data,
12129 +static ssize_t reiserfs_quota_read(struct dqhash *hash, int type, char *data,
12130                                    size_t len, loff_t off)
12131  {
12132 -       struct inode *inode = sb_dqopt(sb)->files[type];
12133 +       struct inode *inode = dqh_dqopt(hash)->files[type];
12134 +       struct super_block *sb = hash->dqh_sb;
12135         unsigned long blk = off >> sb->s_blocksize_bits;
12136         int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
12137         size_t toread;
12138 @@ -2194,10 +2217,11 @@ static ssize_t reiserfs_quota_read(struc
12139  
12140  /* Write to quotafile (we know the transaction is already started and has
12141   * enough credits) */
12142 -static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
12143 +static ssize_t reiserfs_quota_write(struct dqhash *hash, int type,
12144                                     const char *data, size_t len, loff_t off)
12145  {
12146 -       struct inode *inode = sb_dqopt(sb)->files[type];
12147 +       struct inode *inode = dqh_dqopt(hash)->files[type];
12148 +       struct super_block *sb = hash->dqh_sb;
12149         unsigned long blk = off >> sb->s_blocksize_bits;
12150         int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
12151         int journal_quota = REISERFS_SB(sb)->s_qf_names[type] != NULL;
12152 diff -NurpP --minimal linux-2.6.17.11/fs/reiserfs/xattr.c linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/xattr.c
12153 --- linux-2.6.17.11/fs/reiserfs/xattr.c 2006-02-18 14:40:26 +0100
12154 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/reiserfs/xattr.c    2006-07-09 17:06:51 +0200
12155 @@ -35,6 +35,7 @@
12156  #include <linux/namei.h>
12157  #include <linux/errno.h>
12158  #include <linux/fs.h>
12159 +#include <linux/mount.h>
12160  #include <linux/file.h>
12161  #include <linux/pagemap.h>
12162  #include <linux/xattr.h>
12163 @@ -824,7 +825,7 @@ int reiserfs_delete_xattrs(struct inode 
12164         if (dir->d_inode->i_nlink <= 2) {
12165                 root = get_xa_root(inode->i_sb);
12166                 reiserfs_write_lock_xattrs(inode->i_sb);
12167 -               err = vfs_rmdir(root->d_inode, dir);
12168 +               err = vfs_rmdir(root->d_inode, dir, NULL);
12169                 reiserfs_write_unlock_xattrs(inode->i_sb);
12170                 dput(root);
12171         } else {
12172 diff -NurpP --minimal linux-2.6.17.11/fs/stat.c linux-2.6.17.11-vs2.1.1-rc31/fs/stat.c
12173 --- linux-2.6.17.11/fs/stat.c   2006-06-18 04:54:48 +0200
12174 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/stat.c      2006-07-09 17:06:57 +0200
12175 @@ -27,6 +27,7 @@ void generic_fillattr(struct inode *inod
12176         stat->nlink = inode->i_nlink;
12177         stat->uid = inode->i_uid;
12178         stat->gid = inode->i_gid;
12179 +       stat->tag = inode->i_tag;
12180         stat->rdev = inode->i_rdev;
12181         stat->atime = inode->i_atime;
12182         stat->mtime = inode->i_mtime;
12183 diff -NurpP --minimal linux-2.6.17.11/fs/super.c linux-2.6.17.11-vs2.1.1-rc31/fs/super.c
12184 --- linux-2.6.17.11/fs/super.c  2006-06-18 04:54:48 +0200
12185 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/super.c     2006-08-25 21:19:45 +0200
12186 @@ -38,6 +38,8 @@
12187  #include <linux/idr.h>
12188  #include <linux/kobject.h>
12189  #include <linux/mutex.h>
12190 +#include <linux/devpts_fs.h>
12191 +#include <linux/proc_fs.h>
12192  #include <asm/uaccess.h>
12193  
12194  
12195 @@ -77,15 +79,14 @@ static struct super_block *alloc_super(v
12196                 s->s_count = S_BIAS;
12197                 atomic_set(&s->s_active, 1);
12198                 mutex_init(&s->s_vfs_rename_mutex);
12199 -               mutex_init(&s->s_dquot.dqio_mutex);
12200 -               mutex_init(&s->s_dquot.dqonoff_mutex);
12201 -               init_rwsem(&s->s_dquot.dqptr_sem);
12202                 init_waitqueue_head(&s->s_wait_unfrozen);
12203                 s->s_maxbytes = MAX_NON_LFS;
12204 -               s->dq_op = sb_dquot_ops;
12205 +               s->s_qop = sb_dquot_ops;
12206                 s->s_qcop = sb_quotactl_ops;
12207                 s->s_op = &default_op;
12208                 s->s_time_gran = 1000000000;
12209 +               /* quick hack to make dqhash id unique, sufficient for now */
12210 +               s->s_dqh = new_dqhash(s, (unsigned long)s);
12211         }
12212  out:
12213         return s;
12214 @@ -100,6 +101,7 @@ out:
12215  static inline void destroy_super(struct super_block *s)
12216  {
12217         security_sb_free(s);
12218 +       dqhput(s->s_dqh);
12219         kfree(s);
12220  }
12221  
12222 @@ -171,7 +173,7 @@ void deactivate_super(struct super_block
12223         if (atomic_dec_and_lock(&s->s_active, &sb_lock)) {
12224                 s->s_count -= S_BIAS-1;
12225                 spin_unlock(&sb_lock);
12226 -               DQUOT_OFF(s);
12227 +               DQUOT_OFF(s->s_dqh);
12228                 down_write(&s->s_umount);
12229                 fs->kill_sb(s);
12230                 put_filesystem(fs);
12231 @@ -803,7 +805,7 @@ struct vfsmount *
12232  do_kern_mount(const char *fstype, int flags, const char *name, void *data)
12233  {
12234         struct file_system_type *type = get_fs_type(fstype);
12235 -       struct super_block *sb = ERR_PTR(-ENOMEM);
12236 +       struct super_block *sb;
12237         struct vfsmount *mnt;
12238         int error;
12239         char *secdata = NULL;
12240 @@ -811,6 +813,12 @@ do_kern_mount(const char *fstype, int fl
12241         if (!type)
12242                 return ERR_PTR(-ENODEV);
12243  
12244 +       sb = ERR_PTR(-EPERM);
12245 +       if ((type->fs_flags & FS_BINARY_MOUNTDATA) &&
12246 +               !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT))
12247 +               goto out;
12248 +
12249 +       sb = ERR_PTR(-ENOMEM);
12250         mnt = alloc_vfsmnt(name);
12251         if (!mnt)
12252                 goto out;
12253 @@ -832,6 +840,13 @@ do_kern_mount(const char *fstype, int fl
12254         sb = type->get_sb(type, flags, name, data);
12255         if (IS_ERR(sb))
12256                 goto out_free_secdata;
12257 +
12258 +       error = -EPERM;
12259 +       if (!capable(CAP_SYS_ADMIN) && !sb->s_bdev &&
12260 +               (sb->s_magic != PROC_SUPER_MAGIC) &&
12261 +               (sb->s_magic != DEVPTS_SUPER_MAGIC))
12262 +               goto out_sb;
12263 +
12264         error = security_sb_kern_mount(sb, secdata);
12265         if (error)
12266                 goto out_sb;
12267 diff -NurpP --minimal linux-2.6.17.11/fs/sysfs/mount.c linux-2.6.17.11-vs2.1.1-rc31/fs/sysfs/mount.c
12268 --- linux-2.6.17.11/fs/sysfs/mount.c    2005-08-29 22:25:33 +0200
12269 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/sysfs/mount.c       2006-07-09 17:07:08 +0200
12270 @@ -11,8 +11,6 @@
12271  
12272  #include "sysfs.h"
12273  
12274 -/* Random magic number */
12275 -#define SYSFS_MAGIC 0x62656572
12276  
12277  struct vfsmount *sysfs_mount;
12278  struct super_block * sysfs_sb = NULL;
12279 @@ -38,7 +36,7 @@ static int sysfs_fill_super(struct super
12280  
12281         sb->s_blocksize = PAGE_CACHE_SIZE;
12282         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
12283 -       sb->s_magic = SYSFS_MAGIC;
12284 +       sb->s_magic = SYSFS_SUPER_MAGIC;
12285         sb->s_op = &sysfs_ops;
12286         sb->s_time_gran = 1;
12287         sysfs_sb = sb;
12288 diff -NurpP --minimal linux-2.6.17.11/fs/udf/super.c linux-2.6.17.11-vs2.1.1-rc31/fs/udf/super.c
12289 --- linux-2.6.17.11/fs/udf/super.c      2006-08-25 00:25:37 +0200
12290 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/udf/super.c 2006-08-25 00:12:52 +0200
12291 @@ -1571,7 +1571,7 @@ static int udf_fill_super(struct super_b
12292  
12293         /* Fill in the rest of the superblock */
12294         sb->s_op = &udf_sb_ops;
12295 -       sb->dq_op = NULL;
12296 +       sb->s_qop = NULL;
12297         sb->s_dirt = 0;
12298         sb->s_magic = UDF_SUPER_MAGIC;
12299         sb->s_time_gran = 1000;
12300 diff -NurpP --minimal linux-2.6.17.11/fs/ufs/super.c linux-2.6.17.11-vs2.1.1-rc31/fs/ufs/super.c
12301 --- linux-2.6.17.11/fs/ufs/super.c      2006-06-18 04:54:49 +0200
12302 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/ufs/super.c 2006-07-09 17:07:12 +0200
12303 @@ -873,7 +873,7 @@ magic_found:
12304          * Read ufs_super_block into internal data structures
12305          */
12306         sb->s_op = &ufs_super_ops;
12307 -       sb->dq_op = NULL; /***/
12308 +       sb->s_qop = NULL; /***/
12309         sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic);
12310  
12311         uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno);
12312 @@ -1199,8 +1199,8 @@ static void destroy_inodecache(void)
12313  }
12314  
12315  #ifdef CONFIG_QUOTA
12316 -static ssize_t ufs_quota_read(struct super_block *, int, char *,size_t, loff_t);
12317 -static ssize_t ufs_quota_write(struct super_block *, int, const char *, size_t, loff_t);
12318 +static ssize_t ufs_quota_read(struct dqhash *, int, char *,size_t, loff_t);
12319 +static ssize_t ufs_quota_write(struct dqhash *, int, const char *, size_t, loff_t);
12320  #endif
12321  
12322  static struct super_operations ufs_super_ops = {
12323 @@ -1225,10 +1225,11 @@ static struct super_operations ufs_super
12324   * acquiring the locks... As quota files are never truncated and quota code
12325   * itself serializes the operations (and noone else should touch the files)
12326   * we don't have to be afraid of races */
12327 -static ssize_t ufs_quota_read(struct super_block *sb, int type, char *data,
12328 +static ssize_t ufs_quota_read(struct dqhash *hash, int type, char *data,
12329                                size_t len, loff_t off)
12330  {
12331 -       struct inode *inode = sb_dqopt(sb)->files[type];
12332 +       struct inode *inode = dqh_dqopt(hash)->files[type];
12333 +       struct super_block *sb = hash->dqh_sb;
12334         sector_t blk = off >> sb->s_blocksize_bits;
12335         int err = 0;
12336         int offset = off & (sb->s_blocksize - 1);
12337 @@ -1264,10 +1265,11 @@ static ssize_t ufs_quota_read(struct sup
12338  }
12339  
12340  /* Write to quotafile */
12341 -static ssize_t ufs_quota_write(struct super_block *sb, int type,
12342 +static ssize_t ufs_quota_write(struct dqhash *hash, int type,
12343                                 const char *data, size_t len, loff_t off)
12344  {
12345 -       struct inode *inode = sb_dqopt(sb)->files[type];
12346 +       struct inode *inode = dqh_dqopt(hash)->files[type];
12347 +       struct super_block *sb = hash->dqh_sb;
12348         sector_t blk = off >> sb->s_blocksize_bits;
12349         int err = 0;
12350         int offset = off & (sb->s_blocksize - 1);
12351 diff -NurpP --minimal linux-2.6.17.11/fs/xattr.c linux-2.6.17.11-vs2.1.1-rc31/fs/xattr.c
12352 --- linux-2.6.17.11/fs/xattr.c  2006-06-18 04:54:49 +0200
12353 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xattr.c     2006-07-09 17:07:12 +0200
12354 @@ -18,6 +18,7 @@
12355  #include <linux/module.h>
12356  #include <linux/fsnotify.h>
12357  #include <linux/audit.h>
12358 +#include <linux/mount.h>
12359  #include <asm/uaccess.h>
12360  
12361  
12362 @@ -168,7 +169,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
12363   */
12364  static long
12365  setxattr(struct dentry *d, char __user *name, void __user *value,
12366 -        size_t size, int flags)
12367 +        size_t size, int flags, struct vfsmount *mnt)
12368  {
12369         int error;
12370         void *kvalue = NULL;
12371 @@ -195,6 +196,9 @@ setxattr(struct dentry *d, char __user *
12372                 }
12373         }
12374  
12375 +       if (MNT_IS_RDONLY(mnt))
12376 +               return -EROFS;
12377 +
12378         error = vfs_setxattr(d, kname, kvalue, size, flags);
12379         kfree(kvalue);
12380         return error;
12381 @@ -210,7 +214,7 @@ sys_setxattr(char __user *path, char __u
12382         error = user_path_walk(path, &nd);
12383         if (error)
12384                 return error;
12385 -       error = setxattr(nd.dentry, name, value, size, flags);
12386 +       error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
12387         path_release(&nd);
12388         return error;
12389  }
12390 @@ -225,7 +229,7 @@ sys_lsetxattr(char __user *path, char __
12391         error = user_path_walk_link(path, &nd);
12392         if (error)
12393                 return error;
12394 -       error = setxattr(nd.dentry, name, value, size, flags);
12395 +       error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
12396         path_release(&nd);
12397         return error;
12398  }
12399 @@ -243,7 +247,7 @@ sys_fsetxattr(int fd, char __user *name,
12400                 return error;
12401         dentry = f->f_dentry;
12402         audit_inode(NULL, dentry->d_inode, 0);
12403 -       error = setxattr(dentry, name, value, size, flags);
12404 +       error = setxattr(dentry, name, value, size, flags, f->f_vfsmnt);
12405         fput(f);
12406         return error;
12407  }
12408 @@ -416,7 +420,7 @@ sys_flistxattr(int fd, char __user *list
12409   * Extended attribute REMOVE operations
12410   */
12411  static long
12412 -removexattr(struct dentry *d, char __user *name)
12413 +removexattr(struct dentry *d, char __user *name, struct vfsmount *mnt)
12414  {
12415         int error;
12416         char kname[XATTR_NAME_MAX + 1];
12417 @@ -427,6 +431,9 @@ removexattr(struct dentry *d, char __use
12418         if (error < 0)
12419                 return error;
12420  
12421 +       if (MNT_IS_RDONLY(mnt))
12422 +               return -EROFS;
12423 +
12424         return vfs_removexattr(d, kname);
12425  }
12426  
12427 @@ -439,7 +446,7 @@ sys_removexattr(char __user *path, char 
12428         error = user_path_walk(path, &nd);
12429         if (error)
12430                 return error;
12431 -       error = removexattr(nd.dentry, name);
12432 +       error = removexattr(nd.dentry, name, nd.mnt);
12433         path_release(&nd);
12434         return error;
12435  }
12436 @@ -453,7 +460,7 @@ sys_lremovexattr(char __user *path, char
12437         error = user_path_walk_link(path, &nd);
12438         if (error)
12439                 return error;
12440 -       error = removexattr(nd.dentry, name);
12441 +       error = removexattr(nd.dentry, name, nd.mnt);
12442         path_release(&nd);
12443         return error;
12444  }
12445 @@ -470,7 +477,7 @@ sys_fremovexattr(int fd, char __user *na
12446                 return error;
12447         dentry = f->f_dentry;
12448         audit_inode(NULL, dentry->d_inode, 0);
12449 -       error = removexattr(dentry, name);
12450 +       error = removexattr(dentry, name, f->f_vfsmnt);
12451         fput(f);
12452         return error;
12453  }
12454 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/linux-2.6/xfs_file.c linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_file.c
12455 --- linux-2.6.17.11/fs/xfs/linux-2.6/xfs_file.c 2006-06-18 04:54:49 +0200
12456 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_file.c    2006-07-09 17:07:12 +0200
12457 @@ -584,6 +584,7 @@ const struct file_operations xfs_file_op
12458         .aio_read       = xfs_file_aio_read,
12459         .aio_write      = xfs_file_aio_write,
12460         .sendfile       = xfs_file_sendfile,
12461 +       .sendpage       = generic_file_sendpage,
12462         .splice_read    = xfs_file_splice_read,
12463         .splice_write   = xfs_file_splice_write,
12464         .unlocked_ioctl = xfs_file_ioctl,
12465 @@ -608,6 +609,7 @@ const struct file_operations xfs_invis_f
12466         .aio_read       = xfs_file_aio_read_invis,
12467         .aio_write      = xfs_file_aio_write_invis,
12468         .sendfile       = xfs_file_sendfile_invis,
12469 +       .sendpage       = generic_file_sendpage,
12470         .splice_read    = xfs_file_splice_read_invis,
12471         .splice_write   = xfs_file_splice_write_invis,
12472         .unlocked_ioctl = xfs_file_ioctl_invis,
12473 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_ioctl.c
12474 --- linux-2.6.17.11/fs/xfs/linux-2.6/xfs_ioctl.c        2006-06-18 04:54:49 +0200
12475 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_ioctl.c   2006-07-09 17:07:12 +0200
12476 @@ -1100,6 +1100,8 @@ xfs_ioc_fsgeometry(
12477  #define LINUX_XFLAG_APPEND     0x00000020 /* writes to file may only append */
12478  #define LINUX_XFLAG_NODUMP     0x00000040 /* do not dump file */
12479  #define LINUX_XFLAG_NOATIME    0x00000080 /* do not update atime */
12480 +#define LINUX_XFLAG_BARRIER    0x04000000 /* chroot() barrier */
12481 +#define LINUX_XFLAG_IUNLINK    0x08000000 /* immutable unlink */
12482  
12483  STATIC unsigned int
12484  xfs_merge_ioc_xflags(
12485 @@ -1140,6 +1142,10 @@ xfs_di2lxflags(
12486  
12487         if (di_flags & XFS_DIFLAG_IMMUTABLE)
12488                 flags |= LINUX_XFLAG_IMMUTABLE;
12489 +       if (di_flags & XFS_DIFLAG_IUNLINK)
12490 +               flags |= LINUX_XFLAG_IUNLINK;
12491 +       if (di_flags & XFS_DIFLAG_BARRIER)
12492 +               flags |= LINUX_XFLAG_BARRIER;
12493         if (di_flags & XFS_DIFLAG_APPEND)
12494                 flags |= LINUX_XFLAG_APPEND;
12495         if (di_flags & XFS_DIFLAG_SYNC)
12496 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_iops.c
12497 --- linux-2.6.17.11/fs/xfs/linux-2.6/xfs_iops.c 2006-06-18 04:54:49 +0200
12498 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_iops.c    2006-07-09 17:07:13 +0200
12499 @@ -55,6 +55,7 @@
12500  #include <linux/xattr.h>
12501  #include <linux/namei.h>
12502  #include <linux/security.h>
12503 +#include <linux/vserver/tag.h>
12504  
12505  /*
12506   * Get a XFS inode from a given vnode.
12507 @@ -409,6 +410,7 @@ xfs_vn_lookup(
12508                 d_add(dentry, NULL);
12509                 return NULL;
12510         }
12511 +       dx_propagate_tag(nd, vn_to_inode(cvp));
12512  
12513         return d_splice_alias(vn_to_inode(cvp), dentry);
12514  }
12515 @@ -658,6 +660,10 @@ xfs_vn_setattr(
12516         int             flags = 0;
12517         int             error;
12518  
12519 +       error = inode_change_ok(inode, attr);
12520 +       if (error)
12521 +               return error;
12522 +
12523         if (ia_valid & ATTR_UID) {
12524                 vattr.va_mask |= XFS_AT_UID;
12525                 vattr.va_uid = attr->ia_uid;
12526 @@ -666,6 +672,10 @@ xfs_vn_setattr(
12527                 vattr.va_mask |= XFS_AT_GID;
12528                 vattr.va_gid = attr->ia_gid;
12529         }
12530 +       if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode)) {
12531 +               vattr.va_mask |= XFS_AT_TAG;
12532 +               vattr.va_tag = attr->ia_tag;
12533 +       }
12534         if (ia_valid & ATTR_SIZE) {
12535                 vattr.va_mask |= XFS_AT_SIZE;
12536                 vattr.va_size = attr->ia_size;
12537 @@ -711,6 +721,41 @@ xfs_vn_truncate(
12538  }
12539  
12540  STATIC int
12541 +xfs_vn_sync_flags(struct inode *inode)
12542 +{
12543 +       unsigned int oldflags, newflags;
12544 +       vattr_t         vattr;
12545 +       int             flags = 0;
12546 +       int             error;
12547 +       vnode_t         *vp = vn_from_inode(inode);
12548 +
12549 +       memset(&vattr, 0, sizeof(vattr_t));
12550 +
12551 +       vattr.va_mask = XFS_AT_XFLAGS;
12552 +       VOP_GETATTR(vp, &vattr, 0, NULL, error);
12553 +       if (error)
12554 +               return error;
12555 +       oldflags = vattr.va_xflags;
12556 +       newflags = oldflags & ~(XFS_XFLAG_IMMUTABLE |
12557 +               XFS_XFLAG_IUNLINK | XFS_XFLAG_BARRIER);
12558 +
12559 +       if (IS_IMMUTABLE(inode))
12560 +               newflags |= XFS_XFLAG_IMMUTABLE;
12561 +       if (IS_IUNLINK(inode))
12562 +               newflags |= XFS_XFLAG_IUNLINK;
12563 +       if (IS_BARRIER(inode))
12564 +               newflags |= XFS_XFLAG_BARRIER;
12565 +
12566 +       if (oldflags ^ newflags) {
12567 +               vattr.va_xflags = newflags;
12568 +               vattr.va_mask |= XFS_AT_XFLAGS;
12569 +               VOP_SETATTR(vp, &vattr, flags, NULL, error);
12570 +       }
12571 +       vn_revalidate(vp);
12572 +       return error;
12573 +}
12574 +
12575 +STATIC int
12576  xfs_vn_setxattr(
12577         struct dentry   *dentry,
12578         const char      *name,
12579 @@ -823,6 +868,7 @@ struct inode_operations xfs_inode_operat
12580         .getxattr               = xfs_vn_getxattr,
12581         .listxattr              = xfs_vn_listxattr,
12582         .removexattr            = xfs_vn_removexattr,
12583 +       .sync_flags             = xfs_vn_sync_flags,
12584  };
12585  
12586  struct inode_operations xfs_dir_inode_operations = {
12587 @@ -842,6 +888,7 @@ struct inode_operations xfs_dir_inode_op
12588         .getxattr               = xfs_vn_getxattr,
12589         .listxattr              = xfs_vn_listxattr,
12590         .removexattr            = xfs_vn_removexattr,
12591 +       .sync_flags             = xfs_vn_sync_flags,
12592  };
12593  
12594  struct inode_operations xfs_symlink_inode_operations = {
12595 @@ -855,4 +902,5 @@ struct inode_operations xfs_symlink_inod
12596         .getxattr               = xfs_vn_getxattr,
12597         .listxattr              = xfs_vn_listxattr,
12598         .removexattr            = xfs_vn_removexattr,
12599 +       .sync_flags             = xfs_vn_sync_flags,
12600  };
12601 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/linux-2.6/xfs_linux.h linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_linux.h
12602 --- linux-2.6.17.11/fs/xfs/linux-2.6/xfs_linux.h        2006-06-18 04:54:49 +0200
12603 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_linux.h   2006-07-09 17:07:13 +0200
12604 @@ -142,6 +142,7 @@ BUFFER_FNS(PrivateStart, unwritten);
12605  #define current_pid()          (current->pid)
12606  #define current_fsuid(cred)    (current->fsuid)
12607  #define current_fsgid(cred)    (current->fsgid)
12608 +#define current_fstag(cred,vp) (dx_current_fstag(vn_to_inode(vp)->i_sb))
12609  
12610  #define NBPP           PAGE_SIZE
12611  #define DPPSHFT                (PAGE_SHIFT - 9)
12612 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/linux-2.6/xfs_super.c linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_super.c
12613 --- linux-2.6.17.11/fs/xfs/linux-2.6/xfs_super.c        2006-06-18 04:54:49 +0200
12614 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_super.c   2006-08-25 19:44:21 +0200
12615 @@ -160,6 +160,7 @@ xfs_revalidate_inode(
12616         inode->i_nlink  = ip->i_d.di_nlink;
12617         inode->i_uid    = ip->i_d.di_uid;
12618         inode->i_gid    = ip->i_d.di_gid;
12619 +       inode->i_tag    = ip->i_d.di_tag;
12620  
12621         switch (inode->i_mode & S_IFMT) {
12622         case S_IFBLK:
12623 @@ -188,6 +189,14 @@ xfs_revalidate_inode(
12624                 inode->i_flags |= S_IMMUTABLE;
12625         else
12626                 inode->i_flags &= ~S_IMMUTABLE;
12627 +       if (ip->i_d.di_flags & XFS_DIFLAG_IUNLINK)
12628 +               inode->i_flags |= S_IUNLINK;
12629 +       else
12630 +               inode->i_flags &= ~S_IUNLINK;
12631 +       if (ip->i_d.di_flags & XFS_DIFLAG_BARRIER)
12632 +               inode->i_flags |= S_BARRIER;
12633 +       else
12634 +               inode->i_flags &= ~S_BARRIER;
12635         if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
12636                 inode->i_flags |= S_APPEND;
12637         else
12638 @@ -724,6 +733,12 @@ xfs_fs_remount(
12639         int                     error;
12640  
12641         VFS_PARSEARGS(vfsp, options, args, 1, error);
12642 +       if ((args->flags2 & XFSMNT2_TAGGED) &&
12643 +               !(sb->s_flags & MS_TAGGED)) {
12644 +               printk("XFS: %s: tagging not permitted on remount.\n",
12645 +                       sb->s_id);
12646 +               error = EINVAL;
12647 +       }
12648         if (!error)
12649                 VFS_MNTUPDATE(vfsp, flags, args, error);
12650         kmem_free(args, sizeof(*args));
12651 @@ -751,9 +766,10 @@ xfs_fs_show_options(
12652  
12653  STATIC int
12654  xfs_fs_quotasync(
12655 -       struct super_block      *sb,
12656 +       struct dqhash           *hash,
12657         int                     type)
12658  {
12659 +       struct super_block      *sb = hash->dqh_sb;
12660         struct vfs              *vfsp = vfs_from_sb(sb);
12661         int                     error;
12662  
12663 @@ -763,10 +779,10 @@ xfs_fs_quotasync(
12664  
12665  STATIC int
12666  xfs_fs_getxstate(
12667 -       struct super_block      *sb,
12668 +       struct dqhash           *hash,
12669         struct fs_quota_stat    *fqs)
12670  {
12671 -       struct vfs              *vfsp = vfs_from_sb(sb);
12672 +       struct vfs              *vfsp = vfs_from_sb(hash->dqh_sb);
12673         int                     error;
12674  
12675         VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error);
12676 @@ -775,11 +791,11 @@ xfs_fs_getxstate(
12677  
12678  STATIC int
12679  xfs_fs_setxstate(
12680 -       struct super_block      *sb,
12681 +       struct dqhash           *hash,
12682         unsigned int            flags,
12683         int                     op)
12684  {
12685 -       struct vfs              *vfsp = vfs_from_sb(sb);
12686 +       struct vfs              *vfsp = vfs_from_sb(hash->dqh_sb);
12687         int                     error;
12688  
12689         VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error);
12690 @@ -788,12 +804,12 @@ xfs_fs_setxstate(
12691  
12692  STATIC int
12693  xfs_fs_getxquota(
12694 -       struct super_block      *sb,
12695 +       struct dqhash           *hash,
12696         int                     type,
12697         qid_t                   id,
12698         struct fs_disk_quota    *fdq)
12699  {
12700 -       struct vfs              *vfsp = vfs_from_sb(sb);
12701 +       struct vfs              *vfsp = vfs_from_sb(hash->dqh_sb);
12702         int                     error, getmode;
12703  
12704         getmode = (type == USRQUOTA) ? Q_XGETQUOTA :
12705 @@ -804,12 +820,12 @@ xfs_fs_getxquota(
12706  
12707  STATIC int
12708  xfs_fs_setxquota(
12709 -       struct super_block      *sb,
12710 +       struct dqhash           *hash,
12711         int                     type,
12712         qid_t                   id,
12713         struct fs_disk_quota    *fdq)
12714  {
12715 -       struct vfs              *vfsp = vfs_from_sb(sb);
12716 +       struct vfs              *vfsp = vfs_from_sb(hash->dqh_sb);
12717         int                     error, setmode;
12718  
12719         setmode = (type == USRQUOTA) ? Q_XSETQLIM :
12720 @@ -843,6 +859,9 @@ xfs_fs_fill_super(
12721         sb->s_export_op = &xfs_export_operations;
12722  #endif
12723         sb->s_qcop = &xfs_quotactl_operations;
12724 +#ifdef CONFIG_QUOTACTL
12725 +       sb->s_dqh->dqh_qcop = &xfs_quotactl_operations;
12726 +#endif
12727         sb->s_op = &xfs_super_operations;
12728  
12729         VFS_MOUNT(vfsp, args, NULL, error);
12730 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/linux-2.6/xfs_sysctl.c linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_sysctl.c
12731 --- linux-2.6.17.11/fs/xfs/linux-2.6/xfs_sysctl.c       2006-06-18 04:54:49 +0200
12732 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_sysctl.c  2006-07-09 17:07:13 +0200
12733 @@ -57,74 +57,74 @@ xfs_stats_clear_proc_handler(
12734  STATIC ctl_table xfs_table[] = {
12735         {XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown.val,
12736         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12737 -       &sysctl_intvec, NULL,
12738 +       NULL, &sysctl_intvec, NULL,
12739         &xfs_params.restrict_chown.min, &xfs_params.restrict_chown.max},
12740  
12741         {XFS_SGID_INHERIT, "irix_sgid_inherit", &xfs_params.sgid_inherit.val,
12742         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12743 -       &sysctl_intvec, NULL,
12744 +       NULL, &sysctl_intvec, NULL,
12745         &xfs_params.sgid_inherit.min, &xfs_params.sgid_inherit.max},
12746  
12747         {XFS_SYMLINK_MODE, "irix_symlink_mode", &xfs_params.symlink_mode.val,
12748         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12749 -       &sysctl_intvec, NULL,
12750 +       NULL, &sysctl_intvec, NULL,
12751         &xfs_params.symlink_mode.min, &xfs_params.symlink_mode.max},
12752  
12753         {XFS_PANIC_MASK, "panic_mask", &xfs_params.panic_mask.val,
12754         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12755 -       &sysctl_intvec, NULL,
12756 +       NULL, &sysctl_intvec, NULL,
12757         &xfs_params.panic_mask.min, &xfs_params.panic_mask.max},
12758  
12759         {XFS_ERRLEVEL, "error_level", &xfs_params.error_level.val,
12760         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12761 -       &sysctl_intvec, NULL,
12762 +       NULL, &sysctl_intvec, NULL,
12763         &xfs_params.error_level.min, &xfs_params.error_level.max},
12764  
12765         {XFS_SYNCD_TIMER, "xfssyncd_centisecs", &xfs_params.syncd_timer.val,
12766         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12767 -       &sysctl_intvec, NULL,
12768 +       NULL, &sysctl_intvec, NULL,
12769         &xfs_params.syncd_timer.min, &xfs_params.syncd_timer.max},
12770  
12771         {XFS_INHERIT_SYNC, "inherit_sync", &xfs_params.inherit_sync.val,
12772         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12773 -       &sysctl_intvec, NULL,
12774 +       NULL, &sysctl_intvec, NULL,
12775         &xfs_params.inherit_sync.min, &xfs_params.inherit_sync.max},
12776  
12777         {XFS_INHERIT_NODUMP, "inherit_nodump", &xfs_params.inherit_nodump.val,
12778         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12779 -       &sysctl_intvec, NULL,
12780 +       NULL, &sysctl_intvec, NULL,
12781         &xfs_params.inherit_nodump.min, &xfs_params.inherit_nodump.max},
12782  
12783         {XFS_INHERIT_NOATIME, "inherit_noatime", &xfs_params.inherit_noatim.val,
12784         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12785 -       &sysctl_intvec, NULL,
12786 +       NULL, &sysctl_intvec, NULL,
12787         &xfs_params.inherit_noatim.min, &xfs_params.inherit_noatim.max},
12788  
12789         {XFS_BUF_TIMER, "xfsbufd_centisecs", &xfs_params.xfs_buf_timer.val,
12790         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12791 -       &sysctl_intvec, NULL,
12792 +       NULL, &sysctl_intvec, NULL,
12793         &xfs_params.xfs_buf_timer.min, &xfs_params.xfs_buf_timer.max},
12794  
12795         {XFS_BUF_AGE, "age_buffer_centisecs", &xfs_params.xfs_buf_age.val,
12796         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12797 -       &sysctl_intvec, NULL,
12798 +       NULL, &sysctl_intvec, NULL,
12799         &xfs_params.xfs_buf_age.min, &xfs_params.xfs_buf_age.max},
12800  
12801         {XFS_INHERIT_NOSYM, "inherit_nosymlinks", &xfs_params.inherit_nosym.val,
12802         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12803 -       &sysctl_intvec, NULL,
12804 +       NULL, &sysctl_intvec, NULL,
12805         &xfs_params.inherit_nosym.min, &xfs_params.inherit_nosym.max},
12806  
12807         {XFS_ROTORSTEP, "rotorstep", &xfs_params.rotorstep.val,
12808         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12809 -       &sysctl_intvec, NULL,
12810 +       NULL, &sysctl_intvec, NULL,
12811         &xfs_params.rotorstep.min, &xfs_params.rotorstep.max},
12812  
12813         /* please keep this the last entry */
12814  #ifdef CONFIG_PROC_FS
12815         {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
12816         sizeof(int), 0644, NULL, &xfs_stats_clear_proc_handler,
12817 -       &sysctl_intvec, NULL,
12818 +       NULL, &sysctl_intvec, NULL,
12819         &xfs_params.stats_clear.min, &xfs_params.stats_clear.max},
12820  #endif /* CONFIG_PROC_FS */
12821  
12822 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/linux-2.6/xfs_vnode.c linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_vnode.c
12823 --- linux-2.6.17.11/fs/xfs/linux-2.6/xfs_vnode.c        2006-06-18 04:54:50 +0200
12824 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_vnode.c   2006-07-09 17:07:13 +0200
12825 @@ -103,6 +103,7 @@ vn_revalidate_core(
12826         inode->i_nlink      = vap->va_nlink;
12827         inode->i_uid        = vap->va_uid;
12828         inode->i_gid        = vap->va_gid;
12829 +       inode->i_tag        = vap->va_tag;
12830         inode->i_blocks     = vap->va_nblocks;
12831         inode->i_mtime      = vap->va_mtime;
12832         inode->i_ctime      = vap->va_ctime;
12833 @@ -111,6 +112,14 @@ vn_revalidate_core(
12834                 inode->i_flags |= S_IMMUTABLE;
12835         else
12836                 inode->i_flags &= ~S_IMMUTABLE;
12837 +       if (vap->va_xflags & XFS_XFLAG_IUNLINK)
12838 +               inode->i_flags |= S_IUNLINK;
12839 +       else
12840 +               inode->i_flags &= ~S_IUNLINK;
12841 +       if (vap->va_xflags & XFS_XFLAG_BARRIER)
12842 +               inode->i_flags |= S_BARRIER;
12843 +       else
12844 +               inode->i_flags &= ~S_BARRIER;
12845         if (vap->va_xflags & XFS_XFLAG_APPEND)
12846                 inode->i_flags |= S_APPEND;
12847         else
12848 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/linux-2.6/xfs_vnode.h linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_vnode.h
12849 --- linux-2.6.17.11/fs/xfs/linux-2.6/xfs_vnode.h        2006-06-18 04:54:50 +0200
12850 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/linux-2.6/xfs_vnode.h   2006-07-09 17:07:13 +0200
12851 @@ -404,6 +404,7 @@ typedef struct vattr {
12852         xfs_nlink_t     va_nlink;       /* number of references to file */
12853         uid_t           va_uid;         /* owner user id */
12854         gid_t           va_gid;         /* owner group id */
12855 +       tag_t           va_tag;         /* owner group id */
12856         xfs_ino_t       va_nodeid;      /* file id */
12857         xfs_off_t       va_size;        /* file size in bytes */
12858         u_long          va_blocksize;   /* blocksize preferred for i/o */
12859 @@ -452,13 +453,15 @@ typedef struct vattr {
12860  #define XFS_AT_PROJID          0x04000000
12861  #define XFS_AT_SIZE_NOPERM     0x08000000
12862  #define XFS_AT_GENCOUNT                0x10000000
12863 +#define XFS_AT_TAG             0x20000000
12864  
12865  #define XFS_AT_ALL     (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
12866                 XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
12867                 XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\
12868                 XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|XFS_AT_MAC|\
12869                 XFS_AT_ACL|XFS_AT_CAP|XFS_AT_INF|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|\
12870 -               XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT)
12871 +               XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT\
12872 +               XFS_AT_TAG)
12873  
12874  #define XFS_AT_STAT    (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
12875                 XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
12876 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/quota/xfs_qm_syscalls.c linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/quota/xfs_qm_syscalls.c
12877 --- linux-2.6.17.11/fs/xfs/quota/xfs_qm_syscalls.c      2006-06-18 04:54:50 +0200
12878 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/quota/xfs_qm_syscalls.c 2006-07-09 17:07:13 +0200
12879 @@ -215,7 +215,7 @@ xfs_qm_scall_quotaoff(
12880         xfs_qoff_logitem_t      *qoffstart;
12881         int                     nculprits;
12882  
12883 -       if (!force && !capable(CAP_SYS_ADMIN))
12884 +       if (!force && !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12885                 return XFS_ERROR(EPERM);
12886         /*
12887          * No file system can have quotas enabled on disk but not in core.
12888 @@ -384,7 +384,7 @@ xfs_qm_scall_trunc_qfiles(
12889         int             error;
12890         xfs_inode_t     *qip;
12891  
12892 -       if (!capable(CAP_SYS_ADMIN))
12893 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12894                 return XFS_ERROR(EPERM);
12895         error = 0;
12896         if (!XFS_SB_VERSION_HASQUOTA(&mp->m_sb) || flags == 0) {
12897 @@ -429,7 +429,7 @@ xfs_qm_scall_quotaon(
12898         uint            accflags;
12899         __int64_t       sbflags;
12900  
12901 -       if (!capable(CAP_SYS_ADMIN))
12902 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12903                 return XFS_ERROR(EPERM);
12904  
12905         flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
12906 @@ -600,7 +600,7 @@ xfs_qm_scall_setqlim(
12907         int                     error;
12908         xfs_qcnt_t              hard, soft;
12909  
12910 -       if (!capable(CAP_SYS_ADMIN))
12911 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12912                 return XFS_ERROR(EPERM);
12913  
12914         if ((newlim->d_fieldmask &
12915 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/xfs_clnt.h linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_clnt.h
12916 --- linux-2.6.17.11/fs/xfs/xfs_clnt.h   2006-06-18 04:54:50 +0200
12917 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_clnt.h      2006-07-09 17:07:13 +0200
12918 @@ -99,5 +99,7 @@ struct xfs_mount_args {
12919   */
12920  #define XFSMNT2_COMPAT_IOSIZE  0x00000001      /* don't report large preferred
12921                                                  * I/O size in stat(2) */
12922 +#define XFSMNT2_TAGGED         0x80000000      /* context tagging */
12923 +
12924  
12925  #endif /* __XFS_CLNT_H__ */
12926 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/xfs_dinode.h linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_dinode.h
12927 --- linux-2.6.17.11/fs/xfs/xfs_dinode.h 2006-04-09 13:49:55 +0200
12928 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_dinode.h    2006-07-09 17:07:13 +0200
12929 @@ -53,7 +53,8 @@ typedef struct xfs_dinode_core
12930         __uint32_t      di_gid;         /* owner's group id */
12931         __uint32_t      di_nlink;       /* number of links to file */
12932         __uint16_t      di_projid;      /* owner's project id */
12933 -       __uint8_t       di_pad[8];      /* unused, zeroed space */
12934 +       __uint16_t      di_tag;         /* context tagging */
12935 +       __uint8_t       di_pad[6];      /* unused, zeroed space */
12936         __uint16_t      di_flushiter;   /* incremented on flush */
12937         xfs_timestamp_t di_atime;       /* time last accessed */
12938         xfs_timestamp_t di_mtime;       /* time last modified */
12939 @@ -257,6 +258,9 @@ typedef enum xfs_dinode_fmt
12940  #define XFS_DIFLAG_NOSYMLINKS_BIT   10 /* disallow symlink creation */
12941  #define XFS_DIFLAG_EXTSIZE_BIT      11 /* inode extent size allocator hint */
12942  #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */
12943 +#define XFS_DIFLAG_BARRIER_BIT 13      /* chroot() barrier */
12944 +#define XFS_DIFLAG_IUNLINK_BIT 14      /* immutable unlink */
12945 +
12946  #define XFS_DIFLAG_REALTIME      (1 << XFS_DIFLAG_REALTIME_BIT)
12947  #define XFS_DIFLAG_PREALLOC      (1 << XFS_DIFLAG_PREALLOC_BIT)
12948  #define XFS_DIFLAG_NEWRTBM       (1 << XFS_DIFLAG_NEWRTBM_BIT)
12949 @@ -270,12 +274,14 @@ typedef enum xfs_dinode_fmt
12950  #define XFS_DIFLAG_NOSYMLINKS    (1 << XFS_DIFLAG_NOSYMLINKS_BIT)
12951  #define XFS_DIFLAG_EXTSIZE       (1 << XFS_DIFLAG_EXTSIZE_BIT)
12952  #define XFS_DIFLAG_EXTSZINHERIT  (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
12953 +#define XFS_DIFLAG_BARRIER      (1 << XFS_DIFLAG_BARRIER_BIT)
12954 +#define XFS_DIFLAG_IUNLINK      (1 << XFS_DIFLAG_IUNLINK_BIT)
12955  
12956  #define XFS_DIFLAG_ANY \
12957         (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
12958          XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
12959          XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
12960          XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
12961 -        XFS_DIFLAG_EXTSZINHERIT)
12962 +        XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_BARRIER | XFS_DIFLAG_IUNLINK)
12963  
12964  #endif /* __XFS_DINODE_H__ */
12965 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/xfs_fs.h linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_fs.h
12966 --- linux-2.6.17.11/fs/xfs/xfs_fs.h     2006-04-09 13:49:55 +0200
12967 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_fs.h        2006-07-09 17:07:13 +0200
12968 @@ -67,6 +67,8 @@ struct fsxattr {
12969  #define XFS_XFLAG_NOSYMLINKS   0x00000400      /* disallow symlink creation */
12970  #define XFS_XFLAG_EXTSIZE      0x00000800      /* extent size allocator hint */
12971  #define XFS_XFLAG_EXTSZINHERIT 0x00001000      /* inherit inode extent size */
12972 +#define XFS_XFLAG_BARRIER      0x00004000      /* chroot() barrier */
12973 +#define XFS_XFLAG_IUNLINK      0x00008000      /* immutable unlink */
12974  #define XFS_XFLAG_HASATTR      0x80000000      /* no DIFLAG for this   */
12975  
12976  /*
12977 @@ -295,7 +297,8 @@ typedef struct xfs_bstat {
12978         __s32           bs_extents;     /* number of extents            */
12979         __u32           bs_gen;         /* generation count             */
12980         __u16           bs_projid;      /* project id                   */
12981 -       unsigned char   bs_pad[14];     /* pad space, unused            */
12982 +       __u16           bs_tag;         /* context tagging              */
12983 +       unsigned char   bs_pad[12];     /* pad space, unused            */
12984         __u32           bs_dmevmask;    /* DMIG event mask              */
12985         __u16           bs_dmstate;     /* DMIG state info              */
12986         __u16           bs_aextents;    /* attribute number of extents  */
12987 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/xfs_inode.c linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_inode.c
12988 --- linux-2.6.17.11/fs/xfs/xfs_inode.c  2006-06-18 04:54:53 +0200
12989 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_inode.c     2006-07-09 17:07:13 +0200
12990 @@ -52,6 +52,7 @@
12991  #include "xfs_mac.h"
12992  #include "xfs_acl.h"
12993  
12994 +#include <linux/vs_tag.h>
12995  
12996  kmem_zone_t *xfs_ifork_zone;
12997  kmem_zone_t *xfs_inode_zone;
12998 @@ -732,20 +733,35 @@ xfs_xlate_dinode_core(
12999         xfs_dinode_core_t       *buf_core = (xfs_dinode_core_t *)buf;
13000         xfs_dinode_core_t       *mem_core = (xfs_dinode_core_t *)dip;
13001         xfs_arch_t              arch = ARCH_CONVERT;
13002 +       uint32_t                uid = 0, gid = 0;
13003 +       uint16_t                tag = 0;
13004  
13005         ASSERT(dir);
13006  
13007 +       if (dir < 0) {
13008 +               tag = mem_core->di_tag;
13009 +               /* FIXME: supposed to use superblock flag */
13010 +               uid = TAGINO_UID(1, mem_core->di_uid, tag);
13011 +               gid = TAGINO_GID(1, mem_core->di_gid, tag);
13012 +               tag = TAGINO_TAG(1, tag);
13013 +       }
13014 +
13015         INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch);
13016         INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch);
13017         INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch);
13018         INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch);
13019         INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch);
13020 -       INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch);
13021 -       INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch);
13022 +       INT_XLATE(buf_core->di_uid, uid, dir, arch);
13023 +       INT_XLATE(buf_core->di_gid, gid, dir, arch);
13024 +       INT_XLATE(buf_core->di_tag, tag, dir, arch);
13025         INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch);
13026         INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch);
13027  
13028         if (dir > 0) {
13029 +               /* FIXME: supposed to use superblock flag */
13030 +               mem_core->di_uid = INOTAG_UID(1, uid, gid);
13031 +               mem_core->di_gid = INOTAG_GID(1, uid, gid);
13032 +               mem_core->di_tag = INOTAG_TAG(1, uid, gid, tag);
13033                 memcpy(mem_core->di_pad, buf_core->di_pad,
13034                         sizeof(buf_core->di_pad));
13035         } else {
13036 @@ -794,6 +810,10 @@ _xfs_dic2xflags(
13037                         flags |= XFS_XFLAG_PREALLOC;
13038                 if (di_flags & XFS_DIFLAG_IMMUTABLE)
13039                         flags |= XFS_XFLAG_IMMUTABLE;
13040 +               if (di_flags & XFS_DIFLAG_IUNLINK)
13041 +                       flags |= XFS_XFLAG_IUNLINK;
13042 +               if (di_flags & XFS_DIFLAG_BARRIER)
13043 +                       flags |= XFS_XFLAG_BARRIER;
13044                 if (di_flags & XFS_DIFLAG_APPEND)
13045                         flags |= XFS_XFLAG_APPEND;
13046                 if (di_flags & XFS_DIFLAG_SYNC)
13047 @@ -1121,6 +1141,7 @@ xfs_ialloc(
13048         ASSERT(ip->i_d.di_nlink == nlink);
13049         ip->i_d.di_uid = current_fsuid(cr);
13050         ip->i_d.di_gid = current_fsgid(cr);
13051 +       ip->i_d.di_tag = current_fstag(cr, vp);
13052         ip->i_d.di_projid = prid;
13053         memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
13054  
13055 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/xfs_itable.c linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_itable.c
13056 --- linux-2.6.17.11/fs/xfs/xfs_itable.c 2006-06-18 04:54:53 +0200
13057 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_itable.c    2006-07-09 17:07:13 +0200
13058 @@ -85,6 +85,7 @@ xfs_bulkstat_one_iget(
13059         buf->bs_mode = dic->di_mode;
13060         buf->bs_uid = dic->di_uid;
13061         buf->bs_gid = dic->di_gid;
13062 +       buf->bs_tag = dic->di_tag;
13063         buf->bs_size = dic->di_size;
13064         vn_atime_to_bstime(vp, &buf->bs_atime);
13065         buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
13066 @@ -159,6 +160,7 @@ xfs_bulkstat_one_dinode(
13067         buf->bs_mode = INT_GET(dic->di_mode, ARCH_CONVERT);
13068         buf->bs_uid = INT_GET(dic->di_uid, ARCH_CONVERT);
13069         buf->bs_gid = INT_GET(dic->di_gid, ARCH_CONVERT);
13070 +       buf->bs_tag = INT_GET(dic->di_tag, ARCH_CONVERT);
13071         buf->bs_size = INT_GET(dic->di_size, ARCH_CONVERT);
13072         buf->bs_atime.tv_sec = INT_GET(dic->di_atime.t_sec, ARCH_CONVERT);
13073         buf->bs_atime.tv_nsec = INT_GET(dic->di_atime.t_nsec, ARCH_CONVERT);
13074 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/xfs_mount.h linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_mount.h
13075 --- linux-2.6.17.11/fs/xfs/xfs_mount.h  2006-06-18 04:54:53 +0200
13076 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_mount.h     2006-07-09 17:07:13 +0200
13077 @@ -445,6 +445,7 @@ typedef struct xfs_mount {
13078  #define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23)    /* don't use per-cpu superblock
13079                                                    counters */
13080  
13081 +#define XFS_MOUNT_TAGGED       (1ULL << 31)    /* context tagging */
13082  
13083  /*
13084   * Default minimum read and write sizes.
13085 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/xfs_vfsops.c linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_vfsops.c
13086 --- linux-2.6.17.11/fs/xfs/xfs_vfsops.c 2006-06-18 04:54:54 +0200
13087 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_vfsops.c    2006-07-09 17:07:13 +0200
13088 @@ -308,6 +308,8 @@ xfs_start_flags(
13089  
13090         if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE)
13091                 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
13092 +       if (ap->flags2 & XFSMNT2_TAGGED)
13093 +               mp->m_flags |= XFS_MOUNT_TAGGED;
13094  
13095         /*
13096          * no recovery flag requires a read-only mount
13097 @@ -402,6 +404,8 @@ xfs_finish_flags(
13098                         return XFS_ERROR(EINVAL);
13099         }
13100  
13101 +       if (ap->flags2 & XFSMNT2_TAGGED)
13102 +               vfs->vfs_super->s_flags |= MS_TAGGED;
13103         return 0;
13104  }
13105  
13106 @@ -1655,6 +1659,9 @@ xfs_vget(
13107                                          * in stat(). */
13108  #define MNTOPT_ATTR2   "attr2"         /* do use attr2 attribute format */
13109  #define MNTOPT_NOATTR2 "noattr2"       /* do not use attr2 attribute format */
13110 +#define MNTOPT_TAGXID  "tagxid"        /* context tagging for inodes */
13111 +#define MNTOPT_TAGGED  "tag"           /* context tagging for inodes */
13112 +#define MNTOPT_NOTAGTAG        "notag"         /* do not use context tagging */
13113  
13114  STATIC unsigned long
13115  suffix_strtoul(const char *cp, char **endp, unsigned int base)
13116 @@ -1829,6 +1836,19 @@ xfs_parseargs(
13117                         args->flags |= XFSMNT_ATTR2;
13118                 } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
13119                         args->flags &= ~XFSMNT_ATTR2;
13120 +#ifndef CONFIG_TAGGING_NONE
13121 +               } else if (!strcmp(this_char, MNTOPT_TAGGED)) {
13122 +                       args->flags2 |= XFSMNT2_TAGGED;
13123 +               } else if (!strcmp(this_char, MNTOPT_NOTAGTAG)) {
13124 +                       args->flags2 &= ~XFSMNT2_TAGGED;
13125 +               } else if (!strcmp(this_char, MNTOPT_TAGXID)) {
13126 +                       args->flags2 |= XFSMNT2_TAGGED;
13127 +#endif
13128 +#ifdef CONFIG_PROPAGATE
13129 +               } else if (!strcmp(this_char, MNTOPT_TAGGED)) {
13130 +                       /* use value */
13131 +                       args->flags2 |= XFSMNT2_TAGGED;
13132 +#endif
13133                 } else if (!strcmp(this_char, "osyncisdsync")) {
13134                         /* no-op, this is now the default */
13135  printk("XFS: osyncisdsync is now the default, option is deprecated.\n");
13136 diff -NurpP --minimal linux-2.6.17.11/fs/xfs/xfs_vnodeops.c linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_vnodeops.c
13137 --- linux-2.6.17.11/fs/xfs/xfs_vnodeops.c       2006-06-18 04:54:54 +0200
13138 +++ linux-2.6.17.11-vs2.1.1-rc31/fs/xfs/xfs_vnodeops.c  2006-07-09 17:07:13 +0200
13139 @@ -154,6 +154,7 @@ xfs_getattr(
13140         vap->va_mode = ip->i_d.di_mode;
13141         vap->va_uid = ip->i_d.di_uid;
13142         vap->va_gid = ip->i_d.di_gid;
13143 +       vap->va_tag = ip->i_d.di_tag;
13144         vap->va_projid = ip->i_d.di_projid;
13145  
13146         /*
13147 @@ -254,6 +255,7 @@ xfs_setattr(
13148         uint                    commit_flags=0;
13149         uid_t                   uid=0, iuid=0;
13150         gid_t                   gid=0, igid=0;
13151 +       tag_t                   tag=0, itag=0;
13152         int                     timeflags = 0;
13153         vnode_t                 *vp;
13154         xfs_prid_t              projid=0, iprojid=0;
13155 @@ -310,6 +312,7 @@ xfs_setattr(
13156             (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
13157                 uint    qflags = 0;
13158  
13159 +               /* FIXME: handle tagging? */
13160                 if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
13161                         uid = vap->va_uid;
13162                         qflags |= XFS_QMOPT_UQUOTA;
13163 @@ -390,6 +393,8 @@ xfs_setattr(
13164         if (mask &
13165             (XFS_AT_MODE|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_UID|
13166              XFS_AT_GID|XFS_AT_PROJID)) {
13167 +               /* FIXME: handle tagging? */
13168 +
13169                 /*
13170                  * CAP_FOWNER overrides the following restrictions:
13171                  *
13172 @@ -438,7 +443,7 @@ xfs_setattr(
13173          * and can change the group id only to a group of which he
13174          * or she is a member.
13175          */
13176 -       if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
13177 +       if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|XFS_AT_PROJID)) {
13178                 /*
13179                  * These IDs could have changed since we last looked at them.
13180                  * But, we're assured that if the ownership did change
13181 @@ -446,10 +451,12 @@ xfs_setattr(
13182                  * would have changed also.
13183                  */
13184                 iuid = ip->i_d.di_uid;
13185 -               iprojid = ip->i_d.di_projid;
13186                 igid = ip->i_d.di_gid;
13187 -               gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
13188 +               itag = ip->i_d.di_tag;
13189 +               iprojid = ip->i_d.di_projid;
13190                 uid = (mask & XFS_AT_UID) ? vap->va_uid : iuid;
13191 +               gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
13192 +               tag = (mask & XFS_AT_TAG) ? vap->va_tag : itag;
13193                 projid = (mask & XFS_AT_PROJID) ? (xfs_prid_t)vap->va_projid :
13194                          iprojid;
13195  
13196 @@ -477,6 +484,7 @@ xfs_setattr(
13197                 if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
13198                     (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
13199                     (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
13200 +                       /* FIXME: handle tagging? */
13201                         ASSERT(tp);
13202                         code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
13203                                                 capable(CAP_FOWNER) ?
13204 @@ -694,7 +702,7 @@ xfs_setattr(
13205          * and can change the group id only to a group of which he
13206          * or she is a member.
13207          */
13208 -       if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
13209 +       if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|XFS_AT_PROJID)) {
13210                 /*
13211                  * CAP_FSETID overrides the following restrictions:
13212                  *
13213 @@ -710,6 +718,12 @@ xfs_setattr(
13214                  * Change the ownerships and register quota modifications
13215                  * in the transaction.
13216                  */
13217 +               if (itag != tag) {
13218 +                       if (XFS_IS_GQUOTA_ON(mp)) {
13219 +                               /* FIXME: handle tag quota? */
13220 +                       }
13221 +                       ip->i_d.di_tag = tag;
13222 +               }
13223                 if (iuid != uid) {
13224                         if (XFS_IS_UQUOTA_ON(mp)) {
13225                                 ASSERT(mask & XFS_AT_UID);
13226 @@ -790,6 +804,10 @@ xfs_setattr(
13227                         di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
13228                         if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
13229                                 di_flags |= XFS_DIFLAG_IMMUTABLE;
13230 +                       if (vap->va_xflags & XFS_XFLAG_IUNLINK)
13231 +                               di_flags |= XFS_DIFLAG_IUNLINK;
13232 +                       if (vap->va_xflags & XFS_XFLAG_BARRIER)
13233 +                               di_flags |= XFS_DIFLAG_BARRIER;
13234                         if (vap->va_xflags & XFS_XFLAG_APPEND)
13235                                 di_flags |= XFS_DIFLAG_APPEND;
13236                         if (vap->va_xflags & XFS_XFLAG_SYNC)
13237 diff -NurpP --minimal linux-2.6.17.11/include/asm-arm/tlb.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-arm/tlb.h
13238 --- linux-2.6.17.11/include/asm-arm/tlb.h       2006-06-18 04:54:58 +0200
13239 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-arm/tlb.h  2006-07-09 17:07:13 +0200
13240 @@ -28,6 +28,7 @@
13241  #else /* !CONFIG_MMU */
13242  
13243  #include <asm/pgalloc.h>
13244 +#include <linux/vs_memory.h>
13245  
13246  /*
13247   * TLB handling.  This allows us to remove pages from the page
13248 diff -NurpP --minimal linux-2.6.17.11/include/asm-arm26/tlb.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-arm26/tlb.h
13249 --- linux-2.6.17.11/include/asm-arm26/tlb.h     2006-01-03 17:30:02 +0100
13250 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-arm26/tlb.h        2006-07-09 17:07:13 +0200
13251 @@ -3,6 +3,7 @@
13252  
13253  #include <asm/pgalloc.h>
13254  #include <asm/tlbflush.h>
13255 +#include <linux/vs_memory.h>
13256  
13257  /*
13258   * TLB handling.  This allows us to remove pages from the page
13259 diff -NurpP --minimal linux-2.6.17.11/include/asm-arm26/unistd.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-arm26/unistd.h
13260 --- linux-2.6.17.11/include/asm-arm26/unistd.h  2006-01-03 17:30:02 +0100
13261 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-arm26/unistd.h     2006-07-09 17:07:13 +0200
13262 @@ -304,6 +304,8 @@
13263  #define __NR_mq_getsetattr             (__NR_SYSCALL_BASE+279)
13264  #define __NR_waitid                    (__NR_SYSCALL_BASE+280)
13265  
13266 +#define __NR_vserver                   (__NR_SYSCALL_BASE+313)
13267 +
13268  /*
13269   * The following SWIs are ARM private. FIXME - make appropriate for arm26
13270   */
13271 diff -NurpP --minimal linux-2.6.17.11/include/asm-generic/tlb.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-generic/tlb.h
13272 --- linux-2.6.17.11/include/asm-generic/tlb.h   2006-01-03 17:30:02 +0100
13273 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-generic/tlb.h      2006-07-09 17:07:13 +0200
13274 @@ -15,6 +15,7 @@
13275  
13276  #include <linux/config.h>
13277  #include <linux/swap.h>
13278 +#include <linux/vs_memory.h>
13279  #include <asm/pgalloc.h>
13280  #include <asm/tlbflush.h>
13281  
13282 diff -NurpP --minimal linux-2.6.17.11/include/asm-i386/elf.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-i386/elf.h
13283 --- linux-2.6.17.11/include/asm-i386/elf.h      2006-01-03 17:30:04 +0100
13284 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-i386/elf.h 2006-08-17 01:24:55 +0200
13285 @@ -71,7 +71,7 @@ typedef struct user_fxsr_struct elf_fpxr
13286     the loader.  We need to make sure that it is out of the way of the program
13287     that it will "exec", and that there is sufficient room for the brk.  */
13288  
13289 -#define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
13290 +#define ELF_ET_DYN_BASE                ((TASK_UNMAPPED_BASE) * 2)
13291  
13292  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
13293     now struct_user_regs, they are different) */
13294 @@ -108,7 +108,7 @@ typedef struct user_fxsr_struct elf_fpxr
13295     For the moment, we have only optimizations for the Intel generations,
13296     but that could change... */
13297  
13298 -#define ELF_PLATFORM  (system_utsname.machine)
13299 +#define ELF_PLATFORM  (vx_new_uts(machine))
13300  
13301  #ifdef __KERNEL__
13302  #define SET_PERSONALITY(ex, ibcs2) do { } while (0)
13303 diff -NurpP --minimal linux-2.6.17.11/include/asm-ia64/tlb.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-ia64/tlb.h
13304 --- linux-2.6.17.11/include/asm-ia64/tlb.h      2006-01-03 17:30:05 +0100
13305 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-ia64/tlb.h 2006-07-09 17:07:13 +0200
13306 @@ -41,6 +41,7 @@
13307  #include <linux/mm.h>
13308  #include <linux/pagemap.h>
13309  #include <linux/swap.h>
13310 +#include <linux/vs_memory.h>
13311  
13312  #include <asm/pgalloc.h>
13313  #include <asm/processor.h>
13314 diff -NurpP --minimal linux-2.6.17.11/include/asm-powerpc/unistd.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-powerpc/unistd.h
13315 --- linux-2.6.17.11/include/asm-powerpc/unistd.h        2006-06-18 04:55:08 +0200
13316 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-powerpc/unistd.h   2006-07-09 17:07:13 +0200
13317 @@ -275,7 +275,7 @@
13318  #endif
13319  #define __NR_rtas              255
13320  #define __NR_sys_debug_setcontext 256
13321 -/* Number 257 is reserved for vserver */
13322 +#define __NR_vserver           257
13323  /* 258 currently unused */
13324  #define __NR_mbind             259
13325  #define __NR_get_mempolicy     260
13326 diff -NurpP --minimal linux-2.6.17.11/include/asm-s390/unistd.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-s390/unistd.h
13327 --- linux-2.6.17.11/include/asm-s390/unistd.h   2006-06-18 04:55:09 +0200
13328 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-s390/unistd.h      2006-07-09 17:07:13 +0200
13329 @@ -255,7 +255,7 @@
13330  #define __NR_clock_gettime     (__NR_timer_create+6)
13331  #define __NR_clock_getres      (__NR_timer_create+7)
13332  #define __NR_clock_nanosleep   (__NR_timer_create+8)
13333 -/* Number 263 is reserved for vserver */
13334 +#define __NR_vserver           263
13335  #define __NR_fadvise64_64      264
13336  #define __NR_statfs64          265
13337  #define __NR_fstatfs64         266
13338 diff -NurpP --minimal linux-2.6.17.11/include/asm-sparc/unistd.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-sparc/unistd.h
13339 --- linux-2.6.17.11/include/asm-sparc/unistd.h  2006-06-18 04:55:10 +0200
13340 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-sparc/unistd.h     2006-07-09 17:07:13 +0200
13341 @@ -283,7 +283,7 @@
13342  #define __NR_timer_getoverrun  264
13343  #define __NR_timer_delete      265
13344  #define __NR_timer_create      266
13345 -/* #define __NR_vserver                267 Reserved for VSERVER */
13346 +#define __NR_vserver           267
13347  #define __NR_io_setup          268
13348  #define __NR_io_destroy                269
13349  #define __NR_io_submit         270
13350 diff -NurpP --minimal linux-2.6.17.11/include/asm-sparc64/tlb.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-sparc64/tlb.h
13351 --- linux-2.6.17.11/include/asm-sparc64/tlb.h   2006-01-03 17:30:08 +0100
13352 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-sparc64/tlb.h      2006-07-09 17:07:13 +0200
13353 @@ -3,6 +3,7 @@
13354  
13355  #include <linux/config.h>
13356  #include <linux/swap.h>
13357 +#include <linux/vs_memory.h>
13358  #include <asm/pgalloc.h>
13359  #include <asm/tlbflush.h>
13360  #include <asm/mmu_context.h>
13361 diff -NurpP --minimal linux-2.6.17.11/include/asm-sparc64/unistd.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-sparc64/unistd.h
13362 --- linux-2.6.17.11/include/asm-sparc64/unistd.h        2006-06-18 04:55:11 +0200
13363 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-sparc64/unistd.h   2006-07-09 17:07:13 +0200
13364 @@ -285,7 +285,7 @@
13365  #define __NR_timer_getoverrun  264
13366  #define __NR_timer_delete      265
13367  #define __NR_timer_create      266
13368 -/* #define __NR_vserver                267 Reserved for VSERVER */
13369 +#define __NR_vserver           267
13370  #define __NR_io_setup          268
13371  #define __NR_io_destroy                269
13372  #define __NR_io_submit         270
13373 diff -NurpP --minimal linux-2.6.17.11/include/asm-x86_64/unistd.h linux-2.6.17.11-vs2.1.1-rc31/include/asm-x86_64/unistd.h
13374 --- linux-2.6.17.11/include/asm-x86_64/unistd.h 2006-06-18 04:55:15 +0200
13375 +++ linux-2.6.17.11-vs2.1.1-rc31/include/asm-x86_64/unistd.h    2006-07-09 17:07:13 +0200
13376 @@ -532,7 +532,7 @@ __SYSCALL(__NR_tgkill, sys_tgkill)
13377  #define __NR_utimes            235
13378  __SYSCALL(__NR_utimes, sys_utimes)
13379  #define __NR_vserver           236
13380 -__SYSCALL(__NR_vserver, sys_ni_syscall)
13381 +__SYSCALL(__NR_vserver, sys_vserver)
13382  #define __NR_mbind             237
13383  __SYSCALL(__NR_mbind, sys_mbind)
13384  #define __NR_set_mempolicy     238
13385 diff -NurpP --minimal linux-2.6.17.11/include/linux/capability.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/capability.h
13386 --- linux-2.6.17.11/include/linux/capability.h  2006-06-18 04:55:15 +0200
13387 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/capability.h     2006-07-09 17:07:13 +0200
13388 @@ -235,6 +235,7 @@ typedef __u32 kernel_cap_t;
13389     arbitrary SCSI commands */
13390  /* Allow setting encryption key on loopback filesystem */
13391  /* Allow setting zone reclaim policy */
13392 +/* Allow the selection of a security context */
13393  
13394  #define CAP_SYS_ADMIN        21
13395  
13396 @@ -288,6 +289,11 @@ typedef __u32 kernel_cap_t;
13397  
13398  #define CAP_AUDIT_CONTROL    30
13399  
13400 +/* Allow context manipulations */
13401 +/* Allow changing context info on files */
13402 +
13403 +#define CAP_CONTEXT         31
13404 +
13405  #ifdef __KERNEL__
13406  /* 
13407   * Bounding set
13408 diff -NurpP --minimal linux-2.6.17.11/include/linux/devpts_fs.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/devpts_fs.h
13409 --- linux-2.6.17.11/include/linux/devpts_fs.h   2004-08-14 12:55:59 +0200
13410 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/devpts_fs.h      2006-07-09 17:07:13 +0200
13411 @@ -30,5 +30,7 @@ static inline void devpts_pty_kill(int n
13412  
13413  #endif
13414  
13415 +#define DEVPTS_SUPER_MAGIC     0x00001cd1
13416 +
13417  
13418  #endif /* _LINUX_DEVPTS_FS_H */
13419 diff -NurpP --minimal linux-2.6.17.11/include/linux/ext2_fs.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/ext2_fs.h
13420 --- linux-2.6.17.11/include/linux/ext2_fs.h     2005-10-28 20:49:54 +0200
13421 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/ext2_fs.h        2006-07-09 17:07:13 +0200
13422 @@ -192,10 +192,17 @@ struct ext2_group_desc
13423  #define EXT2_NOTAIL_FL                 0x00008000 /* file tail should not be merged */
13424  #define EXT2_DIRSYNC_FL                        0x00010000 /* dirsync behaviour (directories only) */
13425  #define EXT2_TOPDIR_FL                 0x00020000 /* Top of directory hierarchies*/
13426 +#define EXT2_BARRIER_FL                        0x04000000 /* Barrier for chroot() */
13427 +#define EXT2_IUNLINK_FL                        0x08000000 /* Immutable unlink */
13428  #define EXT2_RESERVED_FL               0x80000000 /* reserved for ext2 lib */
13429  
13430 +#ifdef CONFIG_VSERVER_LEGACY
13431 +#define EXT2_FL_USER_VISIBLE           0x0803DFFF /* User visible flags */
13432 +#define EXT2_FL_USER_MODIFIABLE                0x080380FF /* User modifiable flags */
13433 +#else
13434  #define EXT2_FL_USER_VISIBLE           0x0003DFFF /* User visible flags */
13435  #define EXT2_FL_USER_MODIFIABLE                0x000380FF /* User modifiable flags */
13436 +#endif
13437  
13438  /*
13439   * ioctl commands
13440 @@ -240,7 +247,7 @@ struct ext2_inode {
13441                 struct {
13442                         __u8    l_i_frag;       /* Fragment number */
13443                         __u8    l_i_fsize;      /* Fragment size */
13444 -                       __u16   i_pad1;
13445 +                       __u16   l_i_tag;        /* Context Tag */
13446                         __le16  l_i_uid_high;   /* these 2 fields    */
13447                         __le16  l_i_gid_high;   /* were reserved2[0] */
13448                         __u32   l_i_reserved2;
13449 @@ -272,6 +279,7 @@ struct ext2_inode {
13450  #define i_gid_low      i_gid
13451  #define i_uid_high     osd2.linux2.l_i_uid_high
13452  #define i_gid_high     osd2.linux2.l_i_gid_high
13453 +#define i_raw_tag      osd2.linux2.l_i_tag
13454  #define i_reserved2    osd2.linux2.l_i_reserved2
13455  #endif
13456  
13457 @@ -313,8 +321,9 @@ struct ext2_inode {
13458  #define EXT2_MOUNT_XATTR_USER          0x004000  /* Extended user attributes */
13459  #define EXT2_MOUNT_POSIX_ACL           0x008000  /* POSIX Access Control Lists */
13460  #define EXT2_MOUNT_XIP                 0x010000  /* Execute in place */
13461 -#define EXT2_MOUNT_USRQUOTA            0x020000 /* user quota */
13462 -#define EXT2_MOUNT_GRPQUOTA            0x040000 /* group quota */
13463 +#define EXT2_MOUNT_USRQUOTA            0x020000  /* user quota */
13464 +#define EXT2_MOUNT_GRPQUOTA            0x040000  /* group quota */
13465 +#define EXT2_MOUNT_TAGGED              (1<<24)   /* Enable Context Tags */
13466  
13467  
13468  #define clear_opt(o, opt)              o &= ~EXT2_MOUNT_##opt
13469 diff -NurpP --minimal linux-2.6.17.11/include/linux/ext3_fs.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/ext3_fs.h
13470 --- linux-2.6.17.11/include/linux/ext3_fs.h     2006-08-25 00:25:37 +0200
13471 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/ext3_fs.h        2006-08-17 00:42:17 +0200
13472 @@ -186,10 +186,20 @@ struct ext3_group_desc
13473  #define EXT3_NOTAIL_FL                 0x00008000 /* file tail should not be merged */
13474  #define EXT3_DIRSYNC_FL                        0x00010000 /* dirsync behaviour (directories only) */
13475  #define EXT3_TOPDIR_FL                 0x00020000 /* Top of directory hierarchies*/
13476 +#define EXT3_BARRIER_FL                        0x04000000 /* Barrier for chroot() */
13477 +#define EXT3_IUNLINK_FL                        0x08000000 /* Immutable unlink */
13478  #define EXT3_RESERVED_FL               0x80000000 /* reserved for ext3 lib */
13479  
13480 +#ifdef CONFIG_VSERVER_LEGACY
13481 +#define EXT3_FL_USER_VISIBLE           0x0803DFFF /* User visible flags */
13482 +#define EXT3_FL_USER_MODIFIABLE                0x080380FF /* User modifiable flags */
13483 +#else
13484  #define EXT3_FL_USER_VISIBLE           0x0003DFFF /* User visible flags */
13485  #define EXT3_FL_USER_MODIFIABLE                0x000380FF /* User modifiable flags */
13486 +#endif
13487 +#ifdef CONFIG_VSERVER_LEGACY
13488 +#define EXT3_IOC_SETTAG                        FIOC_SETTAGJ
13489 +#endif
13490  
13491  /*
13492   * Inode dynamic state flags
13493 @@ -288,7 +298,7 @@ struct ext3_inode {
13494                 struct {
13495                         __u8    l_i_frag;       /* Fragment number */
13496                         __u8    l_i_fsize;      /* Fragment size */
13497 -                       __u16   i_pad1;
13498 +                       __u16   l_i_tag;        /* Context Tag */
13499                         __le16  l_i_uid_high;   /* these 2 fields    */
13500                         __le16  l_i_gid_high;   /* were reserved2[0] */
13501                         __u32   l_i_reserved2;
13502 @@ -322,6 +332,7 @@ struct ext3_inode {
13503  #define i_gid_low      i_gid
13504  #define i_uid_high     osd2.linux2.l_i_uid_high
13505  #define i_gid_high     osd2.linux2.l_i_gid_high
13506 +#define i_raw_tag      osd2.linux2.l_i_tag
13507  #define i_reserved2    osd2.linux2.l_i_reserved2
13508  
13509  #elif defined(__GNU__)
13510 @@ -376,6 +387,7 @@ struct ext3_inode {
13511  #define EXT3_MOUNT_QUOTA               0x80000 /* Some quota option set */
13512  #define EXT3_MOUNT_USRQUOTA            0x100000 /* "old" user quota */
13513  #define EXT3_MOUNT_GRPQUOTA            0x200000 /* "old" group quota */
13514 +#define EXT3_MOUNT_TAGGED              (1<<24) /* Enable Context Tags */
13515  
13516  /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
13517  #ifndef _LINUX_EXT2_FS_H
13518 @@ -790,6 +802,7 @@ struct buffer_head * ext3_bread (handle_
13519  int ext3_get_blocks_handle(handle_t *handle, struct inode *inode,
13520         sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
13521         int create, int extend_disksize);
13522 +extern int ext3_sync_flags(struct inode *inode);
13523  
13524  extern void ext3_read_inode (struct inode *);
13525  extern int  ext3_write_inode (struct inode *, int);
13526 diff -NurpP --minimal linux-2.6.17.11/include/linux/ext3_jbd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/ext3_jbd.h
13527 --- linux-2.6.17.11/include/linux/ext3_jbd.h    2005-08-29 22:25:41 +0200
13528 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/ext3_jbd.h       2006-07-09 17:07:13 +0200
13529 @@ -77,10 +77,10 @@
13530  #define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0)
13531  /* Amount of blocks needed for quota insert/delete - we do some block writes
13532   * but inode, sb and group updates are done only once */
13533 -#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\
13534 -               (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0)
13535 -#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\
13536 -               (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0)
13537 +#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? \
13538 +       (DQUOT_INIT_ALLOC*(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0)
13539 +#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? \
13540 +       (DQUOT_DEL_ALLOC*(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0)
13541  #else
13542  #define EXT3_QUOTA_TRANS_BLOCKS(sb) 0
13543  #define EXT3_QUOTA_INIT_BLOCKS(sb) 0
13544 diff -NurpP --minimal linux-2.6.17.11/include/linux/fs.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/fs.h
13545 --- linux-2.6.17.11/include/linux/fs.h  2006-06-18 04:55:17 +0200
13546 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/fs.h     2006-08-25 17:51:04 +0200
13547 @@ -116,6 +116,8 @@ extern int dir_notify_enable;
13548  #define MS_PRIVATE     (1<<18) /* change to private */
13549  #define MS_SLAVE       (1<<19) /* change to slave */
13550  #define MS_SHARED      (1<<20) /* change to shared */
13551 +#define MS_TAGGED      (1<<24) /* use generic inode tagging */
13552 +#define MS_TAGID       (1<<25) /* use specific tag for this mount */
13553  #define MS_ACTIVE      (1<<30)
13554  #define MS_NOUSER      (1<<31)
13555  
13556 @@ -142,6 +144,8 @@ extern int dir_notify_enable;
13557  #define S_NOCMTIME     128     /* Do not update file c/mtime */
13558  #define S_SWAPFILE     256     /* Do not truncate: swapon got its bmaps */
13559  #define S_PRIVATE      512     /* Inode is fs-internal */
13560 +#define S_BARRIER      1024    /* Barrier for chroot() */
13561 +#define S_IUNLINK      2048    /* Immutable unlink */
13562  
13563  /*
13564   * Note that nosuid etc flags are inode-specific: setting some file-system
13565 @@ -158,23 +162,30 @@ extern int dir_notify_enable;
13566   */
13567  #define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))
13568  
13569 -#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
13570 +#define IS_RDONLY(inode)       __IS_FLG(inode, MS_RDONLY)
13571  #define IS_SYNC(inode)         (__IS_FLG(inode, MS_SYNCHRONOUS) || \
13572                                         ((inode)->i_flags & S_SYNC))
13573  #define IS_DIRSYNC(inode)      (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \
13574                                         ((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
13575  #define IS_MANDLOCK(inode)     __IS_FLG(inode, MS_MANDLOCK)
13576 +#define IS_TAGGED(inode)       __IS_FLG(inode, MS_TAGGED)
13577  
13578  #define IS_NOQUOTA(inode)      ((inode)->i_flags & S_NOQUOTA)
13579  #define IS_APPEND(inode)       ((inode)->i_flags & S_APPEND)
13580  #define IS_IMMUTABLE(inode)    ((inode)->i_flags & S_IMMUTABLE)
13581 +#define IS_IUNLINK(inode)      ((inode)->i_flags & S_IUNLINK)
13582 +#define IS_IXORUNLINK(inode)   ((IS_IUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode))
13583  #define IS_POSIXACL(inode)     __IS_FLG(inode, MS_POSIXACL)
13584  
13585 +#define IS_BARRIER(inode)      (S_ISDIR((inode)->i_mode) && ((inode)->i_flags & S_BARRIER))
13586  #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
13587  #define IS_NOCMTIME(inode)     ((inode)->i_flags & S_NOCMTIME)
13588  #define IS_SWAPFILE(inode)     ((inode)->i_flags & S_SWAPFILE)
13589  #define IS_PRIVATE(inode)      ((inode)->i_flags & S_PRIVATE)
13590  
13591 +#define IS_COW(inode)          (IS_IUNLINK(inode) && IS_IMMUTABLE(inode))
13592 +#define IS_COW_LINK(inode)     (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1))
13593 +
13594  /* the read-only stuff doesn't really belong here, but any other place is
13595     probably as bad and I don't want to create yet another include file. */
13596  
13597 @@ -277,6 +288,7 @@ typedef void (dio_iodone_t)(struct kiocb
13598  #define ATTR_KILL_SUID 2048
13599  #define ATTR_KILL_SGID 4096
13600  #define ATTR_FILE      8192
13601 +#define ATTR_TAG       16384
13602  
13603  /*
13604   * This is the Inode Attributes structure, used for notify_change().  It
13605 @@ -292,6 +304,7 @@ struct iattr {
13606         umode_t         ia_mode;
13607         uid_t           ia_uid;
13608         gid_t           ia_gid;
13609 +       tag_t           ia_tag;
13610         loff_t          ia_size;
13611         struct timespec ia_atime;
13612         struct timespec ia_mtime;
13613 @@ -305,6 +318,9 @@ struct iattr {
13614         struct file     *ia_file;
13615  };
13616  
13617 +#define ATTR_FLAG_BARRIER      512     /* Barrier for chroot() */
13618 +#define ATTR_FLAG_IUNLINK      1024    /* Immutable unlink */
13619 +
13620  /*
13621   * Includes for diskquotas.
13622   */
13623 @@ -486,6 +502,7 @@ struct inode {
13624         unsigned int            i_nlink;
13625         uid_t                   i_uid;
13626         gid_t                   i_gid;
13627 +       tag_t                   i_tag;
13628         dev_t                   i_rdev;
13629         loff_t                  i_size;
13630         struct timespec         i_atime;
13631 @@ -505,6 +522,9 @@ struct inode {
13632         struct file_lock        *i_flock;
13633         struct address_space    *i_mapping;
13634         struct address_space    i_data;
13635 +#ifdef CONFIG_QUOTACTL
13636 +       struct dqhash           *i_dqh;
13637 +#endif
13638  #ifdef CONFIG_QUOTA
13639         struct dquot            *i_dquot[MAXQUOTAS];
13640  #endif
13641 @@ -648,6 +668,7 @@ struct file {
13642         struct fown_struct      f_owner;
13643         unsigned int            f_uid, f_gid;
13644         struct file_ra_state    f_ra;
13645 +       xid_t                   f_xid;
13646  
13647         unsigned long           f_version;
13648         void                    *f_security;
13649 @@ -726,6 +747,7 @@ struct file_lock {
13650         unsigned char fl_type;
13651         loff_t fl_start;
13652         loff_t fl_end;
13653 +       xid_t fl_xid;
13654  
13655         struct fasync_struct *  fl_fasync; /* for lease break notifications */
13656         unsigned long fl_break_time;    /* for nonblocking lease breaks */
13657 @@ -827,7 +849,7 @@ struct super_block {
13658         unsigned long long      s_maxbytes;     /* Max file size */
13659         struct file_system_type *s_type;
13660         struct super_operations *s_op;
13661 -       struct dquot_operations *dq_op;
13662 +       struct dquot_operations *s_qop;
13663         struct quotactl_ops     *s_qcop;
13664         struct export_operations *s_export_op;
13665         unsigned long           s_flags;
13666 @@ -850,7 +872,7 @@ struct super_block {
13667  
13668         struct block_device     *s_bdev;
13669         struct list_head        s_instances;
13670 -       struct quota_info       s_dquot;        /* Diskquota specific options */
13671 +       struct dqhash           *s_dqh;         /* Diskquota hash */
13672  
13673         int                     s_frozen;
13674         wait_queue_head_t       s_wait_unfrozen;
13675 @@ -920,12 +942,12 @@ static inline void unlock_super(struct s
13676   */
13677  extern int vfs_permission(struct nameidata *, int);
13678  extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
13679 -extern int vfs_mkdir(struct inode *, struct dentry *, int);
13680 -extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
13681 -extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
13682 -extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
13683 -extern int vfs_rmdir(struct inode *, struct dentry *);
13684 -extern int vfs_unlink(struct inode *, struct dentry *);
13685 +extern int vfs_mkdir(struct inode *, struct dentry *, int, struct nameidata *);
13686 +extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t, struct nameidata *);
13687 +extern int vfs_symlink(struct inode *, struct dentry *, const char *, int, struct nameidata *);
13688 +extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct nameidata *);
13689 +extern int vfs_rmdir(struct inode *, struct dentry *, struct nameidata *);
13690 +extern int vfs_unlink(struct inode *, struct dentry *, struct nameidata *);
13691  extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
13692  
13693  /*
13694 @@ -1067,6 +1089,7 @@ struct inode_operations {
13695         ssize_t (*listxattr) (struct dentry *, char *, size_t);
13696         int (*removexattr) (struct dentry *, const char *);
13697         void (*truncate_range)(struct inode *, loff_t, loff_t);
13698 +       int (*sync_flags) (struct inode *);
13699  };
13700  
13701  struct seq_file;
13702 @@ -1077,6 +1100,7 @@ extern ssize_t vfs_readv(struct file *, 
13703                 unsigned long, loff_t *);
13704  extern ssize_t vfs_writev(struct file *, const struct iovec __user *,
13705                 unsigned long, loff_t *);
13706 +ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
13707  
13708  /*
13709   * NOTE: write_inode, delete_inode, clear_inode, put_inode can be called
13710 @@ -1106,8 +1130,8 @@ struct super_operations {
13711         int (*show_options)(struct seq_file *, struct vfsmount *);
13712         int (*show_stats)(struct seq_file *, struct vfsmount *);
13713  
13714 -       ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
13715 -       ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
13716 +       ssize_t (*quota_read)(struct dqhash *, int, char *, size_t, loff_t);
13717 +       ssize_t (*quota_write)(struct dqhash *, int, const char *, size_t, loff_t);
13718  };
13719  
13720  /* Inode state bits.  Protected by inode_lock. */
13721 @@ -1570,7 +1594,7 @@ extern void clear_inode(struct inode *);
13722  extern void destroy_inode(struct inode *);
13723  extern struct inode *new_inode(struct super_block *);
13724  extern int remove_suid(struct dentry *);
13725 -extern void remove_dquot_ref(struct super_block *, int, struct list_head *);
13726 +extern void remove_dquot_ref(struct dqhash *, int, struct list_head *);
13727  
13728  extern void __insert_inode_hash(struct inode *, unsigned long hashval);
13729  extern void remove_inode_hash(struct inode *);
13730 @@ -1609,6 +1633,7 @@ extern ssize_t do_sync_write(struct file
13731  ssize_t generic_file_write_nolock(struct file *file, const struct iovec *iov,
13732                                 unsigned long nr_segs, loff_t *ppos);
13733  extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
13734 +extern ssize_t generic_file_sendpage(struct file *, struct page *, int, size_t, loff_t *, int);
13735  extern void do_generic_mapping_read(struct address_space *mapping,
13736                                     struct file_ra_state *, struct file *,
13737                                     loff_t *, read_descriptor_t *, read_actor_t);
13738 @@ -1742,6 +1767,7 @@ extern int dcache_dir_open(struct inode 
13739  extern int dcache_dir_close(struct inode *, struct file *);
13740  extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
13741  extern int dcache_readdir(struct file *, void *, filldir_t);
13742 +extern int dcache_readdir_filter(struct file *, void *, filldir_t, int (*)(struct dentry *));
13743  extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
13744  extern int simple_statfs(struct super_block *, struct kstatfs *);
13745  extern int simple_link(struct dentry *, struct inode *, struct dentry *);
13746 diff -NurpP --minimal linux-2.6.17.11/include/linux/init_task.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/init_task.h
13747 --- linux-2.6.17.11/include/linux/init_task.h   2006-06-18 04:55:18 +0200
13748 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/init_task.h      2006-08-26 00:53:58 +0200
13749 @@ -123,6 +123,10 @@ extern struct group_info init_groups;
13750         .journal_info   = NULL,                                         \
13751         .cpu_timers     = INIT_CPU_TIMERS(tsk.cpu_timers),              \
13752         .fs_excl        = ATOMIC_INIT(0),                               \
13753 +       .xid            = 0,                                            \
13754 +       .vx_info        = NULL,                                         \
13755 +       .nid            = 0,                                            \
13756 +       .nx_info        = NULL,                                         \
13757  }
13758  
13759  
13760 diff -NurpP --minimal linux-2.6.17.11/include/linux/ipc.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/ipc.h
13761 --- linux-2.6.17.11/include/linux/ipc.h 2004-08-14 12:54:46 +0200
13762 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/ipc.h    2006-07-09 17:07:13 +0200
13763 @@ -66,6 +66,7 @@ struct kern_ipc_perm
13764         mode_t          mode; 
13765         unsigned long   seq;
13766         void            *security;
13767 +       xid_t           xid;
13768  };
13769  
13770  #endif /* __KERNEL__ */
13771 diff -NurpP --minimal linux-2.6.17.11/include/linux/kernel.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/kernel.h
13772 --- linux-2.6.17.11/include/linux/kernel.h      2006-06-18 04:55:18 +0200
13773 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/kernel.h 2006-07-09 17:07:13 +0200
13774 @@ -17,6 +17,7 @@
13775  #include <asm/bug.h>
13776  
13777  extern const char linux_banner[];
13778 +extern const char vx_linux_banner[];
13779  
13780  #define INT_MAX                ((int)(~0U>>1))
13781  #define INT_MIN                (-INT_MAX - 1)
13782 diff -NurpP --minimal linux-2.6.17.11/include/linux/loop.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/loop.h
13783 --- linux-2.6.17.11/include/linux/loop.h        2006-06-18 04:55:19 +0200
13784 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/loop.h   2006-08-04 20:07:26 +0200
13785 @@ -45,6 +45,7 @@ struct loop_device {
13786         struct loop_func_table *lo_encryption;
13787         __u32           lo_init[2];
13788         uid_t           lo_key_owner;   /* Who set the key */
13789 +       xid_t           lo_xid;
13790         int             (*ioctl)(struct loop_device *, int cmd, 
13791                                  unsigned long arg); 
13792  
13793 diff -NurpP --minimal linux-2.6.17.11/include/linux/major.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/major.h
13794 --- linux-2.6.17.11/include/linux/major.h       2006-06-18 04:55:19 +0200
13795 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/major.h  2006-07-09 17:07:13 +0200
13796 @@ -15,6 +15,7 @@
13797  #define HD_MAJOR               IDE0_MAJOR
13798  #define PTY_SLAVE_MAJOR                3
13799  #define TTY_MAJOR              4
13800 +#define VROOT_MAJOR            4
13801  #define TTYAUX_MAJOR           5
13802  #define LP_MAJOR               6
13803  #define VCS_MAJOR              7
13804 diff -NurpP --minimal linux-2.6.17.11/include/linux/mount.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/mount.h
13805 --- linux-2.6.17.11/include/linux/mount.h       2006-04-09 13:49:57 +0200
13806 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/mount.h  2006-07-09 17:07:13 +0200
13807 @@ -22,10 +22,14 @@
13808  #define MNT_NOEXEC     0x04
13809  #define MNT_NOATIME    0x08
13810  #define MNT_NODIRATIME 0x10
13811 +#define MNT_RDONLY     0x20
13812 +
13813 +#define MNT_IS_RDONLY(m)       ((m) && ((m)->mnt_flags & MNT_RDONLY))
13814  
13815  #define MNT_SHARED     0x1000  /* if the vfsmount is a shared mount */
13816  #define MNT_UNBINDABLE 0x2000  /* if the vfsmount is a unbindable mount */
13817  #define MNT_PNODE_MASK 0x3000  /* propogation flag mask */
13818 +#define MNT_TAGID              0x8000
13819  
13820  struct vfsmount {
13821         struct list_head mnt_hash;
13822 @@ -47,6 +51,7 @@ struct vfsmount {
13823         struct vfsmount *mnt_master;    /* slave is on master->mnt_slave_list */
13824         struct namespace *mnt_namespace; /* containing namespace */
13825         int mnt_pinned;
13826 +       tag_t mnt_tag;                  /* tagging used for vfsmount */
13827  };
13828  
13829  static inline struct vfsmount *mntget(struct vfsmount *mnt)
13830 diff -NurpP --minimal linux-2.6.17.11/include/linux/net.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/net.h
13831 --- linux-2.6.17.11/include/linux/net.h 2006-06-18 04:55:19 +0200
13832 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/net.h    2006-07-09 17:07:13 +0200
13833 @@ -62,6 +62,7 @@ typedef enum {
13834  #define SOCK_ASYNC_WAITDATA    1
13835  #define SOCK_NOSPACE           2
13836  #define SOCK_PASSCRED          3
13837 +#define SOCK_USER_SOCKET       4
13838  
13839  #ifndef ARCH_HAS_SOCKET_TYPES
13840  /**
13841 diff -NurpP --minimal linux-2.6.17.11/include/linux/nfs_mount.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/nfs_mount.h
13842 --- linux-2.6.17.11/include/linux/nfs_mount.h   2005-08-29 22:25:42 +0200
13843 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/nfs_mount.h      2006-07-09 17:07:13 +0200
13844 @@ -61,6 +61,7 @@ struct nfs_mount_data {
13845  #define NFS_MOUNT_NOACL                0x0800  /* 4 */
13846  #define NFS_MOUNT_STRICTLOCK   0x1000  /* reserved for NFSv4 */
13847  #define NFS_MOUNT_SECFLAVOUR   0x2000  /* 5 */
13848 +#define NFS_MOUNT_TAGGED       0x8000  /* context tagging */
13849  #define NFS_MOUNT_FLAGMASK     0xFFFF
13850  
13851  #endif
13852 diff -NurpP --minimal linux-2.6.17.11/include/linux/percpu.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/percpu.h
13853 --- linux-2.6.17.11/include/linux/percpu.h      2006-04-09 13:49:57 +0200
13854 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/percpu.h 2006-07-09 17:07:13 +0200
13855 @@ -8,7 +8,7 @@
13856  
13857  /* Enough to cover all DEFINE_PER_CPUs in kernel, including modules. */
13858  #ifndef PERCPU_ENOUGH_ROOM
13859 -#define PERCPU_ENOUGH_ROOM 32768
13860 +#define PERCPU_ENOUGH_ROOM 65536
13861  #endif
13862  
13863  /* Must be an lvalue. */
13864 diff -NurpP --minimal linux-2.6.17.11/include/linux/proc_fs.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/proc_fs.h
13865 --- linux-2.6.17.11/include/linux/proc_fs.h     2006-06-18 04:55:21 +0200
13866 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/proc_fs.h        2006-07-09 17:07:13 +0200
13867 @@ -56,6 +56,7 @@ struct proc_dir_entry {
13868         nlink_t nlink;
13869         uid_t uid;
13870         gid_t gid;
13871 +       int vx_flags;
13872         loff_t size;
13873         struct inode_operations * proc_iops;
13874         const struct file_operations * proc_fops;
13875 @@ -251,9 +252,11 @@ extern void kclist_add(struct kcore_list
13876  struct proc_inode {
13877         struct task_struct *task;
13878         int type;
13879 +       int vx_flags;
13880         union {
13881                 int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
13882                 int (*proc_read)(struct task_struct *task, char *page);
13883 +               int (*proc_vid_read)(int vid, char *page);
13884         } op;
13885         struct proc_dir_entry *pde;
13886         struct inode vfs_inode;
13887 diff -NurpP --minimal linux-2.6.17.11/include/linux/quota.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/quota.h
13888 --- linux-2.6.17.11/include/linux/quota.h       2006-06-18 04:55:21 +0200
13889 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/quota.h  2006-08-25 17:37:22 +0200
13890 @@ -57,6 +57,13 @@ extern spinlock_t dq_data_lock;
13891  #define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10))
13892  #define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
13893  
13894 +/* are NULL dqhash ptrs valid? */
13895 +#ifdef HANDLE_DQHASH_NULL
13896 +#define        dqhash_valid(hash)      ((hash) != NULL)
13897 +#else
13898 +#define        dqhash_valid(hash)      (0 == 0)
13899 +#endif
13900 +
13901  #define MAXQUOTAS 2
13902  #define USRQUOTA  0            /* element used for user quotas */
13903  #define GRPQUOTA  1            /* element used for group quotas */
13904 @@ -176,19 +183,20 @@ struct mem_dqinfo {
13905         } u;
13906  };
13907  
13908 -struct super_block;
13909 +struct dqhash;
13910  
13911  #define DQF_MASK 0xffff                /* Mask for format specific flags */
13912  #define DQF_INFO_DIRTY_B 16
13913  #define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B) /* Is info dirty? */
13914  
13915 -extern void mark_info_dirty(struct super_block *sb, int type);
13916 +extern void mark_info_dirty(struct dqhash *hash, int type);
13917 +
13918  #define info_dirty(info) test_bit(DQF_INFO_DIRTY_B, &(info)->dqi_flags)
13919  #define info_any_dquot_dirty(info) (!list_empty(&(info)->dqi_dirty_list))
13920  #define info_any_dirty(info) (info_dirty(info) || info_any_dquot_dirty(info))
13921  
13922 -#define sb_dqopt(sb) (&(sb)->s_dquot)
13923 -#define sb_dqinfo(sb, type) (sb_dqopt(sb)->info+(type))
13924 +#define dqh_dqopt(hash) (&(hash)->dqh_dqopt)
13925 +#define dqh_dqinfo(hash, type) (dqh_dqopt(hash)->info+(type))
13926  
13927  struct dqstats {
13928         int lookups;
13929 @@ -218,7 +226,7 @@ struct dquot {
13930         struct mutex dq_lock;           /* dquot IO lock */
13931         atomic_t dq_count;              /* Use count */
13932         wait_queue_head_t dq_wait_unused;       /* Wait queue for dquot to become unused */
13933 -       struct super_block *dq_sb;      /* superblock this applies to */
13934 +       struct dqhash *dq_dqh;          /* quota hash backpointer */
13935         unsigned int dq_id;             /* ID this applies to (uid, gid) */
13936         loff_t dq_off;                  /* Offset of dquot on disk */
13937         unsigned long dq_flags;         /* See DQ_* */
13938 @@ -233,13 +241,14 @@ struct dquot {
13939  
13940  /* Operations which must be implemented by each quota format */
13941  struct quota_format_ops {
13942 -       int (*check_quota_file)(struct super_block *sb, int type);      /* Detect whether file is in our format */
13943 -       int (*read_file_info)(struct super_block *sb, int type);        /* Read main info about file - called on quotaon() */
13944 -       int (*write_file_info)(struct super_block *sb, int type);       /* Write main info about file */
13945 -       int (*free_file_info)(struct super_block *sb, int type);        /* Called on quotaoff() */
13946 -       int (*read_dqblk)(struct dquot *dquot);         /* Read structure for one user */
13947 -       int (*commit_dqblk)(struct dquot *dquot);       /* Write structure for one user */
13948 -       int (*release_dqblk)(struct dquot *dquot);      /* Called when last reference to dquot is being dropped */
13949 +       int (*check_quota_file)(struct dqhash *, int);  /* Detect whether file is in our format */
13950 +       int (*read_file_info)(struct dqhash *, int);    /* Read main info about file - called on quotaon() */
13951 +       int (*write_file_info)(struct dqhash *, int);   /* Write main info about file */
13952 +       int (*free_file_info)(struct dqhash *, int);    /* Called on quotaoff() */
13953 +
13954 +       int (*read_dqblk)(struct dquot *);      /* Read structure for one user */
13955 +       int (*commit_dqblk)(struct dquot *);    /* Write structure for one user */
13956 +       int (*release_dqblk)(struct dquot *);   /* Called when last reference to dquot is being dropped */
13957  };
13958  
13959  /* Operations working with dquots */
13960 @@ -255,22 +264,22 @@ struct dquot_operations {
13961         int (*acquire_dquot) (struct dquot *);          /* Quota is going to be created on disk */
13962         int (*release_dquot) (struct dquot *);          /* Quota is going to be deleted from disk */
13963         int (*mark_dirty) (struct dquot *);             /* Dquot is marked dirty */
13964 -       int (*write_info) (struct super_block *, int);  /* Write of quota "superblock" */
13965 +       int (*write_info) (struct dqhash *, int);       /* Write of quota "superblock" */
13966  };
13967  
13968  /* Operations handling requests from userspace */
13969  struct quotactl_ops {
13970 -       int (*quota_on)(struct super_block *, int, int, char *);
13971 -       int (*quota_off)(struct super_block *, int);
13972 -       int (*quota_sync)(struct super_block *, int);
13973 -       int (*get_info)(struct super_block *, int, struct if_dqinfo *);
13974 -       int (*set_info)(struct super_block *, int, struct if_dqinfo *);
13975 -       int (*get_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
13976 -       int (*set_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
13977 -       int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
13978 -       int (*set_xstate)(struct super_block *, unsigned int, int);
13979 -       int (*get_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
13980 -       int (*set_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
13981 +       int (*quota_on)(struct dqhash *, int, int, char *);
13982 +       int (*quota_off)(struct dqhash *, int);
13983 +       int (*quota_sync)(struct dqhash *, int);
13984 +       int (*get_info)(struct dqhash *, int, struct if_dqinfo *);
13985 +       int (*set_info)(struct dqhash *, int, struct if_dqinfo *);
13986 +       int (*get_dqblk)(struct dqhash *, int, qid_t, struct if_dqblk *);
13987 +       int (*set_dqblk)(struct dqhash *, int, qid_t, struct if_dqblk *);
13988 +       int (*get_xstate)(struct dqhash *, struct fs_quota_stat *);
13989 +       int (*set_xstate)(struct dqhash *, unsigned int, int);
13990 +       int (*get_xquota)(struct dqhash *, int, qid_t, struct fs_disk_quota *);
13991 +       int (*set_xquota)(struct dqhash *, int, qid_t, struct fs_disk_quota *);
13992  };
13993  
13994  struct quota_format_type {
13995 @@ -293,16 +302,15 @@ struct quota_info {
13996         struct quota_format_ops *ops[MAXQUOTAS];        /* Operations for each type */
13997  };
13998  
13999 -/* Inline would be better but we need to dereference super_block which is not defined yet */
14000 -int mark_dquot_dirty(struct dquot *dquot);
14001  
14002  #define dquot_dirty(dquot) test_bit(DQ_MOD_B, &(dquot)->dq_flags)
14003  
14004 -#define sb_has_quota_enabled(sb, type) ((type)==USRQUOTA ? \
14005 -       (sb_dqopt(sb)->flags & DQUOT_USR_ENABLED) : (sb_dqopt(sb)->flags & DQUOT_GRP_ENABLED))
14006 +#define dqh_has_quota_enabled(hash, type) (dqhash_valid(hash) && ((type)==USRQUOTA ? \
14007 +       (dqh_dqopt(hash)->flags & DQUOT_USR_ENABLED) : (dqh_dqopt(hash)->flags & DQUOT_GRP_ENABLED)))
14008 +
14009 +#define dqh_any_quota_enabled(hash) (dqhash_valid(hash) && \
14010 +       (dqh_has_quota_enabled(hash, USRQUOTA) || dqh_has_quota_enabled(hash, GRPQUOTA)))
14011  
14012 -#define sb_any_quota_enabled(sb) (sb_has_quota_enabled(sb, USRQUOTA) | \
14013 -                                 sb_has_quota_enabled(sb, GRPQUOTA))
14014  
14015  int register_quota_format(struct quota_format_type *fmt);
14016  void unregister_quota_format(struct quota_format_type *fmt);
14017 @@ -317,6 +325,50 @@ struct quota_module_name {
14018         {QFMT_VFS_V0, "quota_v2"},\
14019         {0, NULL}}
14020  
14021 +struct dqhash {
14022 +       struct list_head dqh_list;      /* List of all quota hashes */
14023 +       unsigned int dqh_id;            /* ID for hash */
14024 +       atomic_t dqh_count;             /* Use count */
14025 +       struct quota_info dqh_dqopt;    /* Diskquota specific options */
14026 +       struct dquot_operations *dqh_qop;
14027 +       struct quotactl_ops *dqh_qcop;
14028 +       struct super_block *dqh_sb;     /* super block */
14029 +       unsigned int dqh_hash_bits;
14030 +       unsigned int dqh_hash_mask;
14031 +       struct hlist_head *dqh_hash;
14032 +};
14033 +
14034 +#ifdef CONFIG_QUOTACTL
14035 +
14036 +struct dqhash *new_dqhash(struct super_block *, unsigned int);
14037 +void destroy_dqhash(struct dqhash *);
14038 +struct dqhash *find_dqhash(unsigned int);
14039 +
14040 +static inline void dqhput(struct dqhash *hash)
14041 +{
14042 +       if (dqhash_valid(hash))
14043 +               if (atomic_dec_and_test(&hash->dqh_count))
14044 +                       destroy_dqhash(hash);
14045 +}
14046 +
14047 +static inline struct dqhash *dqhget(struct dqhash *hash)
14048 +{
14049 +       if (dqhash_valid(hash))
14050 +               atomic_inc(&hash->dqh_count);
14051 +       return hash;
14052 +}
14053 +
14054 +#else /* CONFIG_QUOTACTL */
14055 +
14056 +#define new_dqhash(sb, dqdom)          (0)
14057 +#define find_dqhash(dqdom)             (0)
14058 +#define destroy_dqhash(hash)           do { } while(0)
14059 +
14060 +#define dqhput(hash)                   do { } while(0)
14061 +#define dqhget(hash)                   (hash)
14062 +
14063 +#endif /* CONFIG_QUOTACTL */
14064 +
14065  #else
14066  
14067  # /* nodep */ include <sys/cdefs.h>
14068 diff -NurpP --minimal linux-2.6.17.11/include/linux/quotaops.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/quotaops.h
14069 --- linux-2.6.17.11/include/linux/quotaops.h    2006-04-09 13:49:57 +0200
14070 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/quotaops.h       2006-07-09 17:07:13 +0200
14071 @@ -20,7 +20,7 @@
14072  /*
14073   * declaration of quota_function calls in kernel.
14074   */
14075 -extern void sync_dquots(struct super_block *sb, int type);
14076 +extern void sync_dquots(struct dqhash *hash, int type);
14077  
14078  extern int dquot_initialize(struct inode *inode, int type);
14079  extern int dquot_drop(struct inode *inode);
14080 @@ -35,19 +35,19 @@ extern int dquot_transfer(struct inode *
14081  extern int dquot_commit(struct dquot *dquot);
14082  extern int dquot_acquire(struct dquot *dquot);
14083  extern int dquot_release(struct dquot *dquot);
14084 -extern int dquot_commit_info(struct super_block *sb, int type);
14085 +extern int dquot_commit_info(struct dqhash *hash, int type);
14086  extern int dquot_mark_dquot_dirty(struct dquot *dquot);
14087  
14088 -extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path);
14089 -extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
14090 +extern int vfs_quota_on(struct dqhash *hash, int type, int format_id, char *path);
14091 +extern int vfs_quota_on_mount(struct dqhash *hash, char *qf_name,
14092                 int format_id, int type);
14093 -extern int vfs_quota_off(struct super_block *sb, int type);
14094 -#define vfs_quota_off_mount(sb, type) vfs_quota_off(sb, type)
14095 -extern int vfs_quota_sync(struct super_block *sb, int type);
14096 -extern int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
14097 -extern int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
14098 -extern int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
14099 -extern int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
14100 +extern int vfs_quota_off(struct dqhash *hash, int type);
14101 +#define vfs_quota_off_mount(dqh, type) vfs_quota_off(dqh, type)
14102 +extern int vfs_quota_sync(struct dqhash *hash, int type);
14103 +extern int vfs_get_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii);
14104 +extern int vfs_set_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii);
14105 +extern int vfs_get_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di);
14106 +extern int vfs_set_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di);
14107  
14108  /*
14109   * Operations supported for diskquotas.
14110 @@ -62,9 +62,12 @@ extern struct quotactl_ops vfs_quotactl_
14111   * need a lot of space in journal for dquot structure allocation. */
14112  static __inline__ void DQUOT_INIT(struct inode *inode)
14113  {
14114 -       BUG_ON(!inode->i_sb);
14115 -       if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode))
14116 -               inode->i_sb->dq_op->initialize(inode, -1);
14117 +       if (!dqhash_valid(inode->i_dqh))
14118 +               return;
14119 +       BUG_ON(!inode->i_dqh);
14120 +       // printk("DQUOT_INIT(%p,%p,%d)\n", inode, inode->i_dqh, dqh_any_quota_enabled(inode->i_dqh));
14121 +       if (dqh_any_quota_enabled(inode->i_dqh) && !IS_NOQUOTA(inode))
14122 +               inode->i_dqh->dqh_qop->initialize(inode, -1);
14123  }
14124  
14125  /* The same as with DQUOT_INIT */
14126 @@ -73,8 +76,8 @@ static __inline__ void DQUOT_DROP(struct
14127         /* Here we can get arbitrary inode from clear_inode() so we have
14128          * to be careful. OTOH we don't need locking as quota operations
14129          * are allowed to change only at mount time */
14130 -       if (!IS_NOQUOTA(inode) && inode->i_sb && inode->i_sb->dq_op
14131 -           && inode->i_sb->dq_op->drop) {
14132 +       if (!IS_NOQUOTA(inode) && inode->i_dqh && inode->i_dqh->dqh_qop
14133 +           && inode->i_dqh->dqh_qop->drop) {
14134                 int cnt;
14135                 /* Test before calling to rule out calls from proc and such
14136                   * where we are not allowed to block. Note that this is
14137 @@ -85,7 +88,7 @@ static __inline__ void DQUOT_DROP(struct
14138                         if (inode->i_dquot[cnt] != NODQUOT)
14139                                 break;
14140                 if (cnt < MAXQUOTAS)
14141 -                       inode->i_sb->dq_op->drop(inode);
14142 +                       inode->i_dqh->dqh_qop->drop(inode);
14143         }
14144  }
14145  
14146 @@ -93,9 +96,9 @@ static __inline__ void DQUOT_DROP(struct
14147   * a transaction (deadlocks possible otherwise) */
14148  static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14149  {
14150 -       if (sb_any_quota_enabled(inode->i_sb)) {
14151 +       if (dqh_any_quota_enabled(inode->i_dqh)) {
14152                 /* Used space is updated in alloc_space() */
14153 -               if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA)
14154 +               if (inode->i_dqh->dqh_qop->alloc_space(inode, nr, 1) == NO_QUOTA)
14155                         return 1;
14156         }
14157         else
14158 @@ -113,9 +116,9 @@ static __inline__ int DQUOT_PREALLOC_SPA
14159  
14160  static __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14161  {
14162 -       if (sb_any_quota_enabled(inode->i_sb)) {
14163 +       if (dqh_any_quota_enabled(inode->i_dqh)) {
14164                 /* Used space is updated in alloc_space() */
14165 -               if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA)
14166 +               if (inode->i_dqh->dqh_qop->alloc_space(inode, nr, 0) == NO_QUOTA)
14167                         return 1;
14168         }
14169         else
14170 @@ -133,9 +136,9 @@ static __inline__ int DQUOT_ALLOC_SPACE(
14171  
14172  static __inline__ int DQUOT_ALLOC_INODE(struct inode *inode)
14173  {
14174 -       if (sb_any_quota_enabled(inode->i_sb)) {
14175 +       if (dqh_any_quota_enabled(inode->i_dqh)) {
14176                 DQUOT_INIT(inode);
14177 -               if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA)
14178 +               if (inode->i_dqh->dqh_qop->alloc_inode(inode, 1) == NO_QUOTA)
14179                         return 1;
14180         }
14181         return 0;
14182 @@ -143,8 +146,8 @@ static __inline__ int DQUOT_ALLOC_INODE(
14183  
14184  static __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14185  {
14186 -       if (sb_any_quota_enabled(inode->i_sb))
14187 -               inode->i_sb->dq_op->free_space(inode, nr);
14188 +       if (dqh_any_quota_enabled(inode->i_dqh))
14189 +               inode->i_dqh->dqh_qop->free_space(inode, nr);
14190         else
14191                 inode_sub_bytes(inode, nr);
14192  }
14193 @@ -157,29 +160,30 @@ static __inline__ void DQUOT_FREE_SPACE(
14194  
14195  static __inline__ void DQUOT_FREE_INODE(struct inode *inode)
14196  {
14197 -       if (sb_any_quota_enabled(inode->i_sb))
14198 -               inode->i_sb->dq_op->free_inode(inode, 1);
14199 +       if (dqh_any_quota_enabled(inode->i_dqh))
14200 +               inode->i_dqh->dqh_qop->free_inode(inode, 1);
14201  }
14202  
14203  static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr)
14204  {
14205 -       if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) {
14206 +       if (dqh_any_quota_enabled(inode->i_dqh) && !IS_NOQUOTA(inode)) {
14207                 DQUOT_INIT(inode);
14208 -               if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA)
14209 +               if (inode->i_dqh->dqh_qop->transfer(inode, iattr) == NO_QUOTA)
14210                         return 1;
14211         }
14212         return 0;
14213  }
14214  
14215  /* The following two functions cannot be called inside a transaction */
14216 -#define DQUOT_SYNC(sb) sync_dquots(sb, -1)
14217 +#define DQUOT_SYNC(hash)       sync_dquots(hash, -1)
14218  
14219 -static __inline__ int DQUOT_OFF(struct super_block *sb)
14220 +static __inline__ int DQUOT_OFF(struct dqhash *hash)
14221  {
14222         int ret = -ENOSYS;
14223  
14224 -       if (sb_any_quota_enabled(sb) && sb->s_qcop && sb->s_qcop->quota_off)
14225 -               ret = sb->s_qcop->quota_off(sb, -1);
14226 +       if (dqh_any_quota_enabled(hash) && hash->dqh_qcop &&
14227 +               hash->dqh_qcop->quota_off)
14228 +               ret = hash->dqh_qcop->quota_off(hash, -1);
14229         return ret;
14230  }
14231  
14232 @@ -194,8 +198,8 @@ static __inline__ int DQUOT_OFF(struct s
14233  #define DQUOT_DROP(inode)                      do { } while(0)
14234  #define DQUOT_ALLOC_INODE(inode)               (0)
14235  #define DQUOT_FREE_INODE(inode)                        do { } while(0)
14236 -#define DQUOT_SYNC(sb)                         do { } while(0)
14237 -#define DQUOT_OFF(sb)                          do { } while(0)
14238 +#define DQUOT_SYNC(hash)                       do { } while(0)
14239 +#define DQUOT_OFF(hash)                                do { } while(0)
14240  #define DQUOT_TRANSFER(inode, iattr)           (0)
14241  static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14242  {
14243 diff -NurpP --minimal linux-2.6.17.11/include/linux/reiserfs_fs.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/reiserfs_fs.h
14244 --- linux-2.6.17.11/include/linux/reiserfs_fs.h 2006-06-18 04:55:21 +0200
14245 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/reiserfs_fs.h    2006-07-09 17:07:13 +0200
14246 @@ -829,6 +829,18 @@ struct stat_data_v1 {
14247  #define REISERFS_COMPR_FL     EXT2_COMPR_FL
14248  #define REISERFS_NOTAIL_FL    EXT2_NOTAIL_FL
14249  
14250 +/* unfortunately reiserfs sdattr is only 16 bit */
14251 +#define REISERFS_BARRIER_FL   (EXT2_BARRIER_FL >> 16)
14252 +#define REISERFS_IUNLINK_FL   (EXT2_IUNLINK_FL >> 16)
14253 +
14254 +#ifdef CONFIG_VSERVER_LEGACY
14255 +#define REISERFS_FL_USER_VISIBLE       (REISERFS_IUNLINK_FL|0x80FF)
14256 +#define REISERFS_FL_USER_MODIFIABLE    (REISERFS_IUNLINK_FL|0x80FF)
14257 +#else
14258 +#define REISERFS_FL_USER_VISIBLE       0x80FF
14259 +#define REISERFS_FL_USER_MODIFIABLE    0x80FF
14260 +#endif
14261 +
14262  /* persistent flags that file inherits from the parent directory */
14263  #define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL |        \
14264                                 REISERFS_SYNC_FL |      \
14265 @@ -1909,6 +1921,7 @@ static inline void reiserfs_update_sd(st
14266  void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode);
14267  void i_attrs_to_sd_attrs(struct inode *inode, __u16 * sd_attrs);
14268  int reiserfs_setattr(struct dentry *dentry, struct iattr *attr);
14269 +int reiserfs_sync_flags(struct inode *inode);
14270  
14271  /* namei.c */
14272  void set_de_name_and_namelen(struct reiserfs_dir_entry *de);
14273 diff -NurpP --minimal linux-2.6.17.11/include/linux/reiserfs_fs_sb.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/reiserfs_fs_sb.h
14274 --- linux-2.6.17.11/include/linux/reiserfs_fs_sb.h      2006-02-18 14:40:35 +0100
14275 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/reiserfs_fs_sb.h 2006-07-09 17:07:13 +0200
14276 @@ -456,6 +456,7 @@ enum reiserfs_mount_options {
14277         REISERFS_POSIXACL,
14278         REISERFS_BARRIER_NONE,
14279         REISERFS_BARRIER_FLUSH,
14280 +       REISERFS_TAGGED,
14281  
14282         /* Actions on error */
14283         REISERFS_ERROR_PANIC,
14284 diff -NurpP --minimal linux-2.6.17.11/include/linux/sched.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/sched.h
14285 --- linux-2.6.17.11/include/linux/sched.h       2006-06-18 04:55:21 +0200
14286 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/sched.h  2006-08-26 00:52:08 +0200
14287 @@ -15,6 +15,7 @@
14288  #include <linux/cpumask.h>
14289  #include <linux/errno.h>
14290  #include <linux/nodemask.h>
14291 +#include <linux/vs_base.h>
14292  
14293  #include <asm/system.h>
14294  #include <asm/semaphore.h>
14295 @@ -62,12 +63,13 @@ struct exec_domain;
14296  #define CLONE_UNTRACED         0x00800000      /* set if the tracing process can't force CLONE_PTRACE on this clone */
14297  #define CLONE_CHILD_SETTID     0x01000000      /* set the TID in the child */
14298  #define CLONE_STOPPED          0x02000000      /* Start in stopped state */
14299 +#define CLONE_KTHREAD          0x10000000      /* clone a kernel thread */
14300  
14301  /*
14302   * List of flags we want to share for kernel threads,
14303   * if only because they are not used by them anyway.
14304   */
14305 -#define CLONE_KERNEL   (CLONE_FS | CLONE_FILES | CLONE_SIGHAND)
14306 +#define CLONE_KERNEL   (CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_KTHREAD)
14307  
14308  /*
14309   * These are the constant used to fake the fixed-point load-average
14310 @@ -131,6 +133,7 @@ extern unsigned long nr_iowait(void);
14311  #define EXIT_DEAD              32
14312  /* in tsk->state again */
14313  #define TASK_NONINTERACTIVE    64
14314 +#define TASK_ONHOLD            128
14315  
14316  #define __set_task_state(tsk, state_value)             \
14317         do { (tsk)->state = (state_value); } while (0)
14318 @@ -259,27 +262,30 @@ extern void arch_unmap_area_topdown(stru
14319   * The mm counters are not protected by its page_table_lock,
14320   * so must be incremented atomically.
14321   */
14322 -#define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value)
14323 -#define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member))
14324 -#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member)
14325 -#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)
14326 -#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)
14327  typedef atomic_long_t mm_counter_t;
14328 +#define __set_mm_counter(mm, member, value) \
14329 +       atomic_long_set(&(mm)->_##member, value)
14330 +#define get_mm_counter(mm, member) \
14331 +       ((unsigned long)atomic_long_read(&(mm)->_##member))
14332  
14333  #else  /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
14334  /*
14335   * The mm counters are protected by its page_table_lock,
14336   * so can be incremented directly.
14337   */
14338 -#define set_mm_counter(mm, member, value) (mm)->_##member = (value)
14339 -#define get_mm_counter(mm, member) ((mm)->_##member)
14340 -#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
14341 -#define inc_mm_counter(mm, member) (mm)->_##member++
14342 -#define dec_mm_counter(mm, member) (mm)->_##member--
14343  typedef unsigned long mm_counter_t;
14344 +#define __set_mm_counter(mm, member, value) (mm)->_##member = (value)
14345 +#define get_mm_counter(mm, member) ((mm)->_##member)
14346  
14347  #endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
14348  
14349 +#define set_mm_counter(mm, member, value) \
14350 +       vx_ ## member ## pages_sub((mm), (get_mm_counter(mm, member) - value))
14351 +#define add_mm_counter(mm, member, value) \
14352 +       vx_ ## member ## pages_add((mm), (value))
14353 +#define inc_mm_counter(mm, member) vx_ ## member ## pages_inc((mm))
14354 +#define dec_mm_counter(mm, member) vx_ ## member ## pages_dec((mm))
14355 +
14356  #define get_mm_rss(mm)                                 \
14357         (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
14358  #define update_hiwater_rss(mm) do {                    \
14359 @@ -338,6 +344,7 @@ struct mm_struct {
14360  
14361         /* Architecture-specific MM context */
14362         mm_context_t context;
14363 +       struct vx_info *mm_vx_info;
14364  
14365         /* Token based thrashing protection. */
14366         unsigned long swap_token_time;
14367 @@ -510,9 +517,10 @@ struct user_struct {
14368         /* Hash table maintenance information */
14369         struct list_head uidhash_list;
14370         uid_t uid;
14371 +       xid_t xid;
14372  };
14373  
14374 -extern struct user_struct *find_user(uid_t);
14375 +extern struct user_struct *find_user(xid_t, uid_t);
14376  
14377  extern struct user_struct root_user;
14378  #define INIT_USER (&root_user)
14379 @@ -824,6 +832,14 @@ struct task_struct {
14380         
14381         void *security;
14382         struct audit_context *audit_context;
14383 +
14384 +/* vserver context data */
14385 +       struct vx_info *vx_info;
14386 +       struct nx_info *nx_info;
14387 +
14388 +       xid_t xid;
14389 +       nid_t nid;
14390 +
14391         seccomp_t seccomp;
14392  
14393  /* Thread group tracking */
14394 @@ -1040,13 +1056,19 @@ extern struct task_struct init_task;
14395  
14396  extern struct   mm_struct init_mm;
14397  
14398 -#define find_task_by_pid(nr)   find_task_by_pid_type(PIDTYPE_PID, nr)
14399 +
14400 +#define find_task_by_real_pid(nr) \
14401 +       find_task_by_pid_type(PIDTYPE_PID, nr)
14402 +#define find_task_by_pid(nr) \
14403 +       find_task_by_pid_type(PIDTYPE_PID, \
14404 +               vx_rmap_pid(nr))
14405 +
14406  extern struct task_struct *find_task_by_pid_type(int type, int pid);
14407  extern void set_special_pids(pid_t session, pid_t pgrp);
14408  extern void __set_special_pids(pid_t session, pid_t pgrp);
14409  
14410  /* per-UID process charging. */
14411 -extern struct user_struct * alloc_uid(uid_t);
14412 +extern struct user_struct * alloc_uid(xid_t, uid_t);
14413  static inline struct user_struct *get_uid(struct user_struct *u)
14414  {
14415         atomic_inc(&u->__count);
14416 diff -NurpP --minimal linux-2.6.17.11/include/linux/security.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/security.h
14417 --- linux-2.6.17.11/include/linux/security.h    2006-06-18 04:55:21 +0200
14418 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/security.h       2006-07-09 17:07:13 +0200
14419 @@ -1102,7 +1102,7 @@ struct security_operations {
14420         int (*capable) (struct task_struct * tsk, int cap);
14421         int (*acct) (struct file * file);
14422         int (*sysctl) (struct ctl_table * table, int op);
14423 -       int (*quotactl) (int cmds, int type, int id, struct super_block * sb);
14424 +       int (*quotactl) (int cmds, int type, int id, struct dqhash *);
14425         int (*quota_on) (struct dentry * dentry);
14426         int (*syslog) (int type);
14427         int (*settime) (struct timespec *ts, struct timezone *tz);
14428 @@ -1364,9 +1364,9 @@ static inline int security_sysctl(struct
14429  }
14430  
14431  static inline int security_quotactl (int cmds, int type, int id,
14432 -                                    struct super_block *sb)
14433 +                                    struct dqhash *hash)
14434  {
14435 -       return security_ops->quotactl (cmds, type, id, sb);
14436 +       return security_ops->quotactl (cmds, type, id, hash);
14437  }
14438  
14439  static inline int security_quota_on (struct dentry * dentry)
14440 @@ -2077,7 +2077,7 @@ static inline int security_sysctl(struct
14441  }
14442  
14443  static inline int security_quotactl (int cmds, int type, int id,
14444 -                                    struct super_block * sb)
14445 +                                    struct dqhash * hash)
14446  {
14447         return 0;
14448  }
14449 diff -NurpP --minimal linux-2.6.17.11/include/linux/shmem_fs.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/shmem_fs.h
14450 --- linux-2.6.17.11/include/linux/shmem_fs.h    2006-04-09 13:49:57 +0200
14451 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/shmem_fs.h       2006-07-09 17:07:13 +0200
14452 @@ -8,6 +8,9 @@
14453  
14454  #define SHMEM_NR_DIRECT 16
14455  
14456 +#define TMPFS_SUPER_MAGIC      0x01021994
14457 +
14458 +
14459  struct shmem_inode_info {
14460         spinlock_t              lock;
14461         unsigned long           flags;
14462 diff -NurpP --minimal linux-2.6.17.11/include/linux/stat.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/stat.h
14463 --- linux-2.6.17.11/include/linux/stat.h        2006-06-18 04:55:25 +0200
14464 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/stat.h   2006-07-09 17:07:13 +0200
14465 @@ -63,6 +63,7 @@ struct kstat {
14466         unsigned int    nlink;
14467         uid_t           uid;
14468         gid_t           gid;
14469 +       tag_t           tag;
14470         dev_t           rdev;
14471         loff_t          size;
14472         struct timespec  atime;
14473 diff -NurpP --minimal linux-2.6.17.11/include/linux/sunrpc/auth.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/sunrpc/auth.h
14474 --- linux-2.6.17.11/include/linux/sunrpc/auth.h 2006-02-18 14:40:35 +0100
14475 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/sunrpc/auth.h    2006-07-09 17:07:13 +0200
14476 @@ -28,6 +28,7 @@
14477  struct auth_cred {
14478         uid_t   uid;
14479         gid_t   gid;
14480 +       tag_t   tag;
14481         struct group_info *group_info;
14482  };
14483  
14484 diff -NurpP --minimal linux-2.6.17.11/include/linux/sunrpc/clnt.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/sunrpc/clnt.h
14485 --- linux-2.6.17.11/include/linux/sunrpc/clnt.h 2006-06-18 04:55:25 +0200
14486 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/sunrpc/clnt.h    2006-07-09 17:07:13 +0200
14487 @@ -52,7 +52,8 @@ struct rpc_clnt {
14488                                 cl_intr     : 1,/* interruptible */
14489                                 cl_autobind : 1,/* use getport() */
14490                                 cl_oneshot  : 1,/* dispose after use */
14491 -                               cl_dead     : 1;/* abandoned */
14492 +                               cl_dead     : 1,/* abandoned */
14493 +                               cl_tag      : 1;/* context tagging */
14494  
14495         struct rpc_rtt *        cl_rtt;         /* RTO estimator data */
14496         struct rpc_portmap *    cl_pmap;        /* port mapping */
14497 diff -NurpP --minimal linux-2.6.17.11/include/linux/syscalls.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/syscalls.h
14498 --- linux-2.6.17.11/include/linux/syscalls.h    2006-06-18 04:55:25 +0200
14499 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/syscalls.h       2006-07-09 17:07:13 +0200
14500 @@ -294,6 +294,8 @@ asmlinkage long sys_symlink(const char _
14501  asmlinkage long sys_unlink(const char __user *pathname);
14502  asmlinkage long sys_rename(const char __user *oldname,
14503                                 const char __user *newname);
14504 +asmlinkage long sys_copyfile(const char __user *from, const char __user *to,
14505 +                               umode_t mode);
14506  asmlinkage long sys_chmod(const char __user *filename, mode_t mode);
14507  asmlinkage long sys_fchmod(unsigned int fd, mode_t mode);
14508  
14509 diff -NurpP --minimal linux-2.6.17.11/include/linux/sysctl.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/sysctl.h
14510 --- linux-2.6.17.11/include/linux/sysctl.h      2006-06-18 04:55:25 +0200
14511 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/sysctl.h 2006-07-09 17:07:13 +0200
14512 @@ -93,6 +93,7 @@ enum
14513         KERN_CAP_BSET=14,       /* int: capability bounding set */
14514         KERN_PANIC=15,          /* int: panic timeout */
14515         KERN_REALROOTDEV=16,    /* real root device to mount after initrd */
14516 +       KERN_VSHELPER=17,       /* string: path to vshelper policy agent */
14517  
14518         KERN_SPARC_REBOOT=21,   /* reboot command on Sparc */
14519         KERN_CTLALTDEL=22,      /* int: allow ctl-alt-del to reboot */
14520 @@ -909,6 +910,9 @@ typedef int ctl_handler (ctl_table *tabl
14521  typedef int proc_handler (ctl_table *ctl, int write, struct file * filp,
14522                           void __user *buffer, size_t *lenp, loff_t *ppos);
14523  
14524 +typedef int virt_handler (struct ctl_table *ctl, int write, xid_t xid,
14525 +                         void **datap, size_t *lenp);
14526 +
14527  extern int proc_dostring(ctl_table *, int, struct file *,
14528                          void __user *, size_t *, loff_t *);
14529  extern int proc_dointvec(ctl_table *, int, struct file *,
14530 @@ -990,6 +994,7 @@ struct ctl_table 
14531         mode_t mode;
14532         ctl_table *child;
14533         proc_handler *proc_handler;     /* Callback for text formatting */
14534 +       virt_handler *virt_handler;     /* Context virtualization */
14535         ctl_handler *strategy;          /* Callback function for all r/w */
14536         struct proc_dir_entry *de;      /* /proc control block */
14537         void *extra1;
14538 diff -NurpP --minimal linux-2.6.17.11/include/linux/sysfs.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/sysfs.h
14539 --- linux-2.6.17.11/include/linux/sysfs.h       2006-06-18 04:55:25 +0200
14540 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/sysfs.h  2006-07-09 17:07:13 +0200
14541 @@ -12,6 +12,8 @@
14542  
14543  #include <asm/atomic.h>
14544  
14545 +#define SYSFS_SUPER_MAGIC      0x62656572
14546 +
14547  struct kobject;
14548  struct module;
14549  
14550 diff -NurpP --minimal linux-2.6.17.11/include/linux/time.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/time.h
14551 --- linux-2.6.17.11/include/linux/time.h        2006-06-18 04:55:25 +0200
14552 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/time.h   2006-07-09 17:07:13 +0200
14553 @@ -142,6 +142,8 @@ extern struct timespec ns_to_timespec(co
14554   */
14555  extern struct timeval ns_to_timeval(const s64 nsec);
14556  
14557 +#include <linux/vs_time.h>
14558 +
14559  #endif /* __KERNEL__ */
14560  
14561  #define NFDBITS                        __NFDBITS
14562 diff -NurpP --minimal linux-2.6.17.11/include/linux/types.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/types.h
14563 --- linux-2.6.17.11/include/linux/types.h       2006-06-18 04:55:26 +0200
14564 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/types.h  2006-07-09 17:07:13 +0200
14565 @@ -38,6 +38,9 @@ typedef __kernel_uid32_t      uid_t;
14566  typedef __kernel_gid32_t       gid_t;
14567  typedef __kernel_uid16_t        uid16_t;
14568  typedef __kernel_gid16_t        gid16_t;
14569 +typedef unsigned int           xid_t;
14570 +typedef unsigned int           nid_t;
14571 +typedef unsigned int           tag_t;
14572  
14573  #ifdef CONFIG_UID16
14574  /* This is defined by include/asm-{arch}/posix_types.h */
14575 diff -NurpP --minimal linux-2.6.17.11/include/linux/vroot.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vroot.h
14576 --- linux-2.6.17.11/include/linux/vroot.h       1970-01-01 01:00:00 +0100
14577 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vroot.h  2006-07-09 17:07:13 +0200
14578 @@ -0,0 +1,51 @@
14579 +
14580 +/*
14581 + * include/linux/vroot.h
14582 + *
14583 + * written by Herbert Pötzl, 9/11/2002
14584 + * ported to 2.6 by Herbert Pötzl, 30/12/2004
14585 + *
14586 + * Copyright (C) 2002-2005 by Herbert Pötzl.
14587 + * Redistribution of this file is permitted under the
14588 + * GNU General Public License.
14589 + */
14590 +
14591 +#ifndef _LINUX_VROOT_H
14592 +#define _LINUX_VROOT_H
14593 +
14594 +
14595 +#ifdef __KERNEL__
14596 +
14597 +/* Possible states of device */
14598 +enum {
14599 +       Vr_unbound,
14600 +       Vr_bound,
14601 +};
14602 +
14603 +struct vroot_device {
14604 +       int             vr_number;
14605 +       int             vr_refcnt;
14606 +
14607 +       struct semaphore        vr_ctl_mutex;
14608 +       struct block_device    *vr_device;
14609 +       int                     vr_state;
14610 +};
14611 +
14612 +
14613 +typedef struct block_device *(vroot_grb_func)(struct block_device *);
14614 +
14615 +extern int register_vroot_grb(vroot_grb_func *);
14616 +extern int unregister_vroot_grb(vroot_grb_func *);
14617 +
14618 +#endif /* __KERNEL__ */
14619 +
14620 +#define MAX_VROOT_DEFAULT      8
14621 +
14622 +/*
14623 + * IOCTL commands --- we will commandeer 0x56 ('V')
14624 + */
14625 +
14626 +#define VROOT_SET_DEV          0x5600
14627 +#define VROOT_CLR_DEV          0x5601
14628 +
14629 +#endif /* _LINUX_VROOT_H */
14630 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_base.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_base.h
14631 --- linux-2.6.17.11/include/linux/vs_base.h     1970-01-01 01:00:00 +0100
14632 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_base.h        2006-08-26 00:52:08 +0200
14633 @@ -0,0 +1,130 @@
14634 +#ifndef _VX_VS_BASE_H
14635 +#define _VX_VS_BASE_H
14636 +
14637 +#include "vserver/context.h"
14638 +
14639 +
14640 +#define vx_task_xid(t) ((t)->xid)
14641 +
14642 +#define vx_current_xid() vx_task_xid(current)
14643 +
14644 +#define vx_check(c,m)  __vx_check(vx_current_xid(),c,m)
14645 +
14646 +#define vx_weak_check(c,m)     ((m) ? vx_check(c,m) : 1)
14647 +
14648 +
14649 +/*
14650 + * check current context for ADMIN/WATCH and
14651 + * optionally against supplied argument
14652 + */
14653 +static inline int __vx_check(xid_t cid, xid_t id, unsigned int mode)
14654 +{
14655 +       if (mode & VX_ARG_MASK) {
14656 +               if ((mode & VX_IDENT) &&
14657 +                       (id == cid))
14658 +                       return 1;
14659 +       }
14660 +       if (mode & VX_ATR_MASK) {
14661 +               if ((mode & VX_DYNAMIC) &&
14662 +                       (id >= MIN_D_CONTEXT) &&
14663 +                       (id <= MAX_S_CONTEXT))
14664 +                       return 1;
14665 +               if ((mode & VX_STATIC) &&
14666 +                       (id > 2) && (id < MIN_D_CONTEXT))
14667 +                       return 1;
14668 +       }
14669 +       return (((mode & VX_ADMIN) && (cid == 0)) ||
14670 +               ((mode & VX_WATCH) && (cid == 1)) ||
14671 +               ((mode & VX_HOSTID) && (id == 0)));
14672 +}
14673 +
14674 +
14675 +#define __vx_state(v)  ((v) ? ((v)->vx_state) : 0)
14676 +
14677 +#define vx_info_state(v,m)     (__vx_state(v) & (m))
14678 +
14679 +
14680 +/* generic flag merging */
14681 +
14682 +#define vx_check_flags(v,m,f)  (((v) & (m)) ^ (f))
14683 +
14684 +#define vx_mask_flags(v,f,m)   (((v) & ~(m)) | ((f) & (m)))
14685 +
14686 +#define vx_mask_mask(v,f,m)    (((v) & ~(m)) | ((v) & (f) & (m)))
14687 +
14688 +#define vx_check_bit(v,n)      ((v) & (1LL << (n)))
14689 +
14690 +
14691 +/* context flags */
14692 +
14693 +#define __vx_flags(v)  ((v) ? (v)->vx_flags : 0)
14694 +
14695 +#define vx_current_flags()     __vx_flags(current->vx_info)
14696 +
14697 +#define vx_info_flags(v,m,f) \
14698 +       vx_check_flags(__vx_flags(v),(m),(f))
14699 +
14700 +#define task_vx_flags(t,m,f) \
14701 +       ((t) && vx_info_flags((t)->vx_info, (m), (f)))
14702 +
14703 +#define vx_flags(m,f)  vx_info_flags(current->vx_info,(m),(f))
14704 +
14705 +
14706 +/* context caps */
14707 +
14708 +#define __vx_ccaps(v)  ((v) ? (v)->vx_ccaps : 0)
14709 +
14710 +#define vx_current_ccaps()     __vx_ccaps(current->vx_info)
14711 +
14712 +#define vx_info_ccaps(v,c)     (__vx_ccaps(v) & (c))
14713 +
14714 +#define vx_ccaps(c)    vx_info_ccaps(current->vx_info,(c))
14715 +
14716 +
14717 +#define __vx_mcaps(v)  ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
14718 +
14719 +#define vx_info_mcaps(v,c)     (__vx_mcaps(v) & (c))
14720 +
14721 +#define vx_mcaps(c)    vx_info_mcaps(current->vx_info,(c))
14722 +
14723 +
14724 +/* context bcap mask */
14725 +
14726 +#define __vx_bcaps(v)  ((v) ? (v)->vx_bcaps : ~0 )
14727 +
14728 +#define vx_current_bcaps()     __vx_bcaps(current->vx_info)
14729 +
14730 +#define vx_info_bcaps(v,c)     (__vx_bcaps(v) & (c))
14731 +
14732 +#define vx_bcaps(c)    vx_info_bcaps(current->vx_info,(c))
14733 +
14734 +
14735 +#define vx_info_cap_bset(v)    ((v) ? (v)->vx_cap_bset : cap_bset)
14736 +
14737 +#define vx_current_cap_bset()  vx_info_cap_bset(current->vx_info)
14738 +
14739 +
14740 +#define __vx_info_mbcap(v,b) \
14741 +       (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \
14742 +       vx_info_bcaps(v, b) : (b))
14743 +
14744 +#define vx_info_mbcap(v,b)     __vx_info_mbcap(v,cap_t(b))
14745 +
14746 +#define task_vx_mbcap(t,b) \
14747 +       vx_info_mbcap((t)->vx_info, (t)->b)
14748 +
14749 +#define vx_mbcap(b)    task_vx_mbcap(current,b)
14750 +
14751 +#define vx_cap_raised(v,c,f)   (vx_info_mbcap(v,c) & CAP_TO_MASK(f))
14752 +
14753 +#define vx_capable(b,c) (capable(b) || \
14754 +       (cap_raised(current->cap_effective,b) && vx_ccaps(c)))
14755 +
14756 +
14757 +#define vx_current_initpid(n) \
14758 +       (current->vx_info && \
14759 +       (current->vx_info->vx_initpid == (n)))
14760 +
14761 +#else
14762 +#warning duplicate inclusion
14763 +#endif
14764 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_context.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_context.h
14765 --- linux-2.6.17.11/include/linux/vs_context.h  1970-01-01 01:00:00 +0100
14766 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_context.h     2006-07-09 17:07:13 +0200
14767 @@ -0,0 +1,241 @@
14768 +#ifndef _VX_VS_CONTEXT_H
14769 +#define _VX_VS_CONTEXT_H
14770 +
14771 +#include <linux/kernel.h>
14772 +#include "vserver/debug.h"
14773 +#include "vserver/history.h"
14774 +
14775 +
14776 +#define get_vx_info(i) __get_vx_info(i,__FILE__,__LINE__,__HERE__)
14777 +
14778 +static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
14779 +       const char *_file, int _line, void *_here)
14780 +{
14781 +       if (!vxi)
14782 +               return NULL;
14783 +
14784 +       vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])",
14785 +               vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_usecnt):0,
14786 +               _file, _line);
14787 +       __vxh_get_vx_info(vxi, _here);
14788 +
14789 +       atomic_inc(&vxi->vx_usecnt);
14790 +       return vxi;
14791 +}
14792 +
14793 +
14794 +extern void free_vx_info(struct vx_info *);
14795 +
14796 +#define put_vx_info(i) __put_vx_info(i,__FILE__,__LINE__,__HERE__)
14797 +
14798 +static inline void __put_vx_info(struct vx_info *vxi,
14799 +       const char *_file, int _line, void *_here)
14800 +{
14801 +       if (!vxi)
14802 +               return;
14803 +
14804 +       vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])",
14805 +               vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_usecnt):0,
14806 +               _file, _line);
14807 +       __vxh_put_vx_info(vxi, _here);
14808 +
14809 +       if (atomic_dec_and_test(&vxi->vx_usecnt))
14810 +               free_vx_info(vxi);
14811 +}
14812 +
14813 +
14814 +#define init_vx_info(p,i) __init_vx_info(p,i,__FILE__,__LINE__,__HERE__)
14815 +
14816 +static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi,
14817 +       const char *_file, int _line, void *_here)
14818 +{
14819 +       if (vxi) {
14820 +               vxlprintk(VXD_CBIT(xid, 3),
14821 +                       "init_vx_info(%p[#%d.%d])",
14822 +                       vxi, vxi?vxi->vx_id:0,
14823 +                       vxi?atomic_read(&vxi->vx_usecnt):0,
14824 +                       _file, _line);
14825 +               __vxh_init_vx_info(vxi, vxp, _here);
14826 +
14827 +               atomic_inc(&vxi->vx_usecnt);
14828 +       }
14829 +       *vxp = vxi;
14830 +}
14831 +
14832 +
14833 +#define set_vx_info(p,i) __set_vx_info(p,i,__FILE__,__LINE__,__HERE__)
14834 +
14835 +static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
14836 +       const char *_file, int _line, void *_here)
14837 +{
14838 +       struct vx_info *vxo;
14839 +
14840 +       if (!vxi)
14841 +               return;
14842 +
14843 +       vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])",
14844 +               vxi, vxi?vxi->vx_id:0,
14845 +               vxi?atomic_read(&vxi->vx_usecnt):0,
14846 +               _file, _line);
14847 +       __vxh_set_vx_info(vxi, vxp, _here);
14848 +
14849 +       atomic_inc(&vxi->vx_usecnt);
14850 +       vxo = xchg(vxp, vxi);
14851 +       BUG_ON(vxo);
14852 +}
14853 +
14854 +
14855 +#define clr_vx_info(p) __clr_vx_info(p,__FILE__,__LINE__,__HERE__)
14856 +
14857 +static inline void __clr_vx_info(struct vx_info **vxp,
14858 +       const char *_file, int _line, void *_here)
14859 +{
14860 +       struct vx_info *vxo;
14861 +
14862 +       vxo = xchg(vxp, NULL);
14863 +       if (!vxo)
14864 +               return;
14865 +
14866 +       vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])",
14867 +               vxo, vxo?vxo->vx_id:0,
14868 +               vxo?atomic_read(&vxo->vx_usecnt):0,
14869 +               _file, _line);
14870 +       __vxh_clr_vx_info(vxo, vxp, _here);
14871 +
14872 +       if (atomic_dec_and_test(&vxo->vx_usecnt))
14873 +               free_vx_info(vxo);
14874 +}
14875 +
14876 +
14877 +#define claim_vx_info(v,p) \
14878 +       __claim_vx_info(v,p,__FILE__,__LINE__,__HERE__)
14879 +
14880 +static inline void __claim_vx_info(struct vx_info *vxi,
14881 +       struct task_struct *task,
14882 +       const char *_file, int _line, void *_here)
14883 +{
14884 +       vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p",
14885 +               vxi, vxi?vxi->vx_id:0,
14886 +               vxi?atomic_read(&vxi->vx_usecnt):0,
14887 +               vxi?atomic_read(&vxi->vx_tasks):0,
14888 +               task, _file, _line);
14889 +       __vxh_claim_vx_info(vxi, task, _here);
14890 +
14891 +       atomic_inc(&vxi->vx_tasks);
14892 +}
14893 +
14894 +
14895 +extern void unhash_vx_info(struct vx_info *);
14896 +
14897 +#define release_vx_info(v,p) \
14898 +       __release_vx_info(v,p,__FILE__,__LINE__,__HERE__)
14899 +
14900 +static inline void __release_vx_info(struct vx_info *vxi,
14901 +       struct task_struct *task,
14902 +       const char *_file, int _line, void *_here)
14903 +{
14904 +       vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p",
14905 +               vxi, vxi?vxi->vx_id:0,
14906 +               vxi?atomic_read(&vxi->vx_usecnt):0,
14907 +               vxi?atomic_read(&vxi->vx_tasks):0,
14908 +               task, _file, _line);
14909 +       __vxh_release_vx_info(vxi, task, _here);
14910 +
14911 +       might_sleep();
14912 +
14913 +       if (atomic_dec_and_test(&vxi->vx_tasks))
14914 +               unhash_vx_info(vxi);
14915 +}
14916 +
14917 +
14918 +#define task_get_vx_info(p) \
14919 +       __task_get_vx_info(p,__FILE__,__LINE__,__HERE__)
14920 +
14921 +static inline struct vx_info *__task_get_vx_info(struct task_struct *p,
14922 +       const char *_file, int _line, void *_here)
14923 +{
14924 +       struct vx_info *vxi;
14925 +
14926 +       task_lock(p);
14927 +       vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)",
14928 +               p, _file, _line);
14929 +       vxi = __get_vx_info(p->vx_info, _file, _line, _here);
14930 +       task_unlock(p);
14931 +       return vxi;
14932 +}
14933 +
14934 +
14935 +static inline void __wakeup_vx_info(struct vx_info *vxi)
14936 +{
14937 +       if (waitqueue_active(&vxi->vx_wait))
14938 +               wake_up_interruptible(&vxi->vx_wait);
14939 +}
14940 +
14941 +
14942 +#define enter_vx_info(v,s)     __enter_vx_info(v,s,__FILE__,__LINE__)
14943 +
14944 +static inline void __enter_vx_info(struct vx_info *vxi,
14945 +       struct vx_info_save *vxis, const char *_file, int _line)
14946 +{
14947 +       vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]",
14948 +               vxi, vxi ? vxi->vx_id : 0, vxis, current,
14949 +               current->xid, current->vx_info, _file, _line);
14950 +       vxis->vxi = xchg(&current->vx_info, vxi);
14951 +       vxis->xid = current->xid;
14952 +       current->xid = vxi ? vxi->vx_id : 0;
14953 +}
14954 +
14955 +#define leave_vx_info(s)       __leave_vx_info(s,__FILE__,__LINE__)
14956 +
14957 +static inline void __leave_vx_info(struct vx_info_save *vxis,
14958 +       const char *_file, int _line)
14959 +{
14960 +       vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]",
14961 +               vxis, vxis->xid, vxis->vxi, current,
14962 +               current->xid, current->vx_info, _file, _line);
14963 +       (void)xchg(&current->vx_info, vxis->vxi);
14964 +       current->xid = vxis->xid;
14965 +}
14966 +
14967 +
14968 +static inline void __enter_vx_admin(struct vx_info_save *vxis)
14969 +{
14970 +       vxis->vxi = xchg(&current->vx_info, NULL);
14971 +       vxis->xid = current->xid;
14972 +       current->xid = 0;
14973 +}
14974 +
14975 +static inline void __leave_vx_admin(struct vx_info_save *vxis)
14976 +{
14977 +       if (vxis->vxi)
14978 +               (void)xchg(&current->vx_info, vxis->vxi);
14979 +       current->xid = vxis->xid;
14980 +}
14981 +
14982 +extern void exit_vx_info(struct task_struct *, int);
14983 +
14984 +
14985 +static inline
14986 +struct task_struct *vx_child_reaper(struct task_struct *p)
14987 +{
14988 +       struct vx_info *vxi = p->vx_info;
14989 +       struct task_struct *reaper = child_reaper;
14990 +
14991 +       if (!vxi)
14992 +               goto out;
14993 +
14994 +       BUG_ON(!p->vx_info->vx_reaper);
14995 +
14996 +       /* child reaper for the guest reaper */
14997 +       if (vxi->vx_reaper == p)
14998 +               goto out;
14999 +
15000 +       reaper = vxi->vx_reaper;
15001 +out:
15002 +       return reaper;
15003 +}
15004 +
15005 +
15006 +#else
15007 +#warning duplicate inclusion
15008 +#endif
15009 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_cvirt.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_cvirt.h
15010 --- linux-2.6.17.11/include/linux/vs_cvirt.h    1970-01-01 01:00:00 +0100
15011 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_cvirt.h       2006-07-09 17:07:13 +0200
15012 @@ -0,0 +1,59 @@
15013 +#ifndef _VX_VS_CVIRT_H
15014 +#define _VX_VS_CVIRT_H
15015 +
15016 +#include "vserver/cvirt.h"
15017 +#include "vserver/debug.h"
15018 +
15019 +
15020 +/* utsname virtualization */
15021 +
15022 +static inline struct new_utsname *vx_new_utsname(void)
15023 +{
15024 +       if (current->vx_info)
15025 +               return &current->vx_info->cvirt.utsname;
15026 +       return &system_utsname;
15027 +}
15028 +
15029 +#define vx_new_uts(x)          ((vx_new_utsname())->x)
15030 +
15031 +
15032 +static inline void vx_activate_task(struct task_struct *p)
15033 +{
15034 +       struct vx_info *vxi;
15035 +
15036 +       if ((vxi = p->vx_info)) {
15037 +               vx_update_load(vxi);
15038 +               atomic_inc(&vxi->cvirt.nr_running);
15039 +       }
15040 +}
15041 +
15042 +static inline void vx_deactivate_task(struct task_struct *p)
15043 +{
15044 +       struct vx_info *vxi;
15045 +
15046 +       if ((vxi = p->vx_info)) {
15047 +               vx_update_load(vxi);
15048 +               atomic_dec(&vxi->cvirt.nr_running);
15049 +       }
15050 +}
15051 +
15052 +static inline void vx_uninterruptible_inc(struct task_struct *p)
15053 +{
15054 +       struct vx_info *vxi;
15055 +
15056 +       if ((vxi = p->vx_info))
15057 +               atomic_inc(&vxi->cvirt.nr_uninterruptible);
15058 +}
15059 +
15060 +static inline void vx_uninterruptible_dec(struct task_struct *p)
15061 +{
15062 +       struct vx_info *vxi;
15063 +
15064 +       if ((vxi = p->vx_info))
15065 +               atomic_dec(&vxi->cvirt.nr_uninterruptible);
15066 +}
15067 +
15068 +
15069 +#else
15070 +#warning duplicate inclusion
15071 +#endif
15072 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_dlimit.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_dlimit.h
15073 --- linux-2.6.17.11/include/linux/vs_dlimit.h   1970-01-01 01:00:00 +0100
15074 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_dlimit.h      2006-07-09 17:07:13 +0200
15075 @@ -0,0 +1,213 @@
15076 +#ifndef _VX_VS_DLIMIT_H
15077 +#define _VX_VS_DLIMIT_H
15078 +
15079 +#include "vserver/dlimit.h"
15080 +#include "vserver/debug.h"
15081 +
15082 +
15083 +#define get_dl_info(i) __get_dl_info(i,__FILE__,__LINE__)
15084 +
15085 +static inline struct dl_info *__get_dl_info(struct dl_info *dli,
15086 +       const char *_file, int _line)
15087 +{
15088 +       if (!dli)
15089 +               return NULL;
15090 +       vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
15091 +               dli, dli?dli->dl_tag:0, dli?atomic_read(&dli->dl_usecnt):0,
15092 +               _file, _line);
15093 +       atomic_inc(&dli->dl_usecnt);
15094 +       return dli;
15095 +}
15096 +
15097 +
15098 +#define free_dl_info(i) \
15099 +       call_rcu(&i->dl_rcu, rcu_free_dl_info);
15100 +
15101 +#define put_dl_info(i) __put_dl_info(i,__FILE__,__LINE__)
15102 +
15103 +static inline void __put_dl_info(struct dl_info *dli,
15104 +       const char *_file, int _line)
15105 +{
15106 +       if (!dli)
15107 +               return;
15108 +       vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
15109 +               dli, dli?dli->dl_tag:0, dli?atomic_read(&dli->dl_usecnt):0,
15110 +               _file, _line);
15111 +       if (atomic_dec_and_test(&dli->dl_usecnt))
15112 +               free_dl_info(dli);
15113 +}
15114 +
15115 +
15116 +#define __dlimit_char(d)       ((d)?'*':' ')
15117 +
15118 +static inline int __dl_alloc_space(struct super_block *sb,
15119 +       tag_t tag, dlsize_t nr, const char *file, int line)
15120 +{
15121 +       struct dl_info *dli = NULL;
15122 +       int ret = 0;
15123 +
15124 +       if (nr == 0)
15125 +               goto out;
15126 +       dli = locate_dl_info(sb, tag);
15127 +       if (!dli)
15128 +               goto out;
15129 +
15130 +       spin_lock(&dli->dl_lock);
15131 +       ret = (dli->dl_space_used + nr > dli->dl_space_total);
15132 +       if (!ret)
15133 +               dli->dl_space_used += nr;
15134 +       spin_unlock(&dli->dl_lock);
15135 +       put_dl_info(dli);
15136 +out:
15137 +       vxlprintk(VXD_CBIT(dlim, 1),
15138 +               "ALLOC (%p,#%d)%c %lld bytes (%d)",
15139 +               sb, tag, __dlimit_char(dli), (long long)nr,
15140 +               ret, file, line);
15141 +       return ret;
15142 +}
15143 +
15144 +static inline void __dl_free_space(struct super_block *sb,
15145 +       tag_t tag, dlsize_t nr, const char *_file, int _line)
15146 +{
15147 +       struct dl_info *dli = NULL;
15148 +
15149 +       if (nr == 0)
15150 +               goto out;
15151 +       dli = locate_dl_info(sb, tag);
15152 +       if (!dli)
15153 +               goto out;
15154 +
15155 +       spin_lock(&dli->dl_lock);
15156 +       if (dli->dl_space_used > nr)
15157 +               dli->dl_space_used -= nr;
15158 +       else
15159 +               dli->dl_space_used = 0;
15160 +       spin_unlock(&dli->dl_lock);
15161 +       put_dl_info(dli);
15162 +out:
15163 +       vxlprintk(VXD_CBIT(dlim, 1),
15164 +               "FREE  (%p,#%d)%c %lld bytes",
15165 +               sb, tag, __dlimit_char(dli), (long long)nr,
15166 +               _file, _line);
15167 +}
15168 +
15169 +static inline int __dl_alloc_inode(struct super_block *sb,
15170 +       tag_t tag, const char *_file, int _line)
15171 +{
15172 +       struct dl_info *dli;
15173 +       int ret = 0;
15174 +
15175 +       dli = locate_dl_info(sb, tag);
15176 +       if (!dli)
15177 +               goto out;
15178 +
15179 +       spin_lock(&dli->dl_lock);
15180 +       ret = (dli->dl_inodes_used >= dli->dl_inodes_total);
15181 +       if (!ret)
15182 +               dli->dl_inodes_used++;
15183 +#if 0
15184 +       else
15185 +               vxwprintk("DLIMIT hit (%p,#%d), inode %d>=%d @ %s:%d",
15186 +                       sb, tag,
15187 +                       dli->dl_inodes_used, dli->dl_inodes_total,
15188 +                       file, line);
15189 +#endif
15190 +       spin_unlock(&dli->dl_lock);
15191 +       put_dl_info(dli);
15192 +out:
15193 +       vxlprintk(VXD_CBIT(dlim, 0),
15194 +               "ALLOC (%p,#%d)%c inode (%d)",
15195 +               sb, tag, __dlimit_char(dli), ret, _file, _line);
15196 +       return ret;
15197 +}
15198 +
15199 +static inline void __dl_free_inode(struct super_block *sb,
15200 +       tag_t tag, const char *_file, int _line)
15201 +{
15202 +       struct dl_info *dli;
15203 +
15204 +       dli = locate_dl_info(sb, tag);
15205 +       if (!dli)
15206 +               goto out;
15207 +
15208 +       spin_lock(&dli->dl_lock);
15209 +       if (dli->dl_inodes_used > 1)
15210 +               dli->dl_inodes_used--;
15211 +       else
15212 +               dli->dl_inodes_used = 0;
15213 +       spin_unlock(&dli->dl_lock);
15214 +       put_dl_info(dli);
15215 +out:
15216 +       vxlprintk(VXD_CBIT(dlim, 0),
15217 +               "FREE  (%p,#%d)%c inode",
15218 +               sb, tag, __dlimit_char(dli), _file, _line);
15219 +}
15220 +
15221 +static inline void __dl_adjust_block(struct super_block *sb, tag_t tag,
15222 +       unsigned int *free_blocks, unsigned int *root_blocks,
15223 +       const char *_file, int _line)
15224 +{
15225 +       struct dl_info *dli;
15226 +       uint64_t broot, bfree;
15227 +
15228 +       dli = locate_dl_info(sb, tag);
15229 +       if (!dli)
15230 +               return;
15231 +
15232 +       spin_lock(&dli->dl_lock);
15233 +       broot = (dli->dl_space_total -
15234 +               (dli->dl_space_total >> 10) * dli->dl_nrlmult)
15235 +               >> sb->s_blocksize_bits;
15236 +       bfree = (dli->dl_space_total - dli->dl_space_used)
15237 +                       >> sb->s_blocksize_bits;
15238 +       spin_unlock(&dli->dl_lock);
15239 +
15240 +       vxlprintk(VXD_CBIT(dlim, 2),
15241 +               "ADJUST: %lld,%lld on %d,%d [mult=%d]",
15242 +               (long long)bfree, (long long)broot,
15243 +               *free_blocks, *root_blocks, dli->dl_nrlmult,
15244 +               _file, _line);
15245 +       if (free_blocks) {
15246 +               if (*free_blocks > bfree)
15247 +                       *free_blocks = bfree;
15248 +       }
15249 +       if (root_blocks) {
15250 +               if (*root_blocks > broot)
15251 +                       *root_blocks = broot;
15252 +       }
15253 +       put_dl_info(dli);
15254 +}
15255 +
15256 +#define DLIMIT_ALLOC_SPACE(in, bytes) \
15257 +       __dl_alloc_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
15258 +               __FILE__, __LINE__ )
15259 +
15260 +#define DLIMIT_FREE_SPACE(in, bytes) \
15261 +       __dl_free_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
15262 +               __FILE__, __LINE__ )
15263 +
15264 +#define DLIMIT_ALLOC_BLOCK(in, nr) \
15265 +       __dl_alloc_space((in)->i_sb, (in)->i_tag, \
15266 +               ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
15267 +               __FILE__, __LINE__ )
15268 +
15269 +#define DLIMIT_FREE_BLOCK(in, nr) \
15270 +       __dl_free_space((in)->i_sb, (in)->i_tag, \
15271 +               ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
15272 +               __FILE__, __LINE__ )
15273 +
15274 +
15275 +#define DLIMIT_ALLOC_INODE(in) \
15276 +       __dl_alloc_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
15277 +
15278 +#define DLIMIT_FREE_INODE(in) \
15279 +       __dl_free_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
15280 +
15281 +
15282 +#define DLIMIT_ADJUST_BLOCK(sb, tag, fb, rb) \
15283 +       __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
15284 +
15285 +
15286 +#else
15287 +#warning duplicate inclusion
15288 +#endif
15289 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_limit.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_limit.h
15290 --- linux-2.6.17.11/include/linux/vs_limit.h    1970-01-01 01:00:00 +0100
15291 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_limit.h       2006-07-09 17:07:13 +0200
15292 @@ -0,0 +1,137 @@
15293 +#ifndef _VX_VS_LIMIT_H
15294 +#define _VX_VS_LIMIT_H
15295 +
15296 +#include "vserver/limit.h"
15297 +#include "vserver/debug.h"
15298 +#include "vserver/limit_int.h"
15299 +
15300 +
15301 +#define vx_acc_cres(v,d,p,r) \
15302 +       __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
15303 +
15304 +#define vx_acc_cres_cond(x,d,p,r) \
15305 +       __vx_acc_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \
15306 +       r, d, p, __FILE__, __LINE__)
15307 +
15308 +
15309 +#define vx_add_cres(v,a,p,r) \
15310 +       __vx_add_cres(v, r, a, p, __FILE__, __LINE__)
15311 +#define vx_sub_cres(v,a,p,r)           vx_add_cres(v,-(a),p,r)
15312 +
15313 +#define vx_add_cres_cond(x,a,p,r) \
15314 +       __vx_add_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \
15315 +       r, a, p, __FILE__, __LINE__)
15316 +#define vx_sub_cres_cond(x,a,p,r)      vx_add_cres_cond(x,-(a),p,r)
15317 +
15318 +
15319 +/* process and file limits */
15320 +
15321 +#define vx_nproc_inc(p) \
15322 +       vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
15323 +
15324 +#define vx_nproc_dec(p) \
15325 +       vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
15326 +
15327 +#define vx_files_inc(f) \
15328 +       vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
15329 +
15330 +#define vx_files_dec(f) \
15331 +       vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
15332 +
15333 +#define vx_locks_inc(l) \
15334 +       vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
15335 +
15336 +#define vx_locks_dec(l) \
15337 +       vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
15338 +
15339 +#define vx_openfd_inc(f) \
15340 +       vx_acc_cres(current->vx_info, 1, (void *)(long)(f), VLIMIT_OPENFD)
15341 +
15342 +#define vx_openfd_dec(f) \
15343 +       vx_acc_cres(current->vx_info,-1, (void *)(long)(f), VLIMIT_OPENFD)
15344 +
15345 +
15346 +#define vx_cres_avail(v,n,r) \
15347 +       __vx_cres_avail(v, r, n, __FILE__, __LINE__)
15348 +
15349 +
15350 +#define vx_nproc_avail(n) \
15351 +       vx_cres_avail(current->vx_info, n, RLIMIT_NPROC)
15352 +
15353 +#define vx_files_avail(n) \
15354 +       vx_cres_avail(current->vx_info, n, RLIMIT_NOFILE)
15355 +
15356 +#define vx_locks_avail(n) \
15357 +       vx_cres_avail(current->vx_info, n, RLIMIT_LOCKS)
15358 +
15359 +#define vx_openfd_avail(n) \
15360 +       vx_cres_avail(current->vx_info, n, VLIMIT_OPENFD)
15361 +
15362 +
15363 +/* dentry limits */
15364 +
15365 +#define vx_dentry_inc(d) do {                                          \
15366 +       if (atomic_read(&d->d_count) == 1)                              \
15367 +               vx_acc_cres(current->vx_info, 1, d, VLIMIT_DENTRY);     \
15368 +       } while (0)
15369 +
15370 +#define vx_dentry_dec(d) do {                                          \
15371 +       if (atomic_read(&d->d_count) == 0)                              \
15372 +               vx_acc_cres(current->vx_info,-1, d, VLIMIT_DENTRY);     \
15373 +       } while (0)
15374 +
15375 +#define vx_dentry_avail(n) \
15376 +       vx_cres_avail(current->vx_info, n, VLIMIT_DENTRY)
15377 +
15378 +
15379 +/* socket limits */
15380 +
15381 +#define vx_sock_inc(s) \
15382 +       vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
15383 +
15384 +#define vx_sock_dec(s) \
15385 +       vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
15386 +
15387 +#define vx_sock_avail(n) \
15388 +       vx_cres_avail(current->vx_info, n, VLIMIT_NSOCK)
15389 +
15390 +
15391 +/* ipc resource limits */
15392 +
15393 +#define vx_ipcmsg_add(v,u,a) \
15394 +       vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
15395 +
15396 +#define vx_ipcmsg_sub(v,u,a) \
15397 +       vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
15398 +
15399 +#define vx_ipcmsg_avail(v,a) \
15400 +       vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
15401 +
15402 +
15403 +#define vx_ipcshm_add(v,k,a) \
15404 +       vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
15405 +
15406 +#define vx_ipcshm_sub(v,k,a) \
15407 +       vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
15408 +
15409 +#define vx_ipcshm_avail(v,a) \
15410 +       vx_cres_avail(v, a, VLIMIT_SHMEM)
15411 +
15412 +
15413 +#define vx_semary_inc(a) \
15414 +       vx_acc_cres(current->vx_info, 1, a, VLIMIT_SEMARY)
15415 +
15416 +#define vx_semary_dec(a) \
15417 +       vx_acc_cres(current->vx_info,-1, a, VLIMIT_SEMARY)
15418 +
15419 +
15420 +#define vx_nsems_add(a,n) \
15421 +       vx_add_cres(current->vx_info, n, a, VLIMIT_NSEMS)
15422 +
15423 +#define vx_nsems_sub(a,n) \
15424 +       vx_sub_cres(current->vx_info, n, a, VLIMIT_NSEMS)
15425 +
15426 +
15427 +#else
15428 +#warning duplicate inclusion
15429 +#endif
15430 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_memory.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_memory.h
15431 --- linux-2.6.17.11/include/linux/vs_memory.h   1970-01-01 01:00:00 +0100
15432 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_memory.h      2006-07-09 17:07:13 +0200
15433 @@ -0,0 +1,149 @@
15434 +#ifndef _VX_VS_MEMORY_H
15435 +#define _VX_VS_MEMORY_H
15436 +
15437 +#include "vserver/limit.h"
15438 +#include "vserver/debug.h"
15439 +#include "vserver/limit_int.h"
15440 +
15441 +
15442 +#define __acc_add_long(a,v)    (*(v) += (a))
15443 +#define __acc_inc_long(v)      (++*(v))
15444 +#define __acc_dec_long(v)      (--*(v))
15445 +
15446 +#if    NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
15447 +#define __acc_add_atomic(a,v)  atomic_long_add(a,v)
15448 +#define __acc_inc_atomic(v)    atomic_long_inc(v)
15449 +#define __acc_dec_atomic(v)    atomic_long_dec(v)
15450 +#else  /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
15451 +#define __acc_add_atomic(a,v)  __acc_add_long(a,v)
15452 +#define __acc_inc_atomic(v)    __acc_inc_long(v)
15453 +#define __acc_dec_atomic(v)    __acc_dec_long(v)
15454 +#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
15455 +
15456 +
15457 +#define vx_acc_page(m,d,v,r) do {                                      \
15458 +       if ((d) > 0)                                                    \
15459 +               __acc_inc_long(&(m->v));                                \
15460 +       else                                                            \
15461 +               __acc_dec_long(&(m->v));                                \
15462 +       __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__);      \
15463 +} while (0)
15464 +
15465 +#define vx_acc_page_atomic(m,d,v,r) do {                               \
15466 +       if ((d) > 0)                                                    \
15467 +               __acc_inc_atomic(&(m->v));                              \
15468 +       else                                                            \
15469 +               __acc_dec_atomic(&(m->v));                              \
15470 +       __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__);      \
15471 +} while (0)
15472 +
15473 +
15474 +#define vx_acc_pages(m,p,v,r) do {                                     \
15475 +       unsigned long __p = (p);                                        \
15476 +       __acc_add_long(__p, &(m->v));                                   \
15477 +       __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__);    \
15478 +} while (0)
15479 +
15480 +#define vx_acc_pages_atomic(m,p,v,r) do {                              \
15481 +       unsigned long __p = (p);                                        \
15482 +       __acc_add_atomic(__p, &(m->v));                                 \
15483 +       __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__);    \
15484 +} while (0)
15485 +
15486 +
15487 +
15488 +#define vx_acc_vmpage(m,d) \
15489 +       vx_acc_page(m, d, total_vm,  RLIMIT_AS)
15490 +#define vx_acc_vmlpage(m,d) \
15491 +       vx_acc_page(m, d, locked_vm, RLIMIT_MEMLOCK)
15492 +#define vx_acc_file_rsspage(m,d) \
15493 +       vx_acc_page_atomic(m, d, _file_rss, RLIMIT_RSS)
15494 +#define vx_acc_anon_rsspage(m,d) \
15495 +       vx_acc_page_atomic(m, d, _anon_rss, VLIMIT_ANON)
15496 +
15497 +#define vx_acc_vmpages(m,p) \
15498 +       vx_acc_pages(m, p, total_vm,  RLIMIT_AS)
15499 +#define vx_acc_vmlpages(m,p) \
15500 +       vx_acc_pages(m, p, locked_vm, RLIMIT_MEMLOCK)
15501 +#define vx_acc_file_rsspages(m,p) \
15502 +       vx_acc_pages_atomic(m, p, _file_rss, RLIMIT_RSS)
15503 +#define vx_acc_anon_rsspages(m,p) \
15504 +       vx_acc_pages_atomic(m, p, _anon_rss, VLIMIT_ANON)
15505 +
15506 +#define vx_pages_add(s,r,p)    __vx_add_cres(s, r, p, 0, __FILE__, __LINE__)
15507 +#define vx_pages_sub(s,r,p)    vx_pages_add(s, r, -(p))
15508 +
15509 +#define vx_vmpages_inc(m)              vx_acc_vmpage(m, 1)
15510 +#define vx_vmpages_dec(m)              vx_acc_vmpage(m,-1)
15511 +#define vx_vmpages_add(m,p)            vx_acc_vmpages(m, p)
15512 +#define vx_vmpages_sub(m,p)            vx_acc_vmpages(m,-(p))
15513 +
15514 +#define vx_vmlocked_inc(m)             vx_acc_vmlpage(m, 1)
15515 +#define vx_vmlocked_dec(m)             vx_acc_vmlpage(m,-1)
15516 +#define vx_vmlocked_add(m,p)           vx_acc_vmlpages(m, p)
15517 +#define vx_vmlocked_sub(m,p)           vx_acc_vmlpages(m,-(p))
15518 +
15519 +#define vx_file_rsspages_inc(m)                vx_acc_file_rsspage(m, 1)
15520 +#define vx_file_rsspages_dec(m)                vx_acc_file_rsspage(m,-1)
15521 +#define vx_file_rsspages_add(m,p)      vx_acc_file_rsspages(m, p)
15522 +#define vx_file_rsspages_sub(m,p)      vx_acc_file_rsspages(m,-(p))
15523 +
15524 +#define vx_anon_rsspages_inc(m)                vx_acc_anon_rsspage(m, 1)
15525 +#define vx_anon_rsspages_dec(m)                vx_acc_anon_rsspage(m,-1)
15526 +#define vx_anon_rsspages_add(m,p)      vx_acc_anon_rsspages(m, p)
15527 +#define vx_anon_rsspages_sub(m,p)      vx_acc_anon_rsspages(m,-(p))
15528 +
15529 +
15530 +#define vx_pages_avail(m,p,r) \
15531 +       __vx_cres_avail((m)->mm_vx_info, r, p, __FILE__, __LINE__)
15532 +
15533 +#define vx_vmpages_avail(m,p)  vx_pages_avail(m, p, RLIMIT_AS)
15534 +#define vx_vmlocked_avail(m,p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)
15535 +#define vx_rsspages_avail(m,p) vx_pages_avail(m, p, RLIMIT_RSS)
15536 +#define vx_anonpages_avail(m,p)        vx_pages_avail(m, p, VLIMIT_ANON)
15537 +
15538 +enum {
15539 +       VXPT_UNKNOWN = 0,
15540 +       VXPT_ANON,
15541 +       VXPT_NONE,
15542 +       VXPT_FILE,
15543 +       VXPT_SWAP,
15544 +       VXPT_WRITE
15545 +};
15546 +
15547 +#if 0
15548 +#define        vx_page_fault(mm,vma,type,ret)
15549 +#else
15550 +
15551 +static inline
15552 +void __vx_page_fault(struct mm_struct *mm,
15553 +       struct vm_area_struct *vma, int type, int ret)
15554 +{
15555 +       struct vx_info *vxi = mm->mm_vx_info;
15556 +       int what;
15557 +/*
15558 +       static char *page_type[6] =
15559 +               { "UNKNOWN", "ANON","NONE", "FILE", "SWAP", "WRITE" };
15560 +       static char *page_what[4] =
15561 +               { "FAULT_OOM", "FAULT_SIGBUS", "FAULT_MINOR", "FAULT_MAJOR" };
15562 +*/
15563 +
15564 +       if (!vxi)
15565 +               return;
15566 +
15567 +       what = (ret & 0x3);
15568 +
15569 +/*     printk("[%d] page[%d][%d] %2x %s %s\n", vxi->vx_id,
15570 +               type, what, ret, page_type[type], page_what[what]);
15571 +*/
15572 +       if (ret & VM_FAULT_WRITE)
15573 +               what |= 0x4;
15574 +       atomic_inc(&vxi->cacct.page[type][what]);
15575 +}
15576 +
15577 +#define        vx_page_fault(mm,vma,type,ret)  __vx_page_fault(mm,vma,type,ret)
15578 +#endif
15579 +
15580 +#else
15581 +#warning duplicate inclusion
15582 +#endif
15583 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_network.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_network.h
15584 --- linux-2.6.17.11/include/linux/vs_network.h  1970-01-01 01:00:00 +0100
15585 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_network.h     2006-07-09 17:07:13 +0200
15586 @@ -0,0 +1,244 @@
15587 +#ifndef _NX_VS_NETWORK_H
15588 +#define _NX_VS_NETWORK_H
15589 +
15590 +#include "vserver/network.h"
15591 +#include "vserver/debug.h"
15592 +
15593 +
15594 +#define get_nx_info(i) __get_nx_info(i,__FILE__,__LINE__)
15595 +
15596 +static inline struct nx_info *__get_nx_info(struct nx_info *nxi,
15597 +       const char *_file, int _line)
15598 +{
15599 +       if (!nxi)
15600 +               return NULL;
15601 +
15602 +       vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
15603 +               nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0,
15604 +               _file, _line);
15605 +
15606 +       atomic_inc(&nxi->nx_usecnt);
15607 +       return nxi;
15608 +}
15609 +
15610 +
15611 +extern void free_nx_info(struct nx_info *);
15612 +
15613 +#define put_nx_info(i) __put_nx_info(i,__FILE__,__LINE__)
15614 +
15615 +static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
15616 +{
15617 +       if (!nxi)
15618 +               return;
15619 +
15620 +       vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
15621 +               nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0,
15622 +               _file, _line);
15623 +
15624 +       if (atomic_dec_and_test(&nxi->nx_usecnt))
15625 +               free_nx_info(nxi);
15626 +}
15627 +
15628 +
15629 +#define init_nx_info(p,i) __init_nx_info(p,i,__FILE__,__LINE__)
15630 +
15631 +static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
15632 +               const char *_file, int _line)
15633 +{
15634 +       if (nxi) {
15635 +               vxlprintk(VXD_CBIT(nid, 3),
15636 +                       "init_nx_info(%p[#%d.%d])",
15637 +                       nxi, nxi?nxi->nx_id:0,
15638 +                       nxi?atomic_read(&nxi->nx_usecnt):0,
15639 +                       _file, _line);
15640 +
15641 +               atomic_inc(&nxi->nx_usecnt);
15642 +       }
15643 +       *nxp = nxi;
15644 +}
15645 +
15646 +
15647 +#define set_nx_info(p,i) __set_nx_info(p,i,__FILE__,__LINE__)
15648 +
15649 +static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
15650 +       const char *_file, int _line)
15651 +{
15652 +       struct nx_info *nxo;
15653 +
15654 +       if (!nxi)
15655 +               return;
15656 +
15657 +       vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
15658 +               nxi, nxi?nxi->nx_id:0,
15659 +               nxi?atomic_read(&nxi->nx_usecnt):0,
15660 +               _file, _line);
15661 +
15662 +       atomic_inc(&nxi->nx_usecnt);
15663 +       nxo = xchg(nxp, nxi);
15664 +       BUG_ON(nxo);
15665 +}
15666 +
15667 +#define clr_nx_info(p) __clr_nx_info(p,__FILE__,__LINE__)
15668 +
15669 +static inline void __clr_nx_info(struct nx_info **nxp,
15670 +       const char *_file, int _line)
15671 +{
15672 +       struct nx_info *nxo;
15673 +
15674 +       nxo = xchg(nxp, NULL);
15675 +       if (!nxo)
15676 +               return;
15677 +
15678 +       vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
15679 +               nxo, nxo?nxo->nx_id:0,
15680 +               nxo?atomic_read(&nxo->nx_usecnt):0,
15681 +               _file, _line);
15682 +
15683 +       if (atomic_dec_and_test(&nxo->nx_usecnt))
15684 +               free_nx_info(nxo);
15685 +}
15686 +
15687 +
15688 +#define claim_nx_info(v,p) __claim_nx_info(v,p,__FILE__,__LINE__)
15689 +
15690 +static inline void __claim_nx_info(struct nx_info *nxi,
15691 +       struct task_struct *task, const char *_file, int _line)
15692 +{
15693 +       vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
15694 +               nxi, nxi?nxi->nx_id:0,
15695 +               nxi?atomic_read(&nxi->nx_usecnt):0,
15696 +               nxi?atomic_read(&nxi->nx_tasks):0,
15697 +               task, _file, _line);
15698 +
15699 +       atomic_inc(&nxi->nx_tasks);
15700 +}
15701 +
15702 +
15703 +extern void unhash_nx_info(struct nx_info *);
15704 +
15705 +#define release_nx_info(v,p) __release_nx_info(v,p,__FILE__,__LINE__)
15706 +
15707 +static inline void __release_nx_info(struct nx_info *nxi,
15708 +       struct task_struct *task, const char *_file, int _line)
15709 +{
15710 +       vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
15711 +               nxi, nxi?nxi->nx_id:0,
15712 +               nxi?atomic_read(&nxi->nx_usecnt):0,
15713 +               nxi?atomic_read(&nxi->nx_tasks):0,
15714 +               task, _file, _line);
15715 +
15716 +       might_sleep();
15717 +
15718 +       if (atomic_dec_and_test(&nxi->nx_tasks))
15719 +               unhash_nx_info(nxi);
15720 +}
15721 +
15722 +
15723 +#define task_get_nx_info(i)    __task_get_nx_info(i,__FILE__,__LINE__)
15724 +
15725 +static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
15726 +       const char *_file, int _line)
15727 +{
15728 +       struct nx_info *nxi;
15729 +
15730 +       task_lock(p);
15731 +       vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
15732 +               p, _file, _line);
15733 +       nxi = __get_nx_info(p->nx_info, _file, _line);
15734 +       task_unlock(p);
15735 +       return nxi;
15736 +}
15737 +
15738 +
15739 +#define nx_task_nid(t) ((t)->nid)
15740 +
15741 +#define nx_current_nid() nx_task_nid(current)
15742 +
15743 +#define nx_check(c,m)  __nx_check(nx_current_nid(),c,m)
15744 +
15745 +#define nx_weak_check(c,m)     ((m) ? nx_check(c,m) : 1)
15746 +
15747 +
15748 +/*
15749 + * check current context for ADMIN/WATCH and
15750 + * optionally against supplied argument
15751 + */
15752 +static inline int __nx_check(nid_t cid, nid_t id, unsigned int mode)
15753 +{
15754 +       if (mode & NX_ARG_MASK) {
15755 +               if ((mode & NX_IDENT) &&
15756 +                       (id == cid))
15757 +                       return 1;
15758 +       }
15759 +       if (mode & NX_ATR_MASK) {
15760 +               if ((mode & NX_DYNAMIC) &&
15761 +                       (id >= MIN_D_CONTEXT) &&
15762 +                       (id <= MAX_S_CONTEXT))
15763 +                       return 1;
15764 +               if ((mode & NX_STATIC) &&
15765 +                       (id > 1) && (id < MIN_D_CONTEXT))
15766 +                       return 1;
15767 +       }
15768 +       return (((mode & NX_ADMIN) && (cid == 0)) ||
15769 +               ((mode & NX_WATCH) && (cid == 1)) ||
15770 +               ((mode & NX_BLEND) && (id == 1)) ||
15771 +               ((mode & NX_HOSTID) && (id == 0)));
15772 +}
15773 +
15774 +
15775 +#define __nx_state(v)  ((v) ? ((v)->nx_state) : 0)
15776 +
15777 +#define nx_info_state(v,m)     (__nx_state(v) & (m))
15778 +
15779 +
15780 +#define __nx_flags(v)  ((v) ? (v)->nx_flags : 0)
15781 +
15782 +#define nx_current_flags()     __nx_flags(current->nx_info)
15783 +
15784 +#define nx_info_flags(v,m,f) \
15785 +       vx_check_flags(__nx_flags(v),(m),(f))
15786 +
15787 +#define task_nx_flags(t,m,f) \
15788 +       ((t) && nx_info_flags((t)->nx_info, (m), (f)))
15789 +
15790 +#define nx_flags(m,f)  nx_info_flags(current->nx_info,(m),(f))
15791 +
15792 +
15793 +/* context caps */
15794 +
15795 +#define __nx_ncaps(v)  ((v) ? (v)->nx_ncaps : 0)
15796 +
15797 +#define nx_current_ncaps()     __nx_ncaps(current->nx_info)
15798 +
15799 +#define nx_info_ncaps(v,c)     (__nx_ncaps(v) & (c))
15800 +
15801 +#define nx_ncaps(c)    nx_info_ncaps(current->nx_info,(c))
15802 +
15803 +
15804 +static inline int addr_in_nx_info(struct nx_info *nxi, uint32_t addr)
15805 +{
15806 +       int n,i;
15807 +
15808 +       if (!nxi)
15809 +               return 1;
15810 +
15811 +       n = nxi->nbipv4;
15812 +       if (n && (nxi->ipv4[0] == 0))
15813 +               return 1;
15814 +       for (i=0; i<n; i++) {
15815 +               if (nxi->ipv4[i] == addr)
15816 +                       return 1;
15817 +       }
15818 +       return 0;
15819 +}
15820 +
15821 +static inline void exit_nx_info(struct task_struct *p)
15822 +{
15823 +       if (p->nx_info)
15824 +               release_nx_info(p->nx_info, p);
15825 +}
15826 +
15827 +
15828 +#else
15829 +#warning duplicate inclusion
15830 +#endif
15831 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_pid.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_pid.h
15832 --- linux-2.6.17.11/include/linux/vs_pid.h      1970-01-01 01:00:00 +0100
15833 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_pid.h 2006-07-09 17:07:13 +0200
15834 @@ -0,0 +1,57 @@
15835 +#ifndef _VX_VS_PID_H
15836 +#define _VX_VS_PID_H
15837 +
15838 +#include "vserver/debug.h"
15839 +
15840 +
15841 +/* pid faking stuff */
15842 +
15843 +
15844 +#define vx_info_map_pid(v,p) \
15845 +       __vx_info_map_pid((v), (p), __FUNC__, __FILE__, __LINE__)
15846 +#define vx_info_map_tgid(v,p)  vx_info_map_pid(v,p)
15847 +#define vx_map_pid(p)  vx_info_map_pid(current->vx_info, p)
15848 +#define vx_map_tgid(p) vx_map_pid(p)
15849 +
15850 +static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
15851 +       const char *func, const char *file, int line)
15852 +{
15853 +       if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
15854 +               vxfprintk(VXD_CBIT(cvirt, 2),
15855 +                       "vx_map_tgid: %p/%llx: %d -> %d",
15856 +                       vxi, (long long)vxi->vx_flags, pid,
15857 +                       (pid && pid == vxi->vx_initpid)?1:pid,
15858 +                       func, file, line);
15859 +               if (pid == 0)
15860 +                       return 0;
15861 +               if (pid == vxi->vx_initpid)
15862 +                       return 1;
15863 +       }
15864 +       return pid;
15865 +}
15866 +
15867 +#define vx_info_rmap_pid(v,p) \
15868 +       __vx_info_rmap_pid((v), (p), __FUNC__, __FILE__, __LINE__)
15869 +#define vx_rmap_pid(p) vx_info_rmap_pid(current->vx_info, p)
15870 +#define vx_rmap_tgid(p) vx_rmap_pid(p)
15871 +
15872 +static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
15873 +       const char *func, const char *file, int line)
15874 +{
15875 +       if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
15876 +               vxfprintk(VXD_CBIT(cvirt, 2),
15877 +                       "vx_rmap_tgid: %p/%llx: %d -> %d",
15878 +                       vxi, (long long)vxi->vx_flags, pid,
15879 +                       (pid == 1)?vxi->vx_initpid:pid,
15880 +                       func, file, line);
15881 +               if ((pid == 1) && vxi->vx_initpid)
15882 +                       return vxi->vx_initpid;
15883 +               if (pid == vxi->vx_initpid)
15884 +                       return ~0U;
15885 +       }
15886 +       return pid;
15887 +}
15888 +
15889 +#else
15890 +#warning duplicate inclusion
15891 +#endif
15892 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_sched.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_sched.h
15893 --- linux-2.6.17.11/include/linux/vs_sched.h    1970-01-01 01:00:00 +0100
15894 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_sched.h       2006-07-09 17:07:13 +0200
15895 @@ -0,0 +1,107 @@
15896 +#ifndef _VX_VS_SCHED_H
15897 +#define _VX_VS_SCHED_H
15898 +
15899 +#include "vserver/sched.h"
15900 +
15901 +
15902 +#define VAVAVOOM_RATIO          50
15903 +
15904 +#define MAX_PRIO_BIAS           20
15905 +#define MIN_PRIO_BIAS          -20
15906 +
15907 +
15908 +#ifdef CONFIG_VSERVER_HARDCPU
15909 +
15910 +/*
15911 + * effective_prio - return the priority that is based on the static
15912 + * priority but is modified by bonuses/penalties.
15913 + *
15914 + * We scale the actual sleep average [0 .... MAX_SLEEP_AVG]
15915 + * into a -4 ... 0 ... +4 bonus/penalty range.
15916 + *
15917 + * Additionally, we scale another amount based on the number of
15918 + * CPU tokens currently held by the context, if the process is
15919 + * part of a context (and the appropriate SCHED flag is set).
15920 + * This ranges from -5 ... 0 ... +15, quadratically.
15921 + *
15922 + * So, the total bonus is -9 .. 0 .. +19
15923 + * We use ~50% of the full 0...39 priority range so that:
15924 + *
15925 + * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs.
15926 + * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks.
15927 + *    unless that context is far exceeding its CPU allocation.
15928 + *
15929 + * Both properties are important to certain workloads.
15930 + */
15931 +static inline
15932 +int vx_effective_vavavoom(struct _vx_sched_pc *sched_pc, int max_prio)
15933 +{
15934 +       int vavavoom, max;
15935 +
15936 +       /* lots of tokens = lots of vavavoom
15937 +        *      no tokens = no vavavoom      */
15938 +       if ((vavavoom = sched_pc->tokens) >= 0) {
15939 +               max = sched_pc->tokens_max;
15940 +               vavavoom = max - vavavoom;
15941 +               max = max * max;
15942 +               vavavoom = max_prio * VAVAVOOM_RATIO / 100
15943 +                       * (vavavoom*vavavoom - (max >> 2)) / max;
15944 +               return vavavoom;
15945 +       }
15946 +       return 0;
15947 +}
15948 +
15949 +
15950 +static inline
15951 +int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
15952 +{
15953 +       struct vx_info *vxi = p->vx_info;
15954 +
15955 +       if (!vxi)
15956 +               return prio;
15957 +
15958 +       if (vx_info_flags(vxi, VXF_SCHED_PRIO, 0)) {
15959 +               struct _vx_sched_pc *sched_pc = &vx_cpu(vxi, sched_pc);
15960 +               int vavavoom = vx_effective_vavavoom(sched_pc, max_user);
15961 +
15962 +               vxi->sched.vavavoom = vavavoom;
15963 +               prio += vavavoom;
15964 +       }
15965 +       prio += vxi->sched.prio_bias;
15966 +       return prio;
15967 +}
15968 +
15969 +#else /* !CONFIG_VSERVER_HARDCPU */
15970 +
15971 +static inline
15972 +int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
15973 +{
15974 +       struct vx_info *vxi = p->vx_info;
15975 +
15976 +       if (vxi)
15977 +               prio += vxi->sched.prio_bias;
15978 +       return prio;
15979 +}
15980 +
15981 +#endif /* CONFIG_VSERVER_HARDCPU */
15982 +
15983 +
15984 +static inline void vx_account_user(struct vx_info *vxi,
15985 +       cputime_t cputime, int nice)
15986 +{
15987 +       if (!vxi)
15988 +               return;
15989 +       vx_cpu(vxi, sched_pc).user_ticks += cputime;
15990 +}
15991 +
15992 +static inline void vx_account_system(struct vx_info *vxi,
15993 +       cputime_t cputime, int idle)
15994 +{
15995 +       if (!vxi)
15996 +               return;
15997 +       vx_cpu(vxi, sched_pc).sys_ticks += cputime;
15998 +}
15999 +
16000 +#else
16001 +#warning duplicate inclusion
16002 +#endif
16003 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_socket.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_socket.h
16004 --- linux-2.6.17.11/include/linux/vs_socket.h   1970-01-01 01:00:00 +0100
16005 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_socket.h      2006-08-19 03:12:48 +0200
16006 @@ -0,0 +1,64 @@
16007 +#ifndef _VX_VS_SOCKET_H
16008 +#define _VX_VS_SOCKET_H
16009 +
16010 +#include "vserver/debug.h"
16011 +
16012 +
16013 +/* socket accounting */
16014 +
16015 +#include <linux/socket.h>
16016 +
16017 +static inline int vx_sock_type(int family)
16018 +{
16019 +       switch (family) {
16020 +       case PF_UNSPEC:
16021 +               return VXA_SOCK_UNSPEC;
16022 +       case PF_UNIX:
16023 +               return VXA_SOCK_UNIX;
16024 +       case PF_INET:
16025 +               return VXA_SOCK_INET;
16026 +       case PF_INET6:
16027 +               return VXA_SOCK_INET6;
16028 +       case PF_PACKET:
16029 +               return VXA_SOCK_PACKET;
16030 +       default:
16031 +               return VXA_SOCK_OTHER;
16032 +       }
16033 +}
16034 +
16035 +#define vx_acc_sock(v,f,p,s) \
16036 +       __vx_acc_sock((v), (f), (p), (s), __FILE__, __LINE__)
16037 +
16038 +static inline void __vx_acc_sock(struct vx_info *vxi,
16039 +       int family, int pos, int size, char *file, int line)
16040 +{
16041 +       if (vxi) {
16042 +               int type = vx_sock_type(family);
16043 +
16044 +               atomic_inc(&vxi->cacct.sock[type][pos].count);
16045 +               atomic_add(size, &vxi->cacct.sock[type][pos].total);
16046 +       }
16047 +}
16048 +
16049 +#define vx_sock_recv(sk,s) \
16050 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, (s))
16051 +#define vx_sock_send(sk,s) \
16052 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, (s))
16053 +#define vx_sock_fail(sk,s) \
16054 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, (s))
16055 +
16056 +
16057 +#define sock_vx_init(s) do {           \
16058 +       (s)->sk_xid = 0;                \
16059 +       (s)->sk_vx_info = NULL;         \
16060 +       } while (0)
16061 +
16062 +#define sock_nx_init(s) do {           \
16063 +       (s)->sk_nid = 0;                \
16064 +       (s)->sk_nx_info = NULL;         \
16065 +       } while (0)
16066 +
16067 +
16068 +#else
16069 +#warning duplicate inclusion
16070 +#endif
16071 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_tag.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_tag.h
16072 --- linux-2.6.17.11/include/linux/vs_tag.h      1970-01-01 01:00:00 +0100
16073 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_tag.h 2006-07-09 17:07:13 +0200
16074 @@ -0,0 +1,45 @@
16075 +#ifndef _VX_VS_TAG_H
16076 +#define _VX_VS_TAG_H
16077 +
16078 +#include <linux/kernel.h>
16079 +#include <linux/vserver/tag.h>
16080 +
16081 +/* check conditions */
16082 +
16083 +#define DX_ADMIN       0x0001
16084 +#define DX_WATCH       0x0002
16085 +#define DX_HOSTID      0x0008
16086 +
16087 +#define DX_IDENT       0x0010
16088 +
16089 +#define DX_ARG_MASK    0x0010
16090 +
16091 +
16092 +#define dx_task_tag(t) ((t)->xid)
16093 +
16094 +#define dx_current_tag() dx_task_tag(current)
16095 +
16096 +#define dx_check(c,m)  __dx_check(dx_current_tag(),c,m)
16097 +
16098 +#define dx_weak_check(c,m)     ((m) ? dx_check(c,m) : 1)
16099 +
16100 +
16101 +/*
16102 + * check current context for ADMIN/WATCH and
16103 + * optionally against supplied argument
16104 + */
16105 +static inline int __dx_check(tag_t cid, tag_t id, unsigned int mode)
16106 +{
16107 +       if (mode & DX_ARG_MASK) {
16108 +               if ((mode & DX_IDENT) &&
16109 +                       (id == cid))
16110 +                       return 1;
16111 +       }
16112 +       return (((mode & DX_ADMIN) && (cid == 0)) ||
16113 +               ((mode & DX_WATCH) && (cid == 1)) ||
16114 +               ((mode & DX_HOSTID) && (id == 0)));
16115 +}
16116 +
16117 +#else
16118 +#warning duplicate inclusion
16119 +#endif
16120 diff -NurpP --minimal linux-2.6.17.11/include/linux/vs_time.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_time.h
16121 --- linux-2.6.17.11/include/linux/vs_time.h     1970-01-01 01:00:00 +0100
16122 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vs_time.h        2006-07-09 17:07:13 +0200
16123 @@ -0,0 +1,19 @@
16124 +#ifndef _VX_VS_TIME_H
16125 +#define _VX_VS_TIME_H
16126 +
16127 +
16128 +/* time faking stuff */
16129 +
16130 +#ifdef CONFIG_VSERVER_VTIME
16131 +
16132 +extern void vx_gettimeofday(struct timeval *tv);
16133 +extern int vx_settimeofday(struct timespec *ts);
16134 +
16135 +#else
16136 +#define        vx_gettimeofday(t)      do_gettimeofday(t)
16137 +#define        vx_settimeofday(t)      do_settimeofday(t)
16138 +#endif
16139 +
16140 +#else
16141 +#warning duplicate inclusion
16142 +#endif
16143 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/cacct.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cacct.h
16144 --- linux-2.6.17.11/include/linux/vserver/cacct.h       1970-01-01 01:00:00 +0100
16145 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cacct.h  2006-08-19 16:25:15 +0200
16146 @@ -0,0 +1,15 @@
16147 +#ifndef _VX_CACCT_H
16148 +#define _VX_CACCT_H
16149 +
16150 +
16151 +enum sock_acc_field {
16152 +       VXA_SOCK_UNSPEC = 0,
16153 +       VXA_SOCK_UNIX,
16154 +       VXA_SOCK_INET,
16155 +       VXA_SOCK_INET6,
16156 +       VXA_SOCK_PACKET,
16157 +       VXA_SOCK_OTHER,
16158 +       VXA_SOCK_SIZE   /* array size */
16159 +};
16160 +
16161 +#endif /* _VX_CACCT_H */
16162 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/cacct_cmd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cacct_cmd.h
16163 --- linux-2.6.17.11/include/linux/vserver/cacct_cmd.h   1970-01-01 01:00:00 +0100
16164 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cacct_cmd.h      2006-08-19 03:37:21 +0200
16165 @@ -0,0 +1,23 @@
16166 +#ifndef _VX_CACCT_CMD_H
16167 +#define _VX_CACCT_CMD_H
16168 +
16169 +
16170 +/* virtual host info name commands */
16171 +
16172 +#define VCMD_sock_stat         VC_CMD(VSTAT, 5, 0)
16173 +
16174 +struct vcmd_sock_stat_v0 {
16175 +       uint32_t field;
16176 +       uint32_t count[3];
16177 +       uint64_t total[3];
16178 +};
16179 +
16180 +
16181 +#ifdef __KERNEL__
16182 +
16183 +#include <linux/compiler.h>
16184 +
16185 +extern int vc_sock_stat(struct vx_info *, void __user *);
16186 +
16187 +#endif /* __KERNEL__ */
16188 +#endif /* _VX_CACCT_CMD_H */
16189 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/cacct_def.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cacct_def.h
16190 --- linux-2.6.17.11/include/linux/vserver/cacct_def.h   1970-01-01 01:00:00 +0100
16191 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cacct_def.h      2006-08-19 16:25:46 +0200
16192 @@ -0,0 +1,43 @@
16193 +#ifndef _VX_CACCT_DEF_H
16194 +#define _VX_CACCT_DEF_H
16195 +
16196 +#include <asm/atomic.h>
16197 +#include <linux/vserver/cacct.h>
16198 +
16199 +
16200 +struct _vx_sock_acc {
16201 +       atomic_t count;
16202 +       atomic_t total;
16203 +};
16204 +
16205 +/* context sub struct */
16206 +
16207 +struct _vx_cacct {
16208 +       struct _vx_sock_acc sock[VXA_SOCK_SIZE][3];
16209 +       atomic_t slab[8];
16210 +       atomic_t page[6][8];
16211 +};
16212 +
16213 +#ifdef CONFIG_VSERVER_DEBUG
16214 +
16215 +static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
16216 +{
16217 +       int i,j;
16218 +
16219 +       printk("\t_vx_cacct:");
16220 +       for (i=0; i<6; i++) {
16221 +               struct _vx_sock_acc *ptr = cacct->sock[i];
16222 +
16223 +               printk("\t [%d] =", i);
16224 +               for (j=0; j<3; j++) {
16225 +                       printk(" [%d] = %8d, %8d", j,
16226 +                               atomic_read(&ptr[j].count),
16227 +                               atomic_read(&ptr[j].total));
16228 +               }
16229 +               printk("\n");
16230 +       }
16231 +}
16232 +
16233 +#endif
16234 +
16235 +#endif /* _VX_CACCT_DEF_H */
16236 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/cacct_int.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cacct_int.h
16237 --- linux-2.6.17.11/include/linux/vserver/cacct_int.h   1970-01-01 01:00:00 +0100
16238 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cacct_int.h      2006-08-19 03:49:15 +0200
16239 @@ -0,0 +1,21 @@
16240 +#ifndef _VX_CACCT_INT_H
16241 +#define _VX_CACCT_INT_H
16242 +
16243 +
16244 +#ifdef __KERNEL__
16245 +
16246 +static inline
16247 +unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos)
16248 +{
16249 +       return atomic_read(&cacct->sock[type][pos].count);
16250 +}
16251 +
16252 +
16253 +static inline
16254 +unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos)
16255 +{
16256 +       return atomic_read(&cacct->sock[type][pos].total);
16257 +}
16258 +
16259 +#endif /* __KERNEL__ */
16260 +#endif /* _VX_CACCT_INT_H */
16261 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/context.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/context.h
16262 --- linux-2.6.17.11/include/linux/vserver/context.h     1970-01-01 01:00:00 +0100
16263 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/context.h        2006-08-26 00:46:41 +0200
16264 @@ -0,0 +1,219 @@
16265 +#ifndef _VX_CONTEXT_H
16266 +#define _VX_CONTEXT_H
16267 +
16268 +#include <linux/types.h>
16269 +#include <linux/capability.h>
16270 +
16271 +
16272 +#define MAX_S_CONTEXT  65535   /* Arbitrary limit */
16273 +
16274 +#ifdef CONFIG_VSERVER_DYNAMIC_IDS
16275 +#define MIN_D_CONTEXT  49152   /* dynamic contexts start here */
16276 +#else
16277 +#define MIN_D_CONTEXT  65536
16278 +#endif
16279 +
16280 +#define VX_DYNAMIC_ID  ((uint32_t)-1)          /* id for dynamic context */
16281 +
16282 +/* context flags */
16283 +
16284 +#define VXF_INFO_LOCK          0x00000001
16285 +#define VXF_INFO_SCHED         0x00000002
16286 +#define VXF_INFO_NPROC         0x00000004
16287 +#define VXF_INFO_PRIVATE       0x00000008
16288 +
16289 +#define VXF_INFO_INIT          0x00000010
16290 +#define VXF_INFO_HIDE          0x00000020
16291 +#define VXF_INFO_ULIMIT                0x00000040
16292 +#define VXF_INFO_NSPACE                0x00000080
16293 +
16294 +#define VXF_SCHED_HARD         0x00000100
16295 +#define VXF_SCHED_PRIO         0x00000200
16296 +#define VXF_SCHED_PAUSE                0x00000400
16297 +
16298 +#define VXF_VIRT_MEM           0x00010000
16299 +#define VXF_VIRT_UPTIME                0x00020000
16300 +#define VXF_VIRT_CPU           0x00040000
16301 +#define VXF_VIRT_LOAD          0x00080000
16302 +#define VXF_VIRT_TIME          0x00100000
16303 +
16304 +#define VXF_HIDE_MOUNT         0x01000000
16305 +#define VXF_HIDE_NETIF         0x02000000
16306 +#define VXF_HIDE_VINFO         0x04000000
16307 +
16308 +#define VXF_STATE_SETUP                (1ULL<<32)
16309 +#define VXF_STATE_INIT         (1ULL<<33)
16310 +#define VXF_STATE_ADMIN                (1ULL<<34)
16311 +
16312 +#define VXF_SC_HELPER          (1ULL<<36)
16313 +#define VXF_REBOOT_KILL                (1ULL<<37)
16314 +#define VXF_PERSISTENT         (1ULL<<38)
16315 +
16316 +#define VXF_FORK_RSS           (1ULL<<48)
16317 +#define VXF_PROLIFIC           (1ULL<<49)
16318 +
16319 +#define VXF_IGNEG_NICE         (1ULL<<52)
16320 +
16321 +#define VXF_ONE_TIME           (0x0007ULL<<32)
16322 +
16323 +#define VXF_INIT_SET           (VXF_STATE_SETUP|VXF_STATE_INIT|VXF_STATE_ADMIN)
16324 +
16325 +
16326 +/* context migration */
16327 +
16328 +#define VXM_SET_INIT           0x00000001
16329 +#define VXM_SET_REAPER         0x00000002
16330 +
16331 +/* context caps */
16332 +
16333 +#define VXC_CAP_MASK           0x00000000
16334 +
16335 +#define VXC_SET_UTSNAME                0x00000001
16336 +#define VXC_SET_RLIMIT         0x00000002
16337 +
16338 +#define VXC_RAW_ICMP           0x00000100
16339 +#define VXC_SYSLOG             0x00001000
16340 +
16341 +#define VXC_SECURE_MOUNT       0x00010000
16342 +#define VXC_SECURE_REMOUNT     0x00020000
16343 +#define VXC_BINARY_MOUNT       0x00040000
16344 +
16345 +#define VXC_QUOTA_CTL          0x00100000
16346 +#define VXC_ADMIN_MAPPER       0x00200000
16347 +#define VXC_ADMIN_CLOOP                0x00400000
16348 +
16349 +
16350 +/* context state changes */
16351 +
16352 +enum {
16353 +       VSC_STARTUP = 1,
16354 +       VSC_SHUTDOWN,
16355 +
16356 +       VSC_NETUP,
16357 +       VSC_NETDOWN,
16358 +};
16359 +
16360 +
16361 +#ifdef __KERNEL__
16362 +
16363 +#include <linux/list.h>
16364 +#include <linux/spinlock.h>
16365 +#include <linux/rcupdate.h>
16366 +
16367 +#include "limit_def.h"
16368 +#include "sched_def.h"
16369 +#include "cvirt_def.h"
16370 +#include "cacct_def.h"
16371 +
16372 +struct _vx_info_pc {
16373 +       struct _vx_sched_pc sched_pc;
16374 +       struct _vx_cvirt_pc cvirt_pc;
16375 +};
16376 +
16377 +struct vx_info {
16378 +       struct hlist_node vx_hlist;             /* linked list of contexts */
16379 +       xid_t vx_id;                            /* context id */
16380 +       atomic_t vx_usecnt;                     /* usage count */
16381 +       atomic_t vx_tasks;                      /* tasks count */
16382 +       struct vx_info *vx_parent;              /* parent context */
16383 +       int vx_state;                           /* context state */
16384 +
16385 +       struct namespace *vx_namespace;         /* private namespace */
16386 +       struct fs_struct *vx_fs;                /* private namespace fs */
16387 +       uint64_t vx_flags;                      /* context flags */
16388 +       uint64_t vx_bcaps;                      /* bounding caps (system) */
16389 +       uint64_t vx_ccaps;                      /* context caps (vserver) */
16390 +       kernel_cap_t vx_cap_bset;               /* the guest's bset */
16391 +
16392 +       struct task_struct *vx_reaper;          /* guest reaper process */
16393 +       pid_t vx_initpid;                       /* PID of guest init */
16394 +
16395 +       struct _vx_limit limit;                 /* vserver limits */
16396 +       struct _vx_sched sched;                 /* vserver scheduler */
16397 +       struct _vx_cvirt cvirt;                 /* virtual/bias stuff */
16398 +       struct _vx_cacct cacct;                 /* context accounting */
16399 +
16400 +#ifndef CONFIG_SMP
16401 +       struct _vx_info_pc info_pc;             /* per cpu data */
16402 +#else
16403 +       struct _vx_info_pc *ptr_pc;             /* per cpu array */
16404 +#endif
16405 +
16406 +       wait_queue_head_t vx_wait;              /* context exit waitqueue */
16407 +       int reboot_cmd;                         /* last sys_reboot() cmd */
16408 +       int exit_code;                          /* last process exit code */
16409 +
16410 +       char vx_name[65];                       /* vserver name */
16411 +};
16412 +
16413 +#ifndef CONFIG_SMP
16414 +#define        vx_ptr_pc(vxi)          (&(vxi)->info_pc)
16415 +#define        vx_per_cpu(vxi, v, id)  vx_ptr_pc(vxi)->v
16416 +#else
16417 +#define        vx_ptr_pc(vxi)          ((vxi)->ptr_pc)
16418 +#define        vx_per_cpu(vxi, v, id)  per_cpu_ptr(vx_ptr_pc(vxi), id)->v
16419 +#endif
16420 +
16421 +#define        vx_cpu(vxi, v)          vx_per_cpu(vxi, v, smp_processor_id())
16422 +
16423 +
16424 +struct vx_info_save {
16425 +       struct vx_info *vxi;
16426 +       xid_t xid;
16427 +};
16428 +
16429 +
16430 +/* status flags */
16431 +
16432 +#define VXS_HASHED     0x0001
16433 +#define VXS_PAUSED     0x0010
16434 +#define VXS_SHUTDOWN   0x0100
16435 +#define VXS_HELPER     0x1000
16436 +#define VXS_RELEASED   0x8000
16437 +
16438 +/* check conditions */
16439 +
16440 +#define VX_ADMIN       0x0001
16441 +#define VX_WATCH       0x0002
16442 +#define VX_HIDE                0x0004
16443 +#define VX_HOSTID      0x0008
16444 +
16445 +#define VX_IDENT       0x0010
16446 +#define VX_EQUIV       0x0020
16447 +#define VX_PARENT      0x0040
16448 +#define VX_CHILD       0x0080
16449 +
16450 +#define VX_ARG_MASK    0x00F0
16451 +
16452 +#define VX_DYNAMIC     0x0100
16453 +#define VX_STATIC      0x0200
16454 +
16455 +#define VX_ATR_MASK    0x0F00
16456 +
16457 +
16458 +#ifdef CONFIG_VSERVER_PRIVACY
16459 +#define VX_ADMIN_P     (0)
16460 +#define VX_WATCH_P     (0)
16461 +#else
16462 +#define VX_ADMIN_P     VX_ADMIN
16463 +#define VX_WATCH_P     VX_WATCH
16464 +#endif
16465 +
16466 +extern void claim_vx_info(struct vx_info *, struct task_struct *);
16467 +extern void release_vx_info(struct vx_info *, struct task_struct *);
16468 +
16469 +extern struct vx_info *lookup_vx_info(int);
16470 +extern struct vx_info *lookup_or_create_vx_info(int);
16471 +
16472 +extern int get_xid_list(int, unsigned int *, int);
16473 +extern int xid_is_hashed(xid_t);
16474 +
16475 +extern int vx_migrate_task(struct task_struct *, struct vx_info *);
16476 +
16477 +extern long vs_state_change(struct vx_info *, unsigned int);
16478 +
16479 +
16480 +#endif /* __KERNEL__ */
16481 +#else  /* _VX_CONTEXT_H */
16482 +#warning duplicate inclusion
16483 +#endif /* _VX_CONTEXT_H */
16484 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/context_cmd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/context_cmd.h
16485 --- linux-2.6.17.11/include/linux/vserver/context_cmd.h 1970-01-01 01:00:00 +0100
16486 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/context_cmd.h    2006-07-10 01:52:23 +0200
16487 @@ -0,0 +1,111 @@
16488 +#ifndef _VX_CONTEXT_CMD_H
16489 +#define _VX_CONTEXT_CMD_H
16490 +
16491 +
16492 +/* vinfo commands */
16493 +
16494 +#define VCMD_task_xid          VC_CMD(VINFO, 1, 0)
16495 +
16496 +#ifdef __KERNEL__
16497 +extern int vc_task_xid(uint32_t, void __user *);
16498 +
16499 +#endif /* __KERNEL__ */
16500 +
16501 +#define VCMD_vx_info           VC_CMD(VINFO, 5, 0)
16502 +
16503 +struct vcmd_vx_info_v0 {
16504 +       uint32_t xid;
16505 +       uint32_t initpid;
16506 +       /* more to come */
16507 +};
16508 +
16509 +#ifdef __KERNEL__
16510 +extern int vc_vx_info(struct vx_info *, void __user *);
16511 +
16512 +#endif /* __KERNEL__ */
16513 +
16514 +
16515 +/* context commands */
16516 +
16517 +#define VCMD_ctx_create_v0     VC_CMD(VPROC, 1, 0)
16518 +#define VCMD_ctx_create                VC_CMD(VPROC, 1, 1)
16519 +
16520 +struct vcmd_ctx_create {
16521 +       uint64_t flagword;
16522 +};
16523 +
16524 +#define VCMD_ctx_migrate_v0    VC_CMD(PROCMIG, 1, 0)
16525 +#define VCMD_ctx_migrate       VC_CMD(PROCMIG, 1, 1)
16526 +
16527 +struct vcmd_ctx_migrate {
16528 +       uint64_t flagword;
16529 +};
16530 +
16531 +#ifdef __KERNEL__
16532 +extern int vc_ctx_create(uint32_t, void __user *);
16533 +extern int vc_ctx_migrate(struct vx_info *, void __user *);
16534 +
16535 +#endif /* __KERNEL__ */
16536 +
16537 +
16538 +/* flag commands */
16539 +
16540 +#define VCMD_get_cflags                VC_CMD(FLAGS, 1, 0)
16541 +#define VCMD_set_cflags                VC_CMD(FLAGS, 2, 0)
16542 +
16543 +struct vcmd_ctx_flags_v0 {
16544 +       uint64_t flagword;
16545 +       uint64_t mask;
16546 +};
16547 +
16548 +#ifdef __KERNEL__
16549 +extern int vc_get_cflags(struct vx_info *, void __user *);
16550 +extern int vc_set_cflags(struct vx_info *, void __user *);
16551 +
16552 +#endif /* __KERNEL__ */
16553 +
16554 +
16555 +/* context caps commands */
16556 +
16557 +#define VCMD_get_ccaps_v0      VC_CMD(FLAGS, 3, 0)
16558 +#define VCMD_set_ccaps_v0      VC_CMD(FLAGS, 4, 0)
16559 +
16560 +struct vcmd_ctx_caps_v0 {
16561 +       uint64_t bcaps;
16562 +       uint64_t ccaps;
16563 +       uint64_t cmask;
16564 +};
16565 +
16566 +#define VCMD_get_ccaps         VC_CMD(FLAGS, 3, 1)
16567 +#define VCMD_set_ccaps         VC_CMD(FLAGS, 4, 1)
16568 +
16569 +struct vcmd_ctx_caps_v1 {
16570 +       uint64_t ccaps;
16571 +       uint64_t cmask;
16572 +};
16573 +
16574 +#ifdef __KERNEL__
16575 +extern int vc_get_ccaps_v0(struct vx_info *, void __user *);
16576 +extern int vc_set_ccaps_v0(struct vx_info *, void __user *);
16577 +extern int vc_get_ccaps(struct vx_info *, void __user *);
16578 +extern int vc_set_ccaps(struct vx_info *, void __user *);
16579 +
16580 +#endif /* __KERNEL__ */
16581 +
16582 +
16583 +/* bcaps commands */
16584 +
16585 +#define VCMD_get_bcaps         VC_CMD(FLAGS, 9, 0)
16586 +#define VCMD_set_bcaps         VC_CMD(FLAGS,10, 0)
16587 +
16588 +struct vcmd_bcaps {
16589 +       uint64_t bcaps;
16590 +       uint64_t bmask;
16591 +};
16592 +
16593 +#ifdef __KERNEL__
16594 +extern int vc_get_bcaps(struct vx_info *, void __user *);
16595 +extern int vc_set_bcaps(struct vx_info *, void __user *);
16596 +
16597 +#endif /* __KERNEL__ */
16598 +#endif /* _VX_CONTEXT_CMD_H */
16599 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/cvirt.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cvirt.h
16600 --- linux-2.6.17.11/include/linux/vserver/cvirt.h       1970-01-01 01:00:00 +0100
16601 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cvirt.h  2006-08-19 16:24:55 +0200
16602 @@ -0,0 +1,24 @@
16603 +#ifndef _VX_CVIRT_H
16604 +#define _VX_CVIRT_H
16605 +
16606 +
16607 +#ifdef __KERNEL__
16608 +
16609 +struct timespec;
16610 +
16611 +void vx_vsi_uptime(struct timespec *, struct timespec *);
16612 +
16613 +
16614 +struct vx_info;
16615 +
16616 +void vx_update_load(struct vx_info *);
16617 +
16618 +
16619 +int vx_uts_virt_handler(struct ctl_table *ctl, int write, xid_t xid,
16620 +       void **datap, size_t *lenp);
16621 +
16622 +
16623 +int vx_do_syslog(int, char __user *, int);
16624 +
16625 +#endif /* __KERNEL__ */
16626 +#endif /* _VX_CVIRT_H */
16627 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/cvirt_cmd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cvirt_cmd.h
16628 --- linux-2.6.17.11/include/linux/vserver/cvirt_cmd.h   1970-01-01 01:00:00 +0100
16629 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cvirt_cmd.h      2006-07-09 19:24:57 +0200
16630 @@ -0,0 +1,35 @@
16631 +#ifndef _VX_CVIRT_CMD_H
16632 +#define _VX_CVIRT_CMD_H
16633 +
16634 +
16635 +/* virtual host info name commands */
16636 +
16637 +#define VCMD_set_vhi_name      VC_CMD(VHOST, 1, 0)
16638 +#define VCMD_get_vhi_name      VC_CMD(VHOST, 2, 0)
16639 +
16640 +struct vcmd_vhi_name_v0 {
16641 +       uint32_t field;
16642 +       char name[65];
16643 +};
16644 +
16645 +
16646 +enum vhi_name_field {
16647 +       VHIN_CONTEXT=0,
16648 +       VHIN_SYSNAME,
16649 +       VHIN_NODENAME,
16650 +       VHIN_RELEASE,
16651 +       VHIN_VERSION,
16652 +       VHIN_MACHINE,
16653 +       VHIN_DOMAINNAME,
16654 +};
16655 +
16656 +
16657 +#ifdef __KERNEL__
16658 +
16659 +#include <linux/compiler.h>
16660 +
16661 +extern int vc_set_vhi_name(struct vx_info *, void __user *);
16662 +extern int vc_get_vhi_name(struct vx_info *, void __user *);
16663 +
16664 +#endif /* __KERNEL__ */
16665 +#endif /* _VX_CVIRT_CMD_H */
16666 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/cvirt_def.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cvirt_def.h
16667 --- linux-2.6.17.11/include/linux/vserver/cvirt_def.h   1970-01-01 01:00:00 +0100
16668 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/cvirt_def.h      2006-07-30 16:48:35 +0200
16669 @@ -0,0 +1,84 @@
16670 +#ifndef _VX_CVIRT_DEF_H
16671 +#define _VX_CVIRT_DEF_H
16672 +
16673 +#include <linux/jiffies.h>
16674 +#include <linux/utsname.h>
16675 +#include <linux/spinlock.h>
16676 +#include <linux/wait.h>
16677 +#include <linux/time.h>
16678 +#include <asm/atomic.h>
16679 +
16680 +
16681 +struct _vx_usage_stat {
16682 +       uint64_t user;
16683 +       uint64_t nice;
16684 +       uint64_t system;
16685 +       uint64_t softirq;
16686 +       uint64_t irq;
16687 +       uint64_t idle;
16688 +       uint64_t iowait;
16689 +};
16690 +
16691 +struct _vx_syslog {
16692 +       wait_queue_head_t log_wait;
16693 +       spinlock_t logbuf_lock;         /* lock for the log buffer */
16694 +
16695 +       unsigned long log_start;        /* next char to be read by syslog() */
16696 +       unsigned long con_start;        /* next char to be sent to consoles */
16697 +       unsigned long log_end;  /* most-recently-written-char + 1 */
16698 +       unsigned long logged_chars;     /* #chars since last read+clear operation */
16699 +
16700 +       char log_buf[1024];
16701 +};
16702 +
16703 +
16704 +/* context sub struct */
16705 +
16706 +struct _vx_cvirt {
16707 +//     int max_threads;                /* maximum allowed threads */
16708 +       atomic_t nr_threads;            /* number of current threads */
16709 +       atomic_t nr_running;            /* number of running threads */
16710 +       atomic_t nr_uninterruptible;    /* number of uninterruptible threads */
16711 +
16712 +       atomic_t nr_onhold;             /* processes on hold */
16713 +       uint32_t onhold_last;           /* jiffies when put on hold */
16714 +
16715 +       struct timeval bias_tv;         /* time offset to the host */
16716 +       struct timespec bias_idle;
16717 +       struct timespec bias_uptime;    /* context creation point */
16718 +       uint64_t bias_clock;            /* offset in clock_t */
16719 +
16720 +       struct new_utsname utsname;
16721 +
16722 +       spinlock_t load_lock;           /* lock for the load averages */
16723 +       atomic_t load_updates;          /* nr of load updates done so far */
16724 +       uint32_t load_last;             /* last time load was cacled */
16725 +       uint32_t load[3];               /* load averages 1,5,15 */
16726 +
16727 +       atomic_t total_forks;           /* number of forks so far */
16728 +
16729 +       struct _vx_syslog syslog;
16730 +};
16731 +
16732 +struct _vx_cvirt_pc {
16733 +       struct _vx_usage_stat cpustat;
16734 +};
16735 +
16736 +
16737 +#ifdef CONFIG_VSERVER_DEBUG
16738 +
16739 +static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
16740 +{
16741 +       printk("\t_vx_cvirt:\n");
16742 +       printk("\t threads: %4d, %4d, %4d, %4d\n",
16743 +               atomic_read(&cvirt->nr_threads),
16744 +               atomic_read(&cvirt->nr_running),
16745 +               atomic_read(&cvirt->nr_uninterruptible),
16746 +               atomic_read(&cvirt->nr_onhold));
16747 +       /* add rest here */
16748 +       printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks));
16749 +}
16750 +
16751 +#endif
16752 +
16753 +#endif /* _VX_CVIRT_DEF_H */
16754 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/debug.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/debug.h
16755 --- linux-2.6.17.11/include/linux/vserver/debug.h       1970-01-01 01:00:00 +0100
16756 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/debug.h  2006-07-09 17:07:13 +0200
16757 @@ -0,0 +1,110 @@
16758 +#ifndef _VX_DEBUG_H
16759 +#define _VX_DEBUG_H
16760 +
16761 +
16762 +#define VXD_CBIT(n,m)  (vx_debug_ ## n & (1 << (m)))
16763 +#define VXD_CMIN(n,m)  (vx_debug_ ## n > (m))
16764 +#define VXD_MASK(n,m)  (vx_debug_ ## n & (m))
16765 +
16766 +#define VXD_QPOS(v,p)  (((uint32_t)(v) >> ((p)*8)) & 0xFF)
16767 +#define VXD_QUAD(v)    VXD_QPOS(v,0), VXD_QPOS(v,1),           \
16768 +                       VXD_QPOS(v,2), VXD_QPOS(v,3)
16769 +#define VXF_QUAD       "%u.%u.%u.%u"
16770 +
16771 +#define VXD_DEV(d)     (d), (d)->bd_inode->i_ino,              \
16772 +                       imajor((d)->bd_inode), iminor((d)->bd_inode)
16773 +#define VXF_DEV                "%p[%lu,%d:%d]"
16774 +
16775 +
16776 +#define __FUNC__       __func__
16777 +
16778 +
16779 +#ifdef CONFIG_VSERVER_DEBUG
16780 +
16781 +extern unsigned int vx_debug_switch;
16782 +extern unsigned int vx_debug_xid;
16783 +extern unsigned int vx_debug_nid;
16784 +extern unsigned int vx_debug_tag;
16785 +extern unsigned int vx_debug_net;
16786 +extern unsigned int vx_debug_limit;
16787 +extern unsigned int vx_debug_cres;
16788 +extern unsigned int vx_debug_dlim;
16789 +extern unsigned int vx_debug_quota;
16790 +extern unsigned int vx_debug_cvirt;
16791 +extern unsigned int vx_debug_misc;
16792 +
16793 +
16794 +#define VX_LOGLEVEL    "vxD: "
16795 +#define VX_WARNLEVEL   KERN_WARNING "vxW: "
16796 +
16797 +#define vxdprintk(c,f,x...)                                    \
16798 +       do {                                                    \
16799 +               if (c)                                          \
16800 +                       printk(VX_LOGLEVEL f "\n" , ##x);       \
16801 +       } while (0)
16802 +
16803 +#define vxlprintk(c,f,x...)                                    \
16804 +       do {                                                    \
16805 +               if (c)                                          \
16806 +                       printk(VX_LOGLEVEL f " @%s:%d\n", x);   \
16807 +       } while (0)
16808 +
16809 +#define vxfprintk(c,f,x...)                                    \
16810 +       do {                                                    \
16811 +               if (c)                                          \
16812 +                       printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
16813 +       } while (0)
16814 +
16815 +
16816 +#define vxwprintk(c,f,x...)                                    \
16817 +       do {                                                    \
16818 +               if (c)                                          \
16819 +                       printk(VX_WARNLEVEL f "\n" , ##x);      \
16820 +       } while (0)
16821 +
16822 +
16823 +#define vxd_path(d,m)                                          \
16824 +       ({ static char _buffer[PATH_MAX];                       \
16825 +          d_path((d), (m), _buffer, sizeof(_buffer)); })
16826 +
16827 +#define vxd_cond_path(n)                                       \
16828 +       ((n) ? vxd_path((n)->dentry, (n)->mnt) : "<null>" )
16829 +
16830 +
16831 +void dump_vx_info(struct vx_info *, int);
16832 +void dump_vx_info_inactive(int);
16833 +
16834 +#else  /* CONFIG_VSERVER_DEBUG */
16835 +
16836 +#define vx_debug_switch 0
16837 +#define vx_debug_xid   0
16838 +#define vx_debug_nid   0
16839 +#define vx_debug_tag   0
16840 +#define vx_debug_net   0
16841 +#define vx_debug_limit 0
16842 +#define vx_debug_cres  0
16843 +#define vx_debug_dlim  0
16844 +#define vx_debug_cvirt 0
16845 +
16846 +#define vxdprintk(x...) do { } while (0)
16847 +#define vxlprintk(x...) do { } while (0)
16848 +#define vxfprintk(x...) do { } while (0)
16849 +#define vxwprintk(x...) do { } while (0)
16850 +
16851 +#define vxd_path       "<none>"
16852 +#define vxd_cond_path  vxd_path
16853 +
16854 +#endif /* CONFIG_VSERVER_DEBUG */
16855 +
16856 +
16857 +#ifdef CONFIG_VSERVER_DEBUG
16858 +#define vxd_assert_lock(l)     assert_spin_locked(l)
16859 +#define vxd_assert(c,f,x...)   vxlprintk(!(c), \
16860 +       "assertion [" f "] failed.", ##x, __FILE__, __LINE__)
16861 +#else
16862 +#define vxd_assert_lock(l)     do { } while (0)
16863 +#define vxd_assert(c,f,x...)   do { } while (0)
16864 +#endif
16865 +
16866 +
16867 +#endif /* _VX_DEBUG_H */
16868 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/debug_cmd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/debug_cmd.h
16869 --- linux-2.6.17.11/include/linux/vserver/debug_cmd.h   1970-01-01 01:00:00 +0100
16870 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/debug_cmd.h      2006-07-09 19:25:01 +0200
16871 @@ -0,0 +1,14 @@
16872 +#ifndef _VX_DEBUG_CMD_H
16873 +#define _VX_DEBUG_CMD_H
16874 +
16875 +
16876 +/* debug commands */
16877 +
16878 +#define VCMD_dump_history      VC_CMD(DEBUG, 1, 0)
16879 +
16880 +#ifdef __KERNEL__
16881 +
16882 +extern int vc_dump_history(uint32_t);
16883 +
16884 +#endif /* __KERNEL__ */
16885 +#endif /* _VX_DEBUG_CMD_H */
16886 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/dlimit.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/dlimit.h
16887 --- linux-2.6.17.11/include/linux/vserver/dlimit.h      1970-01-01 01:00:00 +0100
16888 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/dlimit.h 2006-07-09 17:07:13 +0200
16889 @@ -0,0 +1,53 @@
16890 +#ifndef _VX_DLIMIT_H
16891 +#define _VX_DLIMIT_H
16892 +
16893 +#include "switch.h"
16894 +
16895 +
16896 +#ifdef __KERNEL__
16897 +
16898 +/*      keep in sync with CDLIM_INFINITY       */
16899 +
16900 +#define DLIM_INFINITY          (~0ULL)
16901 +
16902 +#include <linux/spinlock.h>
16903 +
16904 +struct super_block;
16905 +
16906 +struct dl_info {
16907 +       struct hlist_node dl_hlist;             /* linked list of contexts */
16908 +       struct rcu_head dl_rcu;                 /* the rcu head */
16909 +       tag_t dl_tag;                           /* context tag */
16910 +       atomic_t dl_usecnt;                     /* usage count */
16911 +       atomic_t dl_refcnt;                     /* reference count */
16912 +
16913 +       struct super_block *dl_sb;              /* associated superblock */
16914 +
16915 +       spinlock_t dl_lock;                     /* protect the values */
16916 +
16917 +       unsigned long long dl_space_used;       /* used space in bytes */
16918 +       unsigned long long dl_space_total;      /* maximum space in bytes */
16919 +       unsigned long dl_inodes_used;           /* used inodes */
16920 +       unsigned long dl_inodes_total;          /* maximum inodes */
16921 +
16922 +       unsigned int dl_nrlmult;                /* non root limit mult */
16923 +};
16924 +
16925 +struct rcu_head;
16926 +
16927 +extern void rcu_free_dl_info(struct rcu_head *);
16928 +extern void unhash_dl_info(struct dl_info *);
16929 +
16930 +extern struct dl_info *locate_dl_info(struct super_block *, tag_t);
16931 +
16932 +
16933 +struct kstatfs;
16934 +
16935 +extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
16936 +
16937 +typedef uint64_t dlsize_t;
16938 +
16939 +#endif /* __KERNEL__ */
16940 +#else  /* _VX_DLIMIT_H */
16941 +#warning duplicate inclusion
16942 +#endif /* _VX_DLIMIT_H */
16943 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/dlimit_cmd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/dlimit_cmd.h
16944 --- linux-2.6.17.11/include/linux/vserver/dlimit_cmd.h  1970-01-01 01:00:00 +0100
16945 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/dlimit_cmd.h     2006-07-09 19:25:12 +0200
16946 @@ -0,0 +1,72 @@
16947 +#ifndef _VX_DLIMIT_CMD_H
16948 +#define _VX_DLIMIT_CMD_H
16949 +
16950 +
16951 +/*  dlimit vserver commands */
16952 +
16953 +#define VCMD_add_dlimit                VC_CMD(DLIMIT, 1, 0)
16954 +#define VCMD_rem_dlimit                VC_CMD(DLIMIT, 2, 0)
16955 +
16956 +#define VCMD_set_dlimit                VC_CMD(DLIMIT, 5, 0)
16957 +#define VCMD_get_dlimit                VC_CMD(DLIMIT, 6, 0)
16958 +
16959 +struct vcmd_ctx_dlimit_base_v0 {
16960 +       const char __user *name;
16961 +       uint32_t flags;
16962 +};
16963 +
16964 +struct vcmd_ctx_dlimit_v0 {
16965 +       const char __user *name;
16966 +       uint32_t space_used;                    /* used space in kbytes */
16967 +       uint32_t space_total;                   /* maximum space in kbytes */
16968 +       uint32_t inodes_used;                   /* used inodes */
16969 +       uint32_t inodes_total;                  /* maximum inodes */
16970 +       uint32_t reserved;                      /* reserved for root in % */
16971 +       uint32_t flags;
16972 +};
16973 +
16974 +#define CDLIM_UNSET            ((uint32_t)0UL)
16975 +#define CDLIM_INFINITY         ((uint32_t)~0UL)
16976 +#define CDLIM_KEEP             ((uint32_t)~1UL)
16977 +
16978 +#ifdef __KERNEL__
16979 +
16980 +#ifdef CONFIG_COMPAT
16981 +
16982 +struct vcmd_ctx_dlimit_base_v0_x32 {
16983 +       compat_uptr_t name_ptr;
16984 +       uint32_t flags;
16985 +};
16986 +
16987 +struct vcmd_ctx_dlimit_v0_x32 {
16988 +       compat_uptr_t name_ptr;
16989 +       uint32_t space_used;                    /* used space in kbytes */
16990 +       uint32_t space_total;                   /* maximum space in kbytes */
16991 +       uint32_t inodes_used;                   /* used inodes */
16992 +       uint32_t inodes_total;                  /* maximum inodes */
16993 +       uint32_t reserved;                      /* reserved for root in % */
16994 +       uint32_t flags;
16995 +};
16996 +
16997 +#endif /* CONFIG_COMPAT */
16998 +
16999 +#include <linux/compiler.h>
17000 +
17001 +extern int vc_add_dlimit(uint32_t, void __user *);
17002 +extern int vc_rem_dlimit(uint32_t, void __user *);
17003 +
17004 +extern int vc_set_dlimit(uint32_t, void __user *);
17005 +extern int vc_get_dlimit(uint32_t, void __user *);
17006 +
17007 +#ifdef CONFIG_COMPAT
17008 +
17009 +extern int vc_add_dlimit_x32(uint32_t, void __user *);
17010 +extern int vc_rem_dlimit_x32(uint32_t, void __user *);
17011 +
17012 +extern int vc_set_dlimit_x32(uint32_t, void __user *);
17013 +extern int vc_get_dlimit_x32(uint32_t, void __user *);
17014 +
17015 +#endif /* CONFIG_COMPAT */
17016 +
17017 +#endif /* __KERNEL__ */
17018 +#endif /* _VX_DLIMIT_CMD_H */
17019 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/global.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/global.h
17020 --- linux-2.6.17.11/include/linux/vserver/global.h      1970-01-01 01:00:00 +0100
17021 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/global.h 2006-07-09 17:07:13 +0200
17022 @@ -0,0 +1,8 @@
17023 +#ifndef _VX_GLOBAL_H
17024 +#define _VX_GLOBAL_H
17025 +
17026 +
17027 +extern atomic_t vx_global_ctotal;
17028 +extern atomic_t vx_global_cactive;
17029 +
17030 +#endif /* _VX_GLOBAL_H */
17031 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/history.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/history.h
17032 --- linux-2.6.17.11/include/linux/vserver/history.h     1970-01-01 01:00:00 +0100
17033 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/history.h        2006-07-09 17:07:13 +0200
17034 @@ -0,0 +1,196 @@
17035 +#ifndef _VX_HISTORY_H
17036 +#define _VX_HISTORY_H
17037 +
17038 +#ifdef CONFIG_VSERVER_HISTORY
17039 +
17040 +extern unsigned volatile int vxh_active;
17041 +
17042 +struct _vxhe_vxi {
17043 +       struct vx_info *ptr;
17044 +       unsigned xid;
17045 +       unsigned usecnt;
17046 +       unsigned tasks;
17047 +};
17048 +
17049 +struct _vxhe_set_clr {
17050 +       void *data;
17051 +};
17052 +
17053 +struct _vxhe_loc_lookup {
17054 +       unsigned arg;
17055 +};
17056 +
17057 +enum {
17058 +       VXH_UNUSED=0,
17059 +       VXH_THROW_OOPS=1,
17060 +
17061 +       VXH_GET_VX_INFO,
17062 +       VXH_PUT_VX_INFO,
17063 +       VXH_INIT_VX_INFO,
17064 +       VXH_SET_VX_INFO,
17065 +       VXH_CLR_VX_INFO,
17066 +       VXH_CLAIM_VX_INFO,
17067 +       VXH_RELEASE_VX_INFO,
17068 +       VXH_ALLOC_VX_INFO,
17069 +       VXH_DEALLOC_VX_INFO,
17070 +       VXH_HASH_VX_INFO,
17071 +       VXH_UNHASH_VX_INFO,
17072 +       VXH_LOC_VX_INFO,
17073 +       VXH_LOOKUP_VX_INFO,
17074 +       VXH_CREATE_VX_INFO,
17075 +};
17076 +
17077 +struct _vx_hist_entry {
17078 +       void *loc;
17079 +       unsigned short seq;
17080 +       unsigned short type;
17081 +       struct _vxhe_vxi vxi;
17082 +       union {
17083 +               struct _vxhe_set_clr sc;
17084 +               struct _vxhe_loc_lookup ll;
17085 +       };
17086 +};
17087 +
17088 +struct _vx_hist_entry *vxh_advance(void *loc);
17089 +
17090 +
17091 +static inline
17092 +void   __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
17093 +{
17094 +       entry->vxi.ptr = vxi;
17095 +       if (vxi) {
17096 +               entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
17097 +               entry->vxi.tasks = atomic_read(&vxi->vx_tasks);
17098 +               entry->vxi.xid = vxi->vx_id;
17099 +       }
17100 +}
17101 +
17102 +
17103 +#define        __HERE__ current_text_addr()
17104 +
17105 +#define __VXH_BODY(__type, __data, __here)     \
17106 +       struct _vx_hist_entry *entry;           \
17107 +                                               \
17108 +       preempt_disable();                      \
17109 +       entry = vxh_advance(__here);            \
17110 +       __data;                                 \
17111 +       entry->type = __type;                   \
17112 +       preempt_enable();
17113 +
17114 +
17115 +       /* pass vxi only */
17116 +
17117 +#define __VXH_SMPL                             \
17118 +       __vxh_copy_vxi(entry, vxi)
17119 +
17120 +static inline
17121 +void   __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
17122 +{
17123 +       __VXH_BODY(__type, __VXH_SMPL, __here)
17124 +}
17125 +
17126 +       /* pass vxi and data (void *) */
17127 +
17128 +#define __VXH_DATA                             \
17129 +       __vxh_copy_vxi(entry, vxi);             \
17130 +       entry->sc.data = data
17131 +
17132 +static inline
17133 +void   __vxh_data(struct vx_info *vxi, void *data,
17134 +                       int __type, void *__here)
17135 +{
17136 +       __VXH_BODY(__type, __VXH_DATA, __here)
17137 +}
17138 +
17139 +       /* pass vxi and arg (long) */
17140 +
17141 +#define __VXH_LONG                             \
17142 +       __vxh_copy_vxi(entry, vxi);             \
17143 +       entry->ll.arg = arg
17144 +
17145 +static inline
17146 +void   __vxh_long(struct vx_info *vxi, long arg,
17147 +                       int __type, void *__here)
17148 +{
17149 +       __VXH_BODY(__type, __VXH_LONG, __here)
17150 +}
17151 +
17152 +
17153 +static inline
17154 +void   __vxh_throw_oops(void *__here)
17155 +{
17156 +       __VXH_BODY(VXH_THROW_OOPS, {}, __here);
17157 +       /* prevent further acquisition */
17158 +       vxh_active = 0;
17159 +}
17160 +
17161 +
17162 +#define vxh_throw_oops()       __vxh_throw_oops(__HERE__);
17163 +
17164 +#define __vxh_get_vx_info(v,h) __vxh_smpl(v, VXH_GET_VX_INFO, h);
17165 +#define __vxh_put_vx_info(v,h) __vxh_smpl(v, VXH_PUT_VX_INFO, h);
17166 +
17167 +#define __vxh_init_vx_info(v,d,h) \
17168 +       __vxh_data(v,d, VXH_INIT_VX_INFO, h);
17169 +#define __vxh_set_vx_info(v,d,h) \
17170 +       __vxh_data(v,d, VXH_SET_VX_INFO, h);
17171 +#define __vxh_clr_vx_info(v,d,h) \
17172 +       __vxh_data(v,d, VXH_CLR_VX_INFO, h);
17173 +
17174 +#define __vxh_claim_vx_info(v,d,h) \
17175 +       __vxh_data(v,d, VXH_CLAIM_VX_INFO, h);
17176 +#define __vxh_release_vx_info(v,d,h) \
17177 +       __vxh_data(v,d, VXH_RELEASE_VX_INFO, h);
17178 +
17179 +#define vxh_alloc_vx_info(v) \
17180 +       __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__);
17181 +#define vxh_dealloc_vx_info(v) \
17182 +       __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__);
17183 +
17184 +#define vxh_hash_vx_info(v) \
17185 +       __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__);
17186 +#define vxh_unhash_vx_info(v) \
17187 +       __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__);
17188 +
17189 +#define vxh_loc_vx_info(v,l) \
17190 +       __vxh_long(v,l, VXH_LOC_VX_INFO, __HERE__);
17191 +#define vxh_lookup_vx_info(v,l) \
17192 +       __vxh_long(v,l, VXH_LOOKUP_VX_INFO, __HERE__);
17193 +#define vxh_create_vx_info(v,l) \
17194 +       __vxh_long(v,l, VXH_CREATE_VX_INFO, __HERE__);
17195 +
17196 +extern void vxh_dump_history(void);
17197 +
17198 +
17199 +#else  /* CONFIG_VSERVER_HISTORY */
17200 +
17201 +#define        __HERE__        0
17202 +
17203 +#define vxh_throw_oops()               do { } while (0)
17204 +
17205 +#define __vxh_get_vx_info(v,h)         do { } while (0)
17206 +#define __vxh_put_vx_info(v,h)         do { } while (0)
17207 +
17208 +#define __vxh_init_vx_info(v,d,h)      do { } while (0)
17209 +#define __vxh_set_vx_info(v,d,h)       do { } while (0)
17210 +#define __vxh_clr_vx_info(v,d,h)       do { } while (0)
17211 +
17212 +#define __vxh_claim_vx_info(v,d,h)     do { } while (0)
17213 +#define __vxh_release_vx_info(v,d,h)   do { } while (0)
17214 +
17215 +#define vxh_alloc_vx_info(v)           do { } while (0)
17216 +#define vxh_dealloc_vx_info(v)         do { } while (0)
17217 +
17218 +#define vxh_hash_vx_info(v)            do { } while (0)
17219 +#define vxh_unhash_vx_info(v)          do { } while (0)
17220 +
17221 +#define vxh_loc_vx_info(a,v)           do { } while (0)
17222 +#define vxh_lookup_vx_info(a,v)                do { } while (0)
17223 +#define vxh_create_vx_info(a,v)                do { } while (0)
17224 +
17225 +#define vxh_dump_history()             do { } while (0)
17226 +
17227 +
17228 +#endif /* CONFIG_VSERVER_HISTORY */
17229 +
17230 +#endif /* _VX_HISTORY_H */
17231 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/inode.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/inode.h
17232 --- linux-2.6.17.11/include/linux/vserver/inode.h       1970-01-01 01:00:00 +0100
17233 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/inode.h  2006-07-09 17:07:13 +0200
17234 @@ -0,0 +1,38 @@
17235 +#ifndef _VX_INODE_H
17236 +#define _VX_INODE_H
17237 +
17238 +
17239 +#define IATTR_TAG      0x01000000
17240 +
17241 +#define IATTR_ADMIN    0x00000001
17242 +#define IATTR_WATCH    0x00000002
17243 +#define IATTR_HIDE     0x00000004
17244 +#define IATTR_FLAGS    0x00000007
17245 +
17246 +#define IATTR_BARRIER  0x00010000
17247 +#define IATTR_IUNLINK  0x00020000
17248 +#define IATTR_IMMUTABLE 0x00040000
17249 +
17250 +#ifdef __KERNEL__
17251 +
17252 +
17253 +#ifdef CONFIG_VSERVER_PROC_SECURE
17254 +#define IATTR_PROC_DEFAULT     ( IATTR_ADMIN | IATTR_HIDE )
17255 +#define IATTR_PROC_SYMLINK     ( IATTR_ADMIN )
17256 +#else
17257 +#define IATTR_PROC_DEFAULT     ( IATTR_ADMIN )
17258 +#define IATTR_PROC_SYMLINK     ( IATTR_ADMIN )
17259 +#endif
17260 +
17261 +#define vx_hide_check(c,m)     (((m) & IATTR_HIDE) ? vx_check(c,m) : 1)
17262 +
17263 +#endif /* __KERNEL__ */
17264 +
17265 +/* inode ioctls */
17266 +
17267 +#define FIOC_GETXFLG   _IOR('x', 5, long)
17268 +#define FIOC_SETXFLG   _IOW('x', 6, long)
17269 +
17270 +#else  /* _VX_INODE_H */
17271 +#warning duplicate inclusion
17272 +#endif /* _VX_INODE_H */
17273 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/inode_cmd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/inode_cmd.h
17274 --- linux-2.6.17.11/include/linux/vserver/inode_cmd.h   1970-01-01 01:00:00 +0100
17275 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/inode_cmd.h      2006-07-09 19:25:23 +0200
17276 @@ -0,0 +1,59 @@
17277 +#ifndef _VX_INODE_CMD_H
17278 +#define _VX_INODE_CMD_H
17279 +
17280 +
17281 +/*  inode vserver commands */
17282 +
17283 +#define VCMD_get_iattr_v0      VC_CMD(INODE, 1, 0)
17284 +#define VCMD_set_iattr_v0      VC_CMD(INODE, 2, 0)
17285 +
17286 +#define VCMD_get_iattr         VC_CMD(INODE, 1, 1)
17287 +#define VCMD_set_iattr         VC_CMD(INODE, 2, 1)
17288 +
17289 +struct vcmd_ctx_iattr_v0 {
17290 +       /* device handle in id */
17291 +       uint64_t ino;
17292 +       uint32_t xid;
17293 +       uint32_t flags;
17294 +       uint32_t mask;
17295 +};
17296 +
17297 +struct vcmd_ctx_iattr_v1 {
17298 +       const char __user *name;
17299 +       uint32_t xid;
17300 +       uint32_t flags;
17301 +       uint32_t mask;
17302 +};
17303 +
17304 +
17305 +#ifdef __KERNEL__
17306 +
17307 +
17308 +#ifdef CONFIG_COMPAT
17309 +
17310 +struct vcmd_ctx_iattr_v1_x32 {
17311 +       compat_uptr_t name_ptr;
17312 +       uint32_t xid;
17313 +       uint32_t flags;
17314 +       uint32_t mask;
17315 +};
17316 +
17317 +#endif /* CONFIG_COMPAT */
17318 +
17319 +#include <linux/compiler.h>
17320 +
17321 +extern int vc_get_iattr_v0(uint32_t, void __user *);
17322 +extern int vc_set_iattr_v0(uint32_t, void __user *);
17323 +
17324 +extern int vc_get_iattr(uint32_t, void __user *);
17325 +extern int vc_set_iattr(uint32_t, void __user *);
17326 +
17327 +#ifdef CONFIG_COMPAT
17328 +
17329 +extern int vc_get_iattr_x32(uint32_t, void __user *);
17330 +extern int vc_set_iattr_x32(uint32_t, void __user *);
17331 +
17332 +#endif /* CONFIG_COMPAT */
17333 +
17334 +#endif /* __KERNEL__ */
17335 +#endif /* _VX_INODE_CMD_H */
17336 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/legacy.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/legacy.h
17337 --- linux-2.6.17.11/include/linux/vserver/legacy.h      1970-01-01 01:00:00 +0100
17338 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/legacy.h 2006-07-09 17:07:13 +0200
17339 @@ -0,0 +1,49 @@
17340 +#ifndef _VX_LEGACY_H
17341 +#define _VX_LEGACY_H
17342 +
17343 +#include "switch.h"
17344 +
17345 +
17346 +/*  compatibiliy vserver commands */
17347 +
17348 +#define VCMD_new_s_context     VC_CMD(COMPAT, 1, 1)
17349 +#define VCMD_set_ipv4root      VC_CMD(COMPAT, 2, 3)
17350 +
17351 +#define VCMD_create_context    VC_CMD(VSETUP, 1, 0)
17352 +
17353 +/*  compatibiliy vserver arguments */
17354 +
17355 +struct vcmd_new_s_context_v1 {
17356 +       uint32_t remove_cap;
17357 +       uint32_t flags;
17358 +};
17359 +
17360 +struct vcmd_set_ipv4root_v3 {
17361 +       /* number of pairs in id */
17362 +       uint32_t broadcast;
17363 +       struct {
17364 +               uint32_t ip;
17365 +               uint32_t mask;
17366 +       } nx_mask_pair[NB_IPV4ROOT];
17367 +};
17368 +
17369 +
17370 +#define VX_INFO_LOCK           1       /* Can't request a new vx_id */
17371 +#define VX_INFO_NPROC          4       /* Limit number of processes in a context */
17372 +#define VX_INFO_PRIVATE                8       /* Noone can join this security context */
17373 +#define VX_INFO_INIT           16      /* This process wants to become the */
17374 +                                       /* logical process 1 of the security */
17375 +                                       /* context */
17376 +#define VX_INFO_HIDEINFO       32      /* Hide some information in /proc */
17377 +#define VX_INFO_ULIMIT         64      /* Use ulimit of the current process */
17378 +                                       /* to become the global limits */
17379 +                                       /* of the context */
17380 +#define VX_INFO_NAMESPACE      128     /* save private namespace */
17381 +
17382 +
17383 +#ifdef __KERNEL__
17384 +extern int vc_new_s_context(uint32_t, void __user *);
17385 +extern int vc_set_ipv4root(uint32_t, void __user *);
17386 +
17387 +#endif /* __KERNEL__ */
17388 +#endif /* _VX_LEGACY_H */
17389 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/limit.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/limit.h
17390 --- linux-2.6.17.11/include/linux/vserver/limit.h       1970-01-01 01:00:00 +0100
17391 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/limit.h  2006-07-12 14:16:06 +0200
17392 @@ -0,0 +1,66 @@
17393 +#ifndef _VX_LIMIT_H
17394 +#define _VX_LIMIT_H
17395 +
17396 +
17397 +#define VLIMIT_NSOCK   16
17398 +#define VLIMIT_OPENFD  17
17399 +#define VLIMIT_ANON    18
17400 +#define VLIMIT_SHMEM   19
17401 +#define VLIMIT_SEMARY  20
17402 +#define VLIMIT_NSEMS   21
17403 +#define VLIMIT_DENTRY  22
17404 +
17405 +#ifdef __KERNEL__
17406 +
17407 +#define        VLIM_NOCHECK    (1L << VLIMIT_DENTRY)
17408 +
17409 +/*     keep in sync with CRLIM_INFINITY */
17410 +
17411 +#define        VLIM_INFINITY   (~0ULL)
17412 +
17413 +#ifndef RLIM_INFINITY
17414 +#warning RLIM_INFINITY is undefined
17415 +#endif
17416 +
17417 +#define __rlim_val(l,r,v)      ((l)->res[(r)].v)
17418 +
17419 +#define __rlim_soft(l,r)       __rlim_val(l,r,soft)
17420 +#define __rlim_hard(l,r)       __rlim_val(l,r,hard)
17421 +
17422 +#define __rlim_rcur(l,r)       __rlim_val(l,r,rcur)
17423 +#define __rlim_rmin(l,r)       __rlim_val(l,r,rmin)
17424 +#define __rlim_rmax(l,r)       __rlim_val(l,r,rmax)
17425 +
17426 +#define __rlim_lhit(l,r)       __rlim_val(l,r,lhit)
17427 +#define __rlim_hit(l,r)                atomic_inc(&__rlim_lhit(l,r))
17428 +
17429 +typedef atomic_long_t rlim_atomic_t;
17430 +typedef unsigned long rlim_t;
17431 +
17432 +#define __rlim_get(l,r)                atomic_long_read(&__rlim_rcur(l,r))
17433 +#define __rlim_set(l,r,v)      atomic_long_set(&__rlim_rcur(l,r), v)
17434 +#define __rlim_inc(l,r)                atomic_long_inc(&__rlim_rcur(l,r))
17435 +#define __rlim_dec(l,r)                atomic_long_dec(&__rlim_rcur(l,r))
17436 +#define __rlim_add(l,r,v)      atomic_long_add(v, &__rlim_rcur(l,r))
17437 +#define __rlim_sub(l,r,v)      atomic_long_sub(v, &__rlim_rcur(l,r))
17438 +
17439 +
17440 +#if    (RLIM_INFINITY == VLIM_INFINITY)
17441 +#define        VX_VLIM(r) ((long long)(long)(r))
17442 +#define        VX_RLIM(v) ((rlim_t)(v))
17443 +#else
17444 +#define        VX_VLIM(r) (((r) == RLIM_INFINITY) \
17445 +               ? VLIM_INFINITY : (long long)(r))
17446 +#define        VX_RLIM(v) (((v) == VLIM_INFINITY) \
17447 +               ? RLIM_INFINITY : (rlim_t)(v))
17448 +#endif
17449 +
17450 +struct sysinfo;
17451 +
17452 +void vx_vsi_meminfo(struct sysinfo *);
17453 +void vx_vsi_swapinfo(struct sysinfo *);
17454 +
17455 +#define NUM_LIMITS     24
17456 +
17457 +#endif /* __KERNEL__ */
17458 +#endif /* _VX_LIMIT_H */
17459 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/limit_cmd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/limit_cmd.h
17460 --- linux-2.6.17.11/include/linux/vserver/limit_cmd.h   1970-01-01 01:00:00 +0100
17461 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/limit_cmd.h      2006-07-30 17:06:43 +0200
17462 @@ -0,0 +1,69 @@
17463 +#ifndef _VX_LIMIT_CMD_H
17464 +#define _VX_LIMIT_CMD_H
17465 +
17466 +
17467 +/*  rlimit vserver commands */
17468 +
17469 +#define VCMD_get_rlimit                VC_CMD(RLIMIT, 1, 0)
17470 +#define VCMD_set_rlimit                VC_CMD(RLIMIT, 2, 0)
17471 +#define VCMD_get_rlimit_mask   VC_CMD(RLIMIT, 3, 0)
17472 +#define VCMD_reset_minmax      VC_CMD(RLIMIT, 9, 0)
17473 +
17474 +struct vcmd_ctx_rlimit_v0 {
17475 +       uint32_t id;
17476 +       uint64_t minimum;
17477 +       uint64_t softlimit;
17478 +       uint64_t maximum;
17479 +};
17480 +
17481 +struct vcmd_ctx_rlimit_mask_v0 {
17482 +       uint32_t minimum;
17483 +       uint32_t softlimit;
17484 +       uint32_t maximum;
17485 +};
17486 +
17487 +#define VCMD_rlimit_stat       VC_CMD(VSTAT, 1, 0)
17488 +
17489 +struct vcmd_rlimit_stat_v0 {
17490 +       uint32_t id;
17491 +       uint32_t hits;
17492 +       uint64_t value;
17493 +       uint64_t minimum;
17494 +       uint64_t maximum;
17495 +};
17496 +
17497 +#define CRLIM_UNSET            (0ULL)
17498 +#define CRLIM_INFINITY         (~0ULL)
17499 +#define CRLIM_KEEP             (~1ULL)
17500 +
17501 +#ifdef __KERNEL__
17502 +
17503 +#ifdef CONFIG_IA32_EMULATION
17504 +
17505 +struct vcmd_ctx_rlimit_v0_x32 {
17506 +       uint32_t id;
17507 +       uint64_t minimum;
17508 +       uint64_t softlimit;
17509 +       uint64_t maximum;
17510 +} __attribute__ ((aligned (4)));
17511 +
17512 +#endif /* CONFIG_IA32_EMULATION */
17513 +
17514 +#include <linux/compiler.h>
17515 +
17516 +extern int vc_get_rlimit_mask(uint32_t, void __user *);
17517 +extern int vc_get_rlimit(struct vx_info *, void __user *);
17518 +extern int vc_set_rlimit(struct vx_info *, void __user *);
17519 +extern int vc_reset_minmax(struct vx_info *, void __user *);
17520 +
17521 +extern int vc_rlimit_stat(struct vx_info *, void __user *);
17522 +
17523 +#ifdef CONFIG_IA32_EMULATION
17524 +
17525 +extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
17526 +extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
17527 +
17528 +#endif /* CONFIG_IA32_EMULATION */
17529 +
17530 +#endif /* __KERNEL__ */
17531 +#endif /* _VX_LIMIT_CMD_H */
17532 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/limit_def.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/limit_def.h
17533 --- linux-2.6.17.11/include/linux/vserver/limit_def.h   1970-01-01 01:00:00 +0100
17534 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/limit_def.h      2006-07-09 17:07:13 +0200
17535 @@ -0,0 +1,47 @@
17536 +#ifndef _VX_LIMIT_DEF_H
17537 +#define _VX_LIMIT_DEF_H
17538 +
17539 +#include <asm/atomic.h>
17540 +#include <asm/resource.h>
17541 +
17542 +#include "limit.h"
17543 +
17544 +
17545 +struct _vx_res_limit {
17546 +       rlim_t soft;            /* Context soft limit */
17547 +       rlim_t hard;            /* Context hard limit */
17548 +
17549 +       rlim_atomic_t rcur;     /* Current value */
17550 +       rlim_t rmin;            /* Context minimum */
17551 +       rlim_t rmax;            /* Context maximum */
17552 +
17553 +       atomic_t lhit;          /* Limit hits */
17554 +};
17555 +
17556 +/* context sub struct */
17557 +
17558 +struct _vx_limit {
17559 +       struct _vx_res_limit res[NUM_LIMITS];
17560 +};
17561 +
17562 +#ifdef CONFIG_VSERVER_DEBUG
17563 +
17564 +static inline void __dump_vx_limit(struct _vx_limit *limit)
17565 +{
17566 +       int i;
17567 +
17568 +       printk("\t_vx_limit:");
17569 +       for (i=0; i<NUM_LIMITS; i++) {
17570 +               printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
17571 +                       i, (unsigned long)__rlim_get(limit, i),
17572 +                       (unsigned long)__rlim_rmin(limit, i),
17573 +                       (unsigned long)__rlim_rmax(limit, i),
17574 +                       (long)__rlim_soft(limit, i),
17575 +                       (long)__rlim_hard(limit, i),
17576 +                       atomic_read(&__rlim_lhit(limit, i)));
17577 +       }
17578 +}
17579 +
17580 +#endif
17581 +
17582 +#endif /* _VX_LIMIT_DEF_H */
17583 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/limit_int.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/limit_int.h
17584 --- linux-2.6.17.11/include/linux/vserver/limit_int.h   1970-01-01 01:00:00 +0100
17585 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/limit_int.h      2006-07-09 17:07:13 +0200
17586 @@ -0,0 +1,83 @@
17587 +#ifndef _VX_LIMIT_INT_H
17588 +#define _VX_LIMIT_INT_H
17589 +
17590 +
17591 +#ifdef __KERNEL__
17592 +
17593 +#define VXD_RCRES_COND(r)      VXD_CBIT(cres, (r))
17594 +#define VXD_RLIMIT_COND(r)     VXD_CBIT(limit, (r))
17595 +
17596 +extern const char *vlimit_name[NUM_LIMITS];
17597 +
17598 +static inline void __vx_acc_cres(struct vx_info *vxi,
17599 +       int res, int dir, void *_data, char *_file, int _line)
17600 +{
17601 +       if (VXD_RCRES_COND(res))
17602 +               vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
17603 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
17604 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
17605 +                       (dir > 0) ? "++" : "--", _data, _file, _line);
17606 +       if (!vxi)
17607 +               return;
17608 +
17609 +       if (dir > 0)
17610 +               __rlim_inc(&vxi->limit, res);
17611 +       else
17612 +               __rlim_dec(&vxi->limit, res);
17613 +}
17614 +
17615 +static inline void __vx_add_cres(struct vx_info *vxi,
17616 +       int res, int amount, void *_data, char *_file, int _line)
17617 +{
17618 +       if (VXD_RCRES_COND(res))
17619 +               vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
17620 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
17621 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
17622 +                       amount, _data, _file, _line);
17623 +       if (amount == 0)
17624 +               return;
17625 +       if (!vxi)
17626 +               return;
17627 +       __rlim_add(&vxi->limit, res, amount);
17628 +}
17629 +
17630 +static inline int __vx_cres_avail(struct vx_info *vxi,
17631 +               int res, int num, char *_file, int _line)
17632 +{
17633 +       rlim_t value;
17634 +
17635 +       if (VXD_RLIMIT_COND(res))
17636 +               vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
17637 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
17638 +                       (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
17639 +                       (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
17640 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
17641 +                       num, _file, _line);
17642 +       if (num == 0)
17643 +               return 1;
17644 +       if (!vxi)
17645 +               return 1;
17646 +
17647 +       value = __rlim_get(&vxi->limit, res);
17648 +
17649 +       if (value > __rlim_rmax(&vxi->limit, res))
17650 +               __rlim_rmax(&vxi->limit, res) = value;
17651 +       else if (value < __rlim_rmin(&vxi->limit, res))
17652 +               __rlim_rmin(&vxi->limit, res) = value;
17653 +
17654 +       if (__rlim_soft(&vxi->limit, res) == RLIM_INFINITY)
17655 +               return -1;
17656 +       if (value + num <= __rlim_soft(&vxi->limit, res))
17657 +               return -1;
17658 +
17659 +       if (__rlim_hard(&vxi->limit, res) == RLIM_INFINITY)
17660 +               return 1;
17661 +       if (value + num <= __rlim_hard(&vxi->limit, res))
17662 +               return 1;
17663 +
17664 +       __rlim_hit(&vxi->limit, res);
17665 +       return 0;
17666 +}
17667 +
17668 +#endif /* __KERNEL__ */
17669 +#endif /* _VX_LIMIT_INT_H */
17670 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/monitor.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/monitor.h
17671 --- linux-2.6.17.11/include/linux/vserver/monitor.h     1970-01-01 01:00:00 +0100
17672 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/monitor.h        2006-07-09 17:07:13 +0200
17673 @@ -0,0 +1,97 @@
17674 +#ifndef _VX_MONITOR_H
17675 +#define _VX_MONITOR_H
17676 +
17677 +#include <linux/config.h>
17678 +
17679 +
17680 +enum {
17681 +       VXM_UNUSED = 0,
17682 +
17683 +       VXM_SYNC = 0x10,
17684 +
17685 +       VXM_UPDATE = 0x20,
17686 +       VXM_UPDATE_1,
17687 +       VXM_UPDATE_2,
17688 +
17689 +       VXM_RQINFO_1 = 0x24,
17690 +       VXM_RQINFO_2,
17691 +
17692 +       VXM_ACTIVATE = 0x40,
17693 +       VXM_DEACTIVATE,
17694 +       VXM_IDLE,
17695 +
17696 +       VXM_HOLD = 0x44,
17697 +       VXM_UNHOLD,
17698 +
17699 +       VXM_MIGRATE = 0x48,
17700 +       VXM_RESCHED,
17701 +
17702 +       /* all other bits are flags */
17703 +       VXM_SCHED = 0x80,
17704 +};
17705 +
17706 +struct _vxm_update_1 {
17707 +       uint32_t tokens_max;
17708 +       uint32_t fill_rate;
17709 +       uint32_t interval;
17710 +};
17711 +
17712 +struct _vxm_update_2 {
17713 +       uint32_t tokens_min;
17714 +       uint32_t fill_rate;
17715 +       uint32_t interval;
17716 +};
17717 +
17718 +struct _vxm_rqinfo_1 {
17719 +       uint16_t running;
17720 +       uint16_t onhold;
17721 +       uint16_t iowait;
17722 +       uint16_t uintr;
17723 +       uint32_t idle_tokens;
17724 +};
17725 +
17726 +struct _vxm_rqinfo_2 {
17727 +       uint32_t norm_time;
17728 +       uint32_t idle_time;
17729 +       uint32_t idle_skip;
17730 +};
17731 +
17732 +struct _vxm_sched {
17733 +       uint32_t tokens;
17734 +       uint32_t norm_time;
17735 +       uint32_t idle_time;
17736 +};
17737 +
17738 +struct _vxm_task {
17739 +       uint16_t pid;
17740 +       uint16_t state;
17741 +};
17742 +
17743 +struct _vxm_event {
17744 +       uint32_t jif;
17745 +       union {
17746 +               uint32_t seq;
17747 +               uint32_t sec;
17748 +       };
17749 +       union {
17750 +               uint32_t tokens;
17751 +               uint32_t nsec;
17752 +               struct _vxm_task tsk;
17753 +       };
17754 +};
17755 +
17756 +struct _vx_mon_entry {
17757 +       uint16_t type;
17758 +       uint16_t xid;
17759 +       union {
17760 +               struct _vxm_event ev;
17761 +               struct _vxm_sched sd;
17762 +               struct _vxm_update_1 u1;
17763 +               struct _vxm_update_2 u2;
17764 +               struct _vxm_rqinfo_1 q1;
17765 +               struct _vxm_rqinfo_2 q2;
17766 +       };
17767 +};
17768 +
17769 +
17770 +#endif /* _VX_MONITOR_H */
17771 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/namespace.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/namespace.h
17772 --- linux-2.6.17.11/include/linux/vserver/namespace.h   1970-01-01 01:00:00 +0100
17773 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/namespace.h      2006-07-09 17:07:13 +0200
17774 @@ -0,0 +1,15 @@
17775 +#ifndef _VX_NAMESPACE_H
17776 +#define _VX_NAMESPACE_H
17777 +
17778 +
17779 +#include <linux/types.h>
17780 +
17781 +struct vx_info;
17782 +struct namespace;
17783 +struct fs_struct;
17784 +
17785 +extern int vx_set_namespace(struct vx_info *, struct namespace *, struct fs_struct *);
17786 +
17787 +#else  /* _VX_NAMESPACE_H */
17788 +#warning duplicate inclusion
17789 +#endif /* _VX_NAMESPACE_H */
17790 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/namespace_cmd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/namespace_cmd.h
17791 --- linux-2.6.17.11/include/linux/vserver/namespace_cmd.h       1970-01-01 01:00:00 +0100
17792 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/namespace_cmd.h  2006-07-27 19:03:51 +0200
17793 @@ -0,0 +1,17 @@
17794 +#ifndef _VX_NAMESPACE_CMD_H
17795 +#define _VX_NAMESPACE_CMD_H
17796 +
17797 +
17798 +#define VCMD_enter_namespace   VC_CMD(PROCALT, 1, 0)
17799 +
17800 +#define VCMD_set_namespace_v0  VC_CMD(PROCALT, 3, 0)
17801 +#define VCMD_set_namespace     VC_CMD(PROCALT, 3, 1)
17802 +
17803 +
17804 +#ifdef __KERNEL__
17805 +
17806 +extern int vc_enter_namespace(struct vx_info *, void __user *);
17807 +extern int vc_set_namespace(struct vx_info *, void __user *);
17808 +
17809 +#endif /* __KERNEL__ */
17810 +#endif /* _VX_NAMESPACE_CMD_H */
17811 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/network.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/network.h
17812 --- linux-2.6.17.11/include/linux/vserver/network.h     1970-01-01 01:00:00 +0100
17813 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/network.h        2006-08-25 05:47:25 +0200
17814 @@ -0,0 +1,142 @@
17815 +#ifndef _VX_NETWORK_H
17816 +#define _VX_NETWORK_H
17817 +
17818 +#include <linux/types.h>
17819 +
17820 +
17821 +#define MAX_N_CONTEXT  65535   /* Arbitrary limit */
17822 +
17823 +#define NX_DYNAMIC_ID  ((uint32_t)-1)          /* id for dynamic context */
17824 +
17825 +#define NB_IPV4ROOT    16
17826 +
17827 +
17828 +/* network flags */
17829 +
17830 +#define NXF_INFO_LOCK          0x00000001
17831 +
17832 +#define NXF_STATE_SETUP                (1ULL<<32)
17833 +#define NXF_STATE_ADMIN                (1ULL<<34)
17834 +
17835 +#define NXF_SC_HELPER          (1ULL<<36)
17836 +#define NXF_PERSISTENT         (1ULL<<38)
17837 +
17838 +#define NXF_ONE_TIME           (0x0005ULL<<32)
17839 +
17840 +#define NXF_INIT_SET           (NXF_STATE_ADMIN)
17841 +
17842 +
17843 +/* address types */
17844 +
17845 +#define NXA_TYPE_IPV4          1
17846 +#define NXA_TYPE_IPV6          2
17847 +
17848 +#define NXA_MOD_BCAST          (1<<8)
17849 +
17850 +#define NXA_TYPE_ANY           ((uint16_t)-1)
17851 +
17852 +
17853 +#ifdef __KERNEL__
17854 +
17855 +#include <linux/list.h>
17856 +#include <linux/spinlock.h>
17857 +#include <linux/rcupdate.h>
17858 +#include <asm/atomic.h>
17859 +
17860 +
17861 +struct nx_info {
17862 +       struct hlist_node nx_hlist;     /* linked list of nxinfos */
17863 +       nid_t nx_id;                    /* vnet id */
17864 +       atomic_t nx_usecnt;             /* usage count */
17865 +       atomic_t nx_tasks;              /* tasks count */
17866 +       int nx_state;                   /* context state */
17867 +
17868 +       uint64_t nx_flags;              /* network flag word */
17869 +       uint64_t nx_ncaps;              /* network capabilities */
17870 +
17871 +       int nbipv4;
17872 +       __u32 ipv4[NB_IPV4ROOT];        /* Process can only bind to these IPs */
17873 +                                       /* The first one is used to connect */
17874 +                                       /* and for bind any service */
17875 +                                       /* The other must be used explicity */
17876 +       __u32 mask[NB_IPV4ROOT];        /* Netmask for each ipv4 */
17877 +                                       /* Used to select the proper source */
17878 +                                       /* address for sockets */
17879 +       __u32 v4_bcast;                 /* Broadcast address to receive UDP  */
17880 +
17881 +       char nx_name[65];               /* network context name */
17882 +};
17883 +
17884 +
17885 +/* status flags */
17886 +
17887 +#define NXS_HASHED      0x0001
17888 +#define NXS_SHUTDOWN    0x0100
17889 +#define NXS_RELEASED    0x8000
17890 +
17891 +/* check conditions */
17892 +
17893 +#define NX_ADMIN       0x0001
17894 +#define NX_WATCH       0x0002
17895 +#define NX_BLEND       0x0004
17896 +#define NX_HOSTID      0x0008
17897 +
17898 +#define NX_IDENT       0x0010
17899 +#define NX_EQUIV       0x0020
17900 +#define NX_PARENT      0x0040
17901 +#define NX_CHILD       0x0080
17902 +
17903 +#define NX_ARG_MASK    0x00F0
17904 +
17905 +#define NX_DYNAMIC     0x0100
17906 +#define NX_STATIC      0x0200
17907 +
17908 +#define NX_ATR_MASK    0x0F00
17909 +
17910 +
17911 +extern struct nx_info *lookup_nx_info(int);
17912 +
17913 +extern int get_nid_list(int, unsigned int *, int);
17914 +extern int nid_is_hashed(nid_t);
17915 +
17916 +extern int nx_migrate_task(struct task_struct *, struct nx_info *);
17917 +
17918 +extern long vs_net_change(struct nx_info *, unsigned int);
17919 +
17920 +struct in_ifaddr;
17921 +struct net_device;
17922 +
17923 +#ifdef CONFIG_INET
17924 +int ifa_in_nx_info(struct in_ifaddr *, struct nx_info *);
17925 +int dev_in_nx_info(struct net_device *, struct nx_info *);
17926 +
17927 +#else /* CONFIG_INET */
17928 +static inline
17929 +int ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
17930 +{
17931 +       return 1;
17932 +}
17933 +
17934 +static inline
17935 +int dev_in_nx_info(struct net_device *d, struct nx_info *n)
17936 +{
17937 +       return 1;
17938 +}
17939 +#endif /* CONFIG_INET */
17940 +
17941 +struct sock;
17942 +
17943 +#ifdef CONFIG_INET
17944 +int nx_addr_conflict(struct nx_info *, uint32_t, struct sock *);
17945 +#else /* CONFIG_INET */
17946 +static inline
17947 +int nx_addr_conflict(struct nx_info *n, uint32_t a, struct sock *s)
17948 +{
17949 +       return 1;
17950 +}
17951 +#endif /* CONFIG_INET */
17952 +
17953 +#endif /* __KERNEL__ */
17954 +#else  /* _VX_NETWORK_H */
17955 +#warning duplicate inclusion
17956 +#endif /* _VX_NETWORK_H */
17957 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/network_cmd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/network_cmd.h
17958 --- linux-2.6.17.11/include/linux/vserver/network_cmd.h 1970-01-01 01:00:00 +0100
17959 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/network_cmd.h    2006-07-09 19:32:36 +0200
17960 @@ -0,0 +1,89 @@
17961 +#ifndef _VX_NETWORK_CMD_H
17962 +#define _VX_NETWORK_CMD_H
17963 +
17964 +
17965 +/* vinfo commands */
17966 +
17967 +#define VCMD_task_nid          VC_CMD(VINFO, 2, 0)
17968 +
17969 +#ifdef __KERNEL__
17970 +extern int vc_task_nid(uint32_t, void __user *);
17971 +
17972 +#endif /* __KERNEL__ */
17973 +
17974 +#define VCMD_nx_info           VC_CMD(VINFO, 6, 0)
17975 +
17976 +struct vcmd_nx_info_v0 {
17977 +       uint32_t nid;
17978 +       /* more to come */
17979 +};
17980 +
17981 +#ifdef __KERNEL__
17982 +extern int vc_nx_info(struct nx_info *, void __user *);
17983 +
17984 +#endif /* __KERNEL__ */
17985 +
17986 +#define VCMD_net_create_v0     VC_CMD(VNET, 1, 0)
17987 +#define VCMD_net_create                VC_CMD(VNET, 1, 1)
17988 +
17989 +struct  vcmd_net_create {
17990 +       uint64_t flagword;
17991 +};
17992 +
17993 +#define VCMD_net_migrate       VC_CMD(NETMIG, 1, 0)
17994 +
17995 +#define VCMD_net_add           VC_CMD(NETALT, 1, 0)
17996 +#define VCMD_net_remove                VC_CMD(NETALT, 2, 0)
17997 +
17998 +struct vcmd_net_addr_v0 {
17999 +       uint16_t type;
18000 +       uint16_t count;
18001 +       uint32_t ip[4];
18002 +       uint32_t mask[4];
18003 +       /* more to come */
18004 +};
18005 +
18006 +
18007 +#ifdef __KERNEL__
18008 +extern int vc_net_create(uint32_t, void __user *);
18009 +extern int vc_net_migrate(struct nx_info *, void __user *);
18010 +
18011 +extern int vc_net_add(struct nx_info *, void __user *);
18012 +extern int vc_net_remove(struct nx_info *, void __user *);
18013 +
18014 +#endif /* __KERNEL__ */
18015 +
18016 +
18017 +/* flag commands */
18018 +
18019 +#define VCMD_get_nflags                VC_CMD(FLAGS, 5, 0)
18020 +#define VCMD_set_nflags                VC_CMD(FLAGS, 6, 0)
18021 +
18022 +struct vcmd_net_flags_v0 {
18023 +       uint64_t flagword;
18024 +       uint64_t mask;
18025 +};
18026 +
18027 +#ifdef __KERNEL__
18028 +extern int vc_get_nflags(struct nx_info *, void __user *);
18029 +extern int vc_set_nflags(struct nx_info *, void __user *);
18030 +
18031 +#endif /* __KERNEL__ */
18032 +
18033 +
18034 +/* network caps commands */
18035 +
18036 +#define VCMD_get_ncaps         VC_CMD(FLAGS, 7, 0)
18037 +#define VCMD_set_ncaps         VC_CMD(FLAGS, 8, 0)
18038 +
18039 +struct vcmd_net_caps_v0 {
18040 +       uint64_t ncaps;
18041 +       uint64_t cmask;
18042 +};
18043 +
18044 +#ifdef __KERNEL__
18045 +extern int vc_get_ncaps(struct nx_info *, void __user *);
18046 +extern int vc_set_ncaps(struct nx_info *, void __user *);
18047 +
18048 +#endif /* __KERNEL__ */
18049 +#endif /* _VX_CONTEXT_CMD_H */
18050 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/sched.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/sched.h
18051 --- linux-2.6.17.11/include/linux/vserver/sched.h       1970-01-01 01:00:00 +0100
18052 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/sched.h  2006-07-09 17:07:13 +0200
18053 @@ -0,0 +1,26 @@
18054 +#ifndef _VX_SCHED_H
18055 +#define _VX_SCHED_H
18056 +
18057 +
18058 +#ifdef __KERNEL__
18059 +
18060 +struct timespec;
18061 +
18062 +void vx_vsi_uptime(struct timespec *, struct timespec *);
18063 +
18064 +
18065 +struct vx_info;
18066 +
18067 +void vx_update_load(struct vx_info *);
18068 +
18069 +
18070 +int vx_tokens_recalc(struct _vx_sched_pc *,
18071 +       unsigned long *, unsigned long *, int [2]);
18072 +
18073 +void vx_update_sched_param(struct _vx_sched *sched,
18074 +       struct _vx_sched_pc *sched_pc);
18075 +
18076 +#endif /* __KERNEL__ */
18077 +#else  /* _VX_SCHED_H */
18078 +#warning duplicate inclusion
18079 +#endif /* _VX_SCHED_H */
18080 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/sched_cmd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/sched_cmd.h
18081 --- linux-2.6.17.11/include/linux/vserver/sched_cmd.h   1970-01-01 01:00:00 +0100
18082 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/sched_cmd.h      2006-07-09 19:27:34 +0200
18083 @@ -0,0 +1,72 @@
18084 +#ifndef _VX_SCHED_CMD_H
18085 +#define _VX_SCHED_CMD_H
18086 +
18087 +
18088 +/*  sched vserver commands */
18089 +
18090 +#define VCMD_set_sched_v2      VC_CMD(SCHED, 1, 2)
18091 +#define VCMD_set_sched_v3      VC_CMD(SCHED, 1, 3)
18092 +#define VCMD_set_sched         VC_CMD(SCHED, 1, 4)
18093 +
18094 +struct vcmd_set_sched_v2 {
18095 +       int32_t fill_rate;
18096 +       int32_t interval;
18097 +       int32_t tokens;
18098 +       int32_t tokens_min;
18099 +       int32_t tokens_max;
18100 +       uint64_t cpu_mask;
18101 +};
18102 +
18103 +struct vcmd_set_sched_v3 {
18104 +       uint32_t set_mask;
18105 +       int32_t fill_rate;
18106 +       int32_t interval;
18107 +       int32_t tokens;
18108 +       int32_t tokens_min;
18109 +       int32_t tokens_max;
18110 +       int32_t priority_bias;
18111 +};
18112 +
18113 +struct vcmd_set_sched_v4 {
18114 +       uint32_t set_mask;
18115 +       int32_t fill_rate;
18116 +       int32_t interval;
18117 +       int32_t tokens;
18118 +       int32_t tokens_min;
18119 +       int32_t tokens_max;
18120 +       int32_t prio_bias;
18121 +       int32_t cpu_id;
18122 +       int32_t bucket_id;
18123 +};
18124 +
18125 +
18126 +#define VXSM_FILL_RATE         0x0001
18127 +#define VXSM_INTERVAL          0x0002
18128 +#define VXSM_FILL_RATE2                0x0004
18129 +#define VXSM_INTERVAL2         0x0008
18130 +#define VXSM_TOKENS            0x0010
18131 +#define VXSM_TOKENS_MIN                0x0020
18132 +#define VXSM_TOKENS_MAX                0x0040
18133 +#define VXSM_PRIO_BIAS         0x0100
18134 +
18135 +#define VXSM_IDLE_TIME         0x0200
18136 +#define VXSM_FORCE             0x0400
18137 +
18138 +#define        VXSM_V3_MASK            0x0173
18139 +#define        VXSM_SET_MASK           0x01FF
18140 +
18141 +#define VXSM_CPU_ID            0x1000
18142 +#define VXSM_BUCKET_ID         0x2000
18143 +
18144 +#define SCHED_KEEP             (-2)    /* only for v2 */
18145 +
18146 +#ifdef __KERNEL__
18147 +
18148 +#include <linux/compiler.h>
18149 +
18150 +extern int vc_set_sched_v2(struct vx_info *, void __user *);
18151 +extern int vc_set_sched_v3(struct vx_info *, void __user *);
18152 +extern int vc_set_sched(struct vx_info *, void __user *);
18153 +
18154 +#endif /* __KERNEL__ */
18155 +#endif /* _VX_SCHED_CMD_H */
18156 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/sched_def.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/sched_def.h
18157 --- linux-2.6.17.11/include/linux/vserver/sched_def.h   1970-01-01 01:00:00 +0100
18158 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/sched_def.h      2006-07-09 17:07:13 +0200
18159 @@ -0,0 +1,67 @@
18160 +#ifndef _VX_SCHED_DEF_H
18161 +#define _VX_SCHED_DEF_H
18162 +
18163 +#include <linux/spinlock.h>
18164 +#include <linux/jiffies.h>
18165 +#include <linux/cpumask.h>
18166 +#include <asm/atomic.h>
18167 +#include <asm/param.h>
18168 +
18169 +
18170 +/* context sub struct */
18171 +
18172 +struct _vx_sched {
18173 +       spinlock_t tokens_lock;         /* lock for token bucket */
18174 +
18175 +       int tokens;                     /* number of CPU tokens */
18176 +       int fill_rate[2];               /* Fill rate: add X tokens... */
18177 +       int interval[2];                /* Divisor:   per Y jiffies   */
18178 +       int tokens_min;                 /* Limit:     minimum for unhold */
18179 +       int tokens_max;                 /* Limit:     no more than N tokens */
18180 +
18181 +       unsigned update_mask;           /* which features should be updated */
18182 +       cpumask_t update;               /* CPUs which should update */
18183 +
18184 +       int prio_bias;                  /* bias offset for priority */
18185 +       int vavavoom;                   /* last calculated vavavoom */
18186 +};
18187 +
18188 +struct _vx_sched_pc {
18189 +       int tokens;                     /* number of CPU tokens */
18190 +       int flags;                      /* bucket flags */
18191 +
18192 +       int fill_rate[2];               /* Fill rate: add X tokens... */
18193 +       int interval[2];                /* Divisor:   per Y jiffies   */
18194 +       int tokens_min;                 /* Limit:     minimum for unhold */
18195 +       int tokens_max;                 /* Limit:     no more than N tokens */
18196 +
18197 +       unsigned long norm_time;        /* last time accounted */
18198 +       unsigned long idle_time;        /* non linear time for fair sched */
18199 +       unsigned long token_time;       /* token time for accounting */
18200 +       unsigned long onhold;           /* jiffies when put on hold */
18201 +
18202 +       uint64_t user_ticks;            /* token tick events */
18203 +       uint64_t sys_ticks;             /* token tick events */
18204 +       uint64_t hold_ticks;            /* token ticks paused */
18205 +};
18206 +
18207 +
18208 +#define VXSF_ONHOLD    0x0001
18209 +#define VXSF_IDLE_TIME 0x0100
18210 +
18211 +#ifdef CONFIG_VSERVER_DEBUG
18212 +
18213 +static inline void __dump_vx_sched(struct _vx_sched *sched)
18214 +{
18215 +       printk("\t_vx_sched:\n");
18216 +       printk("\t tokens: %4d/%4d, %4d/%4d, %4d, %4d\n",
18217 +               sched->fill_rate[0], sched->interval[0],
18218 +               sched->fill_rate[1], sched->interval[1],
18219 +               sched->tokens_min, sched->tokens_max);
18220 +       printk("\t priority = %4d, %4d\n",
18221 +               sched->prio_bias, sched->vavavoom);
18222 +}
18223 +
18224 +#endif
18225 +
18226 +#endif /* _VX_SCHED_DEF_H */
18227 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/signal.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/signal.h
18228 --- linux-2.6.17.11/include/linux/vserver/signal.h      1970-01-01 01:00:00 +0100
18229 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/signal.h 2006-07-09 17:07:13 +0200
18230 @@ -0,0 +1,14 @@
18231 +#ifndef _VX_SIGNAL_H
18232 +#define _VX_SIGNAL_H
18233 +
18234 +
18235 +#ifdef __KERNEL__
18236 +
18237 +struct vx_info;
18238 +
18239 +int vx_info_kill(struct vx_info *, int, int);
18240 +
18241 +#endif /* __KERNEL__ */
18242 +#else  /* _VX_SIGNAL_H */
18243 +#warning duplicate inclusion
18244 +#endif /* _VX_SIGNAL_H */
18245 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/signal_cmd.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/signal_cmd.h
18246 --- linux-2.6.17.11/include/linux/vserver/signal_cmd.h  1970-01-01 01:00:00 +0100
18247 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/signal_cmd.h     2006-07-09 19:27:47 +0200
18248 @@ -0,0 +1,26 @@
18249 +#ifndef _VX_SIGNAL_CMD_H
18250 +#define _VX_SIGNAL_CMD_H
18251 +
18252 +
18253 +/*  signalling vserver commands */
18254 +
18255 +#define VCMD_ctx_kill          VC_CMD(PROCTRL, 1, 0)
18256 +#define VCMD_wait_exit         VC_CMD(EVENT, 99, 0)
18257 +
18258 +struct vcmd_ctx_kill_v0 {
18259 +       int32_t pid;
18260 +       int32_t sig;
18261 +};
18262 +
18263 +struct vcmd_wait_exit_v0 {
18264 +       int32_t reboot_cmd;
18265 +       int32_t exit_code;
18266 +};
18267 +
18268 +#ifdef __KERNEL__
18269 +
18270 +extern int vc_ctx_kill(struct vx_info *, void __user *);
18271 +extern int vc_wait_exit(struct vx_info *, void __user *);
18272 +
18273 +#endif /* __KERNEL__ */
18274 +#endif /* _VX_SIGNAL_CMD_H */
18275 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/switch.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/switch.h
18276 --- linux-2.6.17.11/include/linux/vserver/switch.h      1970-01-01 01:00:00 +0100
18277 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/switch.h 2006-07-30 16:32:52 +0200
18278 @@ -0,0 +1,100 @@
18279 +#ifndef _VX_SWITCH_H
18280 +#define _VX_SWITCH_H
18281 +
18282 +#include <linux/types.h>
18283 +
18284 +
18285 +#define VC_CATEGORY(c)         (((c) >> 24) & 0x3F)
18286 +#define VC_COMMAND(c)          (((c) >> 16) & 0xFF)
18287 +#define VC_VERSION(c)          ((c) & 0xFFF)
18288 +
18289 +#define VC_CMD(c,i,v)          ((((VC_CAT_ ## c) & 0x3F) << 24) \
18290 +                               | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
18291 +
18292 +/*
18293 +
18294 +  Syscall Matrix V2.8
18295 +
18296 +        |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
18297 +        |STATS  |DESTROY|ALTER  |CHANGE |LIMIT  |TEST   | |       |       |
18298 +        |INFO   |SETUP  |       |MOVE   |       |       | |       |       |
18299 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18300 +  SYSTEM |VERSION|VSETUP |VHOST  |       |       |       | |DEVICES|       |
18301 +  HOST   |     00|     01|     02|     03|     04|     05| |     06|     07|
18302 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18303 +  CPU    |       |VPROC  |PROCALT|PROCMIG|PROCTRL|       | |SCHED. |       |
18304 +  PROCESS|     08|     09|     10|     11|     12|     13| |     14|     15|
18305 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18306 +  MEMORY |       |       |       |       |       |       | |SWAP   |       |
18307 +        |     16|     17|     18|     19|     20|     21| |     22|     23|
18308 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18309 +  NETWORK|       |VNET   |NETALT |NETMIG |NETCTL |       | |SERIAL |       |
18310 +        |     24|     25|     26|     27|     28|     29| |     30|     31|
18311 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18312 +  DISK   |       |       |       |       |DLIMIT |       | |INODE  |       |
18313 +  VFS    |     32|     33|     34|     35|     36|     37| |     38|     39|
18314 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18315 +  OTHER  |VSTAT  |       |       |       |       |       | |VINFO  |       |
18316 +        |     40|     41|     42|     43|     44|     45| |     46|     47|
18317 +  =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
18318 +  SPECIAL|EVENT  |       |       |       |FLAGS  |       | |       |       |
18319 +        |     48|     49|     50|     51|     52|     53| |     54|     55|
18320 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18321 +  SPECIAL|DEBUG  |       |       |       |RLIMIT |SYSCALL| |       |COMPAT |
18322 +        |     56|     57|     58|     59|     60|TEST 61| |     62|     63|
18323 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18324 +
18325 +*/
18326 +
18327 +#define VC_CAT_VERSION         0
18328 +
18329 +#define VC_CAT_VSETUP          1
18330 +#define VC_CAT_VHOST           2
18331 +
18332 +#define VC_CAT_VPROC           9
18333 +#define VC_CAT_PROCALT         10
18334 +#define VC_CAT_PROCMIG         11
18335 +#define VC_CAT_PROCTRL         12
18336 +
18337 +#define VC_CAT_SCHED           14
18338 +
18339 +#define VC_CAT_VNET            25
18340 +#define VC_CAT_NETALT          26
18341 +#define VC_CAT_NETMIG          27
18342 +#define VC_CAT_NETCTRL         28
18343 +
18344 +#define VC_CAT_DLIMIT          36
18345 +#define VC_CAT_INODE           38
18346 +
18347 +#define VC_CAT_VSTAT           40
18348 +#define VC_CAT_VINFO           46
18349 +#define VC_CAT_EVENT           48
18350 +
18351 +#define VC_CAT_FLAGS           52
18352 +#define VC_CAT_DEBUG           56
18353 +#define VC_CAT_RLIMIT          60
18354 +
18355 +#define VC_CAT_SYSTEST         61
18356 +#define VC_CAT_COMPAT          63
18357 +
18358 +/*  interface version */
18359 +
18360 +#define VCI_VERSION            0x00020102
18361 +#define VCI_LEGACY_VERSION     0x000100FF
18362 +
18363 +/*  query version */
18364 +
18365 +#define VCMD_get_version       VC_CMD(VERSION, 0, 0)
18366 +#define VCMD_get_vci           VC_CMD(VERSION, 1, 0)
18367 +
18368 +
18369 +#ifdef __KERNEL__
18370 +
18371 +#include <linux/errno.h>
18372 +
18373 +
18374 +#else  /* __KERNEL__ */
18375 +#define __user
18376 +#endif /* __KERNEL__ */
18377 +
18378 +#endif /* _VX_SWITCH_H */
18379 diff -NurpP --minimal linux-2.6.17.11/include/linux/vserver/tag.h linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/tag.h
18380 --- linux-2.6.17.11/include/linux/vserver/tag.h 1970-01-01 01:00:00 +0100
18381 +++ linux-2.6.17.11-vs2.1.1-rc31/include/linux/vserver/tag.h    2006-07-09 17:07:13 +0200
18382 @@ -0,0 +1,153 @@
18383 +#ifndef _DX_TAG_H
18384 +#define _DX_TAG_H
18385 +
18386 +
18387 +#define DX_TAG(in)     (IS_TAGGED(in))
18388 +
18389 +
18390 +#ifdef CONFIG_DX_TAG_NFSD
18391 +#define DX_TAG_NFSD    1
18392 +#else
18393 +#define DX_TAG_NFSD    0
18394 +#endif
18395 +
18396 +
18397 +#ifdef CONFIG_TAGGING_NONE
18398 +
18399 +#define MAX_UID                0xFFFFFFFF
18400 +#define MAX_GID                0xFFFFFFFF
18401 +
18402 +#define INOTAG_TAG(cond, uid, gid, tag)        (0)
18403 +
18404 +#define TAGINO_UID(cond, uid, tag)     (uid)
18405 +#define TAGINO_GID(cond, gid, tag)     (gid)
18406 +
18407 +#endif
18408 +
18409 +
18410 +#ifdef CONFIG_TAGGING_GID16
18411 +
18412 +#define MAX_UID                0xFFFFFFFF
18413 +#define MAX_GID                0x0000FFFF
18414 +
18415 +#define INOTAG_TAG(cond, uid, gid, tag)        \
18416 +       ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
18417 +
18418 +#define TAGINO_UID(cond, uid, tag)     (uid)
18419 +#define TAGINO_GID(cond, gid, tag)     \
18420 +       ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
18421 +
18422 +#endif
18423 +
18424 +
18425 +#ifdef CONFIG_TAGGING_ID24
18426 +
18427 +#define MAX_UID                0x00FFFFFF
18428 +#define MAX_GID                0x00FFFFFF
18429 +
18430 +#define INOTAG_TAG(cond, uid, gid, tag)        \
18431 +       ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
18432 +
18433 +#define TAGINO_UID(cond, uid, tag)     \
18434 +       ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
18435 +#define TAGINO_GID(cond, gid, tag)     \
18436 +       ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
18437 +
18438 +#endif
18439 +
18440 +
18441 +#ifdef CONFIG_TAGGING_UID16
18442 +
18443 +#define MAX_UID                0x0000FFFF
18444 +#define MAX_GID                0xFFFFFFFF
18445 +
18446 +#define INOTAG_TAG(cond, uid, gid, tag)        \
18447 +       ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
18448 +
18449 +#define TAGINO_UID(cond, uid, tag)     \
18450 +       ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
18451 +#define TAGINO_GID(cond, gid, tag)     (gid)
18452 +
18453 +#endif
18454 +
18455 +
18456 +#ifdef CONFIG_TAGGING_INTERN
18457 +
18458 +#define MAX_UID                0xFFFFFFFF
18459 +#define MAX_GID                0xFFFFFFFF
18460 +
18461 +#define INOTAG_TAG(cond, uid, gid, tag)        \
18462 +       ((cond) ? (tag) : 0)
18463 +
18464 +#define TAGINO_UID(cond, uid, tag)     (uid)
18465 +#define TAGINO_GID(cond, gid, tag)     (gid)
18466 +
18467 +#endif
18468 +
18469 +
18470 +#ifdef CONFIG_TAGGING_RUNTIME
18471 +
18472 +#define MAX_UID                0xFFFFFFFF
18473 +#define MAX_GID                0xFFFFFFFF
18474 +
18475 +#define INOTAG_TAG(cond, uid, gid, tag)        (0)
18476 +
18477 +#define TAGINO_UID(cond, uid, tag)     (uid)
18478 +#define TAGINO_GID(cond, gid, tag)     (gid)
18479 +
18480 +#endif
18481 +
18482 +
18483 +#ifndef CONFIG_TAGGING_NONE
18484 +#define dx_current_fstag(sb)   \
18485 +       ((sb)->s_flags & MS_TAGGED ? dx_current_tag(): 0)
18486 +#else
18487 +#define dx_current_fstag(sb)   (0)
18488 +#endif
18489 +
18490 +#ifndef CONFIG_TAGGING_INTERN
18491 +#define TAGINO_TAG(cond, tag)  (0)
18492 +#else
18493 +#define TAGINO_TAG(cond, tag)  ((cond) ? (tag) : 0)
18494 +#endif
18495 +
18496 +#define INOTAG_UID(cond, uid, gid)     \
18497 +       ((cond) ? ((uid) & MAX_UID) : (uid))
18498 +#define INOTAG_GID(cond, uid, gid)     \
18499 +       ((cond) ? ((gid) & MAX_GID) : (gid))
18500 +
18501 +
18502 +static inline uid_t dx_map_uid(uid_t uid)
18503 +{
18504 +       if ((uid > MAX_UID) && (uid != -1))
18505 +               uid = -2;
18506 +       return (uid & MAX_UID);
18507 +}
18508 +
18509 +static inline gid_t dx_map_gid(gid_t gid)
18510 +{
18511 +       if ((gid > MAX_GID) && (gid != -1))
18512 +               gid = -2;
18513 +       return (gid & MAX_GID);
18514 +}
18515 +
18516 +
18517 +#ifdef CONFIG_VSERVER_LEGACY
18518 +#define FIOC_GETTAG    _IOR('x', 1, long)
18519 +#define FIOC_SETTAG    _IOW('x', 2, long)
18520 +#define FIOC_SETTAGJ   _IOW('x', 3, long)
18521 +#endif
18522 +
18523 +#ifdef CONFIG_PROPAGATE
18524 +
18525 +int dx_parse_tag(char *string, tag_t *tag, int remove);
18526 +
18527 +void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
18528 +
18529 +#define dx_propagate_tag(n,i)  __dx_propagate_tag(n,i)
18530 +
18531 +#else
18532 +#define dx_propagate_tag(n,i)  do { } while (0)
18533 +#endif
18534 +
18535 +#endif /* _DX_TAG_H */
18536 diff -NurpP --minimal linux-2.6.17.11/include/net/af_unix.h linux-2.6.17.11-vs2.1.1-rc31/include/net/af_unix.h
18537 --- linux-2.6.17.11/include/net/af_unix.h       2006-06-18 04:55:27 +0200
18538 +++ linux-2.6.17.11-vs2.1.1-rc31/include/net/af_unix.h  2006-08-06 06:04:49 +0200
18539 @@ -18,9 +18,9 @@ extern spinlock_t unix_table_lock;
18540  
18541  extern atomic_t unix_tot_inflight;
18542  
18543 -static inline struct sock *first_unix_socket(int *i)
18544 +static inline struct sock *next_unix_socket_table(int *i)
18545  {
18546 -       for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
18547 +       for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
18548                 if (!hlist_empty(&unix_socket_table[*i]))
18549                         return __sk_head(&unix_socket_table[*i]);
18550         }
18551 @@ -29,16 +29,19 @@ static inline struct sock *first_unix_so
18552  
18553  static inline struct sock *next_unix_socket(int *i, struct sock *s)
18554  {
18555 -       struct sock *next = sk_next(s);
18556 -       /* More in this chain? */
18557 -       if (next)
18558 -               return next;
18559 -       /* Look for next non-empty chain. */
18560 -       for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
18561 -               if (!hlist_empty(&unix_socket_table[*i]))
18562 -                       return __sk_head(&unix_socket_table[*i]);
18563 -       }
18564 -       return NULL;
18565 +       do {
18566 +               if (s)
18567 +                       s = sk_next(s);
18568 +               if (!s)
18569 +                       s = next_unix_socket_table(i);
18570 +       } while (s && !vx_check(s->sk_xid, VX_WATCH_P|VX_IDENT));
18571 +       return s;
18572 +}
18573 +
18574 +static inline struct sock *first_unix_socket(int *i)
18575 +{
18576 +       *i = 0;
18577 +       return next_unix_socket(i, NULL);
18578  }
18579  
18580  #define forall_unix_sockets(i, s) \
18581 diff -NurpP --minimal linux-2.6.17.11/include/net/inet_hashtables.h linux-2.6.17.11-vs2.1.1-rc31/include/net/inet_hashtables.h
18582 --- linux-2.6.17.11/include/net/inet_hashtables.h       2006-04-09 13:49:58 +0200
18583 +++ linux-2.6.17.11-vs2.1.1-rc31/include/net/inet_hashtables.h  2006-07-09 17:07:13 +0200
18584 @@ -272,6 +272,25 @@ static inline int inet_iif(const struct 
18585         return ((struct rtable *)skb->dst)->rt_iif;
18586  }
18587  
18588 +/*
18589 + *      Check if a given address matches for an inet socket
18590 + *
18591 + *      nxi:   the socket's nx_info if any
18592 + *      addr:  to be verified address
18593 + *      saddr: socket addresses
18594 + */
18595 +static inline int inet_addr_match (
18596 +       struct nx_info *nxi,
18597 +       uint32_t addr,
18598 +       uint32_t saddr)
18599 +{
18600 +       if (addr && (saddr == addr))
18601 +               return 1;
18602 +       if (!saddr)
18603 +               return addr_in_nx_info(nxi, addr);
18604 +       return 0;
18605 +}
18606 +
18607  extern struct sock *__inet_lookup_listener(const struct hlist_head *head,
18608                                            const u32 daddr,
18609                                            const unsigned short hnum,
18610 @@ -292,7 +311,7 @@ static inline struct sock *
18611                 const struct inet_sock *inet = inet_sk((sk = __sk_head(head)));
18612  
18613                 if (inet->num == hnum && !sk->sk_node.next &&
18614 -                   (!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
18615 +                   inet_addr_match(sk->sk_nx_info, daddr, inet->rcv_saddr) &&
18616                     (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
18617                     !sk->sk_bound_dev_if)
18618                         goto sherry_cache;
18619 diff -NurpP --minimal linux-2.6.17.11/include/net/inet_sock.h linux-2.6.17.11-vs2.1.1-rc31/include/net/inet_sock.h
18620 --- linux-2.6.17.11/include/net/inet_sock.h     2006-04-09 13:49:58 +0200
18621 +++ linux-2.6.17.11-vs2.1.1-rc31/include/net/inet_sock.h        2006-07-09 17:07:13 +0200
18622 @@ -115,6 +115,7 @@ struct inet_sock {
18623         /* Socket demultiplex comparisons on incoming packets. */
18624         __u32                   daddr;
18625         __u32                   rcv_saddr;
18626 +       __u32                   rcv_saddr2;     /* Second bound ipv4 addr, for ipv4root */
18627         __u16                   dport;
18628         __u16                   num;
18629         __u32                   saddr;
18630 diff -NurpP --minimal linux-2.6.17.11/include/net/inet_timewait_sock.h linux-2.6.17.11-vs2.1.1-rc31/include/net/inet_timewait_sock.h
18631 --- linux-2.6.17.11/include/net/inet_timewait_sock.h    2006-06-18 04:55:27 +0200
18632 +++ linux-2.6.17.11-vs2.1.1-rc31/include/net/inet_timewait_sock.h       2006-07-09 17:07:13 +0200
18633 @@ -116,6 +116,10 @@ struct inet_timewait_sock {
18634  #define tw_refcnt              __tw_common.skc_refcnt
18635  #define tw_hash                        __tw_common.skc_hash
18636  #define tw_prot                        __tw_common.skc_prot
18637 +#define tw_xid         __tw_common.skc_xid
18638 +#define tw_vx_info             __tw_common.skc_vx_info
18639 +#define tw_nid         __tw_common.skc_nid
18640 +#define tw_nx_info             __tw_common.skc_nx_info
18641         volatile unsigned char  tw_substate;
18642         /* 3 bits hole, try to pack */
18643         unsigned char           tw_rcv_wscale;
18644 diff -NurpP --minimal linux-2.6.17.11/include/net/route.h linux-2.6.17.11-vs2.1.1-rc31/include/net/route.h
18645 --- linux-2.6.17.11/include/net/route.h 2006-06-18 04:55:28 +0200
18646 +++ linux-2.6.17.11-vs2.1.1-rc31/include/net/route.h    2006-07-09 17:07:13 +0200
18647 @@ -28,11 +28,14 @@
18648  #include <net/dst.h>
18649  #include <net/inetpeer.h>
18650  #include <net/flow.h>
18651 +#include <net/inet_sock.h>
18652  #include <linux/in_route.h>
18653  #include <linux/rtnetlink.h>
18654  #include <linux/route.h>
18655  #include <linux/ip.h>
18656  #include <linux/cache.h>
18657 +#include <linux/vs_network.h>
18658 +#include <linux/in.h>
18659  
18660  #ifndef __KERNEL__
18661  #warning This file is not supposed to be used outside of kernel.
18662 @@ -144,6 +147,59 @@ static inline char rt_tos2priority(u8 to
18663         return ip_tos2prio[IPTOS_TOS(tos)>>1];
18664  }
18665  
18666 +#define IPI_LOOPBACK   htonl(INADDR_LOOPBACK)
18667 +
18668 +static inline int ip_find_src(struct nx_info *nxi, struct rtable **rp, struct flowi *fl)
18669 +{
18670 +       int err;
18671 +       int i, n = nxi->nbipv4;
18672 +       u32 ipv4root = nxi->ipv4[0];
18673 +
18674 +       if (ipv4root == 0)
18675 +               return 0;
18676 +
18677 +       if (fl->fl4_src == 0) {
18678 +               if (n > 1) {
18679 +                       u32 foundsrc;
18680 +
18681 +                       err = __ip_route_output_key(rp, fl);
18682 +                       if (err) {
18683 +                               fl->fl4_src = ipv4root;
18684 +                               err = __ip_route_output_key(rp, fl);
18685 +                       }
18686 +                       if (err)
18687 +                               return err;
18688 +
18689 +                       foundsrc = (*rp)->rt_src;
18690 +                       ip_rt_put(*rp);
18691 +
18692 +                       for (i=0; i<n; i++){
18693 +                               u32 mask = nxi->mask[i];
18694 +                               u32 ipv4 = nxi->ipv4[i];
18695 +                               u32 net4 = ipv4 & mask;
18696 +
18697 +                               if (foundsrc == ipv4) {
18698 +                                       fl->fl4_src = ipv4;
18699 +                                       break;
18700 +                               }
18701 +                               if (!fl->fl4_src && (foundsrc & mask) == net4)
18702 +                                       fl->fl4_src = ipv4;
18703 +                       }
18704 +               }
18705 +               if (fl->fl4_src == 0)
18706 +                       fl->fl4_src = (fl->fl4_dst == IPI_LOOPBACK)
18707 +                               ? IPI_LOOPBACK : ipv4root;
18708 +       } else {
18709 +               for (i=0; i<n; i++) {
18710 +                       if (nxi->ipv4[i] == fl->fl4_src)
18711 +                               break;
18712 +               }
18713 +               if (i == n)
18714 +                       return -EPERM;
18715 +       }
18716 +       return 0;
18717 +}
18718 +
18719  static inline int ip_route_connect(struct rtable **rp, u32 dst,
18720                                    u32 src, u32 tos, int oif, u8 protocol,
18721                                    u16 sport, u16 dport, struct sock *sk)
18722 @@ -158,7 +214,27 @@ static inline int ip_route_connect(struc
18723                                          .dport = dport } } };
18724  
18725         int err;
18726 -       if (!dst || !src) {
18727 +       struct nx_info *nx_info = current->nx_info;
18728 +
18729 +       if (sk)
18730 +               nx_info = sk->sk_nx_info;
18731 +       vxdprintk(VXD_CBIT(net, 4),
18732 +               "ip_route_connect(%p) %p,%p;%lx",
18733 +               sk, nx_info, sk->sk_socket,
18734 +               (sk->sk_socket?sk->sk_socket->flags:0));
18735 +
18736 +       if (nx_info) {
18737 +               err = ip_find_src(nx_info, rp, &fl);
18738 +               if (err)
18739 +                       return err;
18740 +               if (fl.fl4_dst == IPI_LOOPBACK && !vx_check(0, VX_ADMIN))
18741 +                       fl.fl4_dst = nx_info->ipv4[0];
18742 +#ifdef CONFIG_VSERVER_REMAP_SADDR
18743 +               if (fl.fl4_src == IPI_LOOPBACK && !vx_check(0, VX_ADMIN))
18744 +                       fl.fl4_src = nx_info->ipv4[0];
18745 +#endif
18746 +       }
18747 +       if (!fl.fl4_dst || !fl.fl4_src) {
18748                 err = __ip_route_output_key(rp, &fl);
18749                 if (err)
18750                         return err;
18751 diff -NurpP --minimal linux-2.6.17.11/include/net/sock.h linux-2.6.17.11-vs2.1.1-rc31/include/net/sock.h
18752 --- linux-2.6.17.11/include/net/sock.h  2006-06-18 04:55:28 +0200
18753 +++ linux-2.6.17.11-vs2.1.1-rc31/include/net/sock.h     2006-08-17 01:24:55 +0200
18754 @@ -115,6 +115,10 @@ struct sock_common {
18755         atomic_t                skc_refcnt;
18756         unsigned int            skc_hash;
18757         struct proto            *skc_prot;
18758 +       xid_t                   skc_xid;
18759 +       struct vx_info          *skc_vx_info;
18760 +       nid_t                   skc_nid;
18761 +       struct nx_info          *skc_nx_info;
18762  };
18763  
18764  /**
18765 @@ -189,6 +193,10 @@ struct sock {
18766  #define sk_refcnt              __sk_common.skc_refcnt
18767  #define sk_hash                        __sk_common.skc_hash
18768  #define sk_prot                        __sk_common.skc_prot
18769 +#define sk_xid                 __sk_common.skc_xid
18770 +#define sk_vx_info             __sk_common.skc_vx_info
18771 +#define sk_nid                 __sk_common.skc_nid
18772 +#define sk_nx_info             __sk_common.skc_nx_info
18773         unsigned char           sk_shutdown : 2,
18774                                 sk_no_check : 2,
18775                                 sk_userlocks : 4;
18776 diff -NurpP --minimal linux-2.6.17.11/init/version.c linux-2.6.17.11-vs2.1.1-rc31/init/version.c
18777 --- linux-2.6.17.11/init/version.c      2005-03-02 12:39:08 +0100
18778 +++ linux-2.6.17.11-vs2.1.1-rc31/init/version.c 2006-07-09 17:07:13 +0200
18779 @@ -31,3 +31,8 @@ EXPORT_SYMBOL(system_utsname);
18780  const char linux_banner[] =
18781         "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
18782         LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
18783 +
18784 +const char vx_linux_banner[] =
18785 +       "Linux version %s (" LINUX_COMPILE_BY "@"
18786 +       LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") %s\n";
18787 +
18788 diff -NurpP --minimal linux-2.6.17.11/ipc/mqueue.c linux-2.6.17.11-vs2.1.1-rc31/ipc/mqueue.c
18789 --- linux-2.6.17.11/ipc/mqueue.c        2006-06-18 04:55:30 +0200
18790 +++ linux-2.6.17.11-vs2.1.1-rc31/ipc/mqueue.c   2006-07-09 17:07:13 +0200
18791 @@ -26,6 +26,8 @@
18792  #include <linux/syscalls.h>
18793  #include <linux/signal.h>
18794  #include <linux/mutex.h>
18795 +#include <linux/vs_context.h>
18796 +#include <linux/vs_limit.h>
18797  
18798  #include <net/sock.h>
18799  #include "util.h"
18800 @@ -149,17 +151,20 @@ static struct inode *mqueue_get_inode(st
18801                         spin_lock(&mq_lock);
18802                         if (u->mq_bytes + mq_bytes < u->mq_bytes ||
18803                             u->mq_bytes + mq_bytes >
18804 -                           p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
18805 +                           p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur ||
18806 +                           !vx_ipcmsg_avail(p->vx_info, mq_bytes)) {
18807                                 spin_unlock(&mq_lock);
18808                                 goto out_inode;
18809                         }
18810                         u->mq_bytes += mq_bytes;
18811 +                       vx_ipcmsg_add(p->vx_info, u, mq_bytes);
18812                         spin_unlock(&mq_lock);
18813  
18814                         info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
18815                         if (!info->messages) {
18816                                 spin_lock(&mq_lock);
18817                                 u->mq_bytes -= mq_bytes;
18818 +                               vx_ipcmsg_sub(p->vx_info, u, mq_bytes);
18819                                 spin_unlock(&mq_lock);
18820                                 goto out_inode;
18821                         }
18822 @@ -257,10 +262,14 @@ static void mqueue_delete_inode(struct i
18823                    (info->attr.mq_maxmsg * info->attr.mq_msgsize));
18824         user = info->user;
18825         if (user) {
18826 +               struct vx_info *vxi = lookup_vx_info(user->xid);
18827 +
18828                 spin_lock(&mq_lock);
18829                 user->mq_bytes -= mq_bytes;
18830 +               vx_ipcmsg_sub(vxi, user, mq_bytes);
18831                 queues_count--;
18832                 spin_unlock(&mq_lock);
18833 +               put_vx_info(vxi);
18834                 free_uid(user);
18835         }
18836  }
18837 @@ -739,7 +748,7 @@ asmlinkage long sys_mq_unlink(const char
18838         if (inode)
18839                 atomic_inc(&inode->i_count);
18840  
18841 -       err = vfs_unlink(dentry->d_parent->d_inode, dentry);
18842 +       err = vfs_unlink(dentry->d_parent->d_inode, dentry, NULL);
18843  out_err:
18844         dput(dentry);
18845  
18846 diff -NurpP --minimal linux-2.6.17.11/ipc/msg.c linux-2.6.17.11-vs2.1.1-rc31/ipc/msg.c
18847 --- linux-2.6.17.11/ipc/msg.c   2006-06-18 04:55:30 +0200
18848 +++ linux-2.6.17.11-vs2.1.1-rc31/ipc/msg.c      2006-08-06 06:15:35 +0200
18849 @@ -105,6 +105,7 @@ static int newque (key_t key, int msgflg
18850  
18851         msq->q_perm.mode = (msgflg & S_IRWXUGO);
18852         msq->q_perm.key = key;
18853 +       msq->q_perm.xid = vx_current_xid();
18854  
18855         msq->q_perm.security = NULL;
18856         retval = security_msg_queue_alloc(msq);
18857 @@ -826,6 +827,9 @@ static int sysvipc_msg_proc_show(struct 
18858  {
18859         struct msg_queue *msq = it;
18860  
18861 +       if (!vx_check(msq->q_perm.xid, VX_WATCH_P|VX_IDENT))
18862 +               return 0;
18863 +
18864         return seq_printf(s,
18865                           "%10d %10d  %4o  %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
18866                           msq->q_perm.key,
18867 diff -NurpP --minimal linux-2.6.17.11/ipc/sem.c linux-2.6.17.11-vs2.1.1-rc31/ipc/sem.c
18868 --- linux-2.6.17.11/ipc/sem.c   2006-06-18 04:55:30 +0200
18869 +++ linux-2.6.17.11-vs2.1.1-rc31/ipc/sem.c      2006-08-06 06:15:49 +0200
18870 @@ -79,6 +79,7 @@
18871  #include <linux/capability.h>
18872  #include <linux/seq_file.h>
18873  #include <linux/mutex.h>
18874 +#include <linux/vs_limit.h>
18875  
18876  #include <asm/uaccess.h>
18877  #include "util.h"
18878 @@ -184,6 +185,7 @@ static int newary (key_t key, int nsems,
18879  
18880         sma->sem_perm.mode = (semflg & S_IRWXUGO);
18881         sma->sem_perm.key = key;
18882 +       sma->sem_perm.xid = vx_current_xid();
18883  
18884         sma->sem_perm.security = NULL;
18885         retval = security_sem_alloc(sma);
18886 @@ -199,6 +201,8 @@ static int newary (key_t key, int nsems,
18887                 return -ENOSPC;
18888         }
18889         used_sems += nsems;
18890 +       vx_semary_inc(sma);
18891 +       vx_nsems_add(sma, nsems);
18892  
18893         sma->sem_id = sem_buildid(id, sma->sem_perm.seq);
18894         sma->sem_base = (struct sem *) &sma[1];
18895 @@ -477,6 +481,8 @@ static void freeary (struct sem_array *s
18896         sem_unlock(sma);
18897  
18898         used_sems -= sma->sem_nsems;
18899 +       vx_nsems_sub(sma, sma->sem_nsems);
18900 +       vx_semary_dec(sma);
18901         size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
18902         security_sem_free(sma);
18903         ipc_rcu_putref(sma);
18904 @@ -1345,6 +1351,9 @@ static int sysvipc_sem_proc_show(struct 
18905  {
18906         struct sem_array *sma = it;
18907  
18908 +       if (!vx_check(sma->sem_perm.xid, VX_WATCH_P|VX_IDENT))
18909 +               return 0;
18910 +
18911         return seq_printf(s,
18912                           "%10d %10d  %4o %10lu %5u %5u %5u %5u %10lu %10lu\n",
18913                           sma->sem_perm.key,
18914 diff -NurpP --minimal linux-2.6.17.11/ipc/shm.c linux-2.6.17.11-vs2.1.1-rc31/ipc/shm.c
18915 --- linux-2.6.17.11/ipc/shm.c   2006-06-18 04:55:30 +0200
18916 +++ linux-2.6.17.11-vs2.1.1-rc31/ipc/shm.c      2006-08-06 06:16:05 +0200
18917 @@ -33,6 +33,8 @@
18918  #include <linux/ptrace.h>
18919  #include <linux/seq_file.h>
18920  #include <linux/mutex.h>
18921 +#include <linux/vs_context.h>
18922 +#include <linux/vs_limit.h>
18923  
18924  #include <asm/uaccess.h>
18925  
18926 @@ -117,7 +119,12 @@ static void shm_open (struct vm_area_str
18927   */
18928  static void shm_destroy (struct shmid_kernel *shp)
18929  {
18930 -       shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
18931 +       struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
18932 +       int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
18933 +
18934 +       vx_ipcshm_sub(vxi, shp, numpages);
18935 +       shm_tot -= numpages;
18936 +
18937         shm_rmid (shp->id);
18938         shm_unlock(shp);
18939         if (!is_file_hugepages(shp->shm_file))
18940 @@ -127,6 +134,7 @@ static void shm_destroy (struct shmid_ke
18941                                                 shp->mlock_user);
18942         fput (shp->shm_file);
18943         security_shm_free(shp);
18944 +       put_vx_info(vxi);
18945         ipc_rcu_putref(shp);
18946  }
18947  
18948 @@ -203,12 +211,15 @@ static int newseg (key_t key, int shmflg
18949  
18950         if (shm_tot + numpages >= shm_ctlall)
18951                 return -ENOSPC;
18952 +       if (!vx_ipcshm_avail(current->vx_info, numpages))
18953 +               return -ENOSPC;
18954  
18955         shp = ipc_rcu_alloc(sizeof(*shp));
18956         if (!shp)
18957                 return -ENOMEM;
18958  
18959         shp->shm_perm.key = key;
18960 +       shp->shm_perm.xid = vx_current_xid();
18961         shp->shm_perm.mode = (shmflg & S_IRWXUGO);
18962         shp->mlock_user = NULL;
18963  
18964 @@ -259,6 +270,7 @@ static int newseg (key_t key, int shmflg
18965                 file->f_op = &shm_file_operations;
18966  
18967         shm_tot += numpages;
18968 +       vx_ipcshm_add(current->vx_info, key, numpages);
18969         shm_unlock(shp);
18970         return shp->id;
18971  
18972 @@ -914,6 +926,9 @@ static int sysvipc_shm_proc_show(struct 
18973  #define SMALL_STRING "%10d %10d  %4o %10u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
18974  #define BIG_STRING   "%10d %10d  %4o %21u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
18975  
18976 +       if (!vx_check(shp->shm_perm.xid, VX_WATCH_P|VX_IDENT))
18977 +               return 0;
18978 +
18979         if (sizeof(size_t) <= sizeof(int))
18980                 format = SMALL_STRING;
18981         else
18982 diff -NurpP --minimal linux-2.6.17.11/ipc/util.c linux-2.6.17.11-vs2.1.1-rc31/ipc/util.c
18983 --- linux-2.6.17.11/ipc/util.c  2006-06-18 04:55:30 +0200
18984 +++ linux-2.6.17.11-vs2.1.1-rc31/ipc/util.c     2006-08-06 06:19:33 +0200
18985 @@ -158,7 +158,9 @@ int ipc_findkey(struct ipc_ids* ids, key
18986          */
18987         for (id = 0; id <= max_id; id++) {
18988                 p = ids->entries->p[id];
18989 -               if(p==NULL)
18990 +               if (p==NULL)
18991 +                       continue;
18992 +               if (!vx_check(p->xid, VX_WATCH_P|VX_IDENT))
18993                         continue;
18994                 if (key == p->key)
18995                         return id;
18996 @@ -471,6 +473,9 @@ int ipcperms (struct kern_ipc_perm *ipcp
18997  
18998         if (unlikely((err = audit_ipc_obj(ipcp))))
18999                 return err;
19000 +
19001 +       if (!vx_check(ipcp->xid, VX_WATCH_P|VX_IDENT)) /* maybe just VX_IDENT? */
19002 +               return -1;
19003         requested_mode = (flag >> 6) | (flag >> 3) | flag;
19004         granted_mode = ipcp->mode;
19005         if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
19006 diff -NurpP --minimal linux-2.6.17.11/kernel/Makefile linux-2.6.17.11-vs2.1.1-rc31/kernel/Makefile
19007 --- linux-2.6.17.11/kernel/Makefile     2006-06-18 04:55:30 +0200
19008 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/Makefile        2006-07-09 17:07:13 +0200
19009 @@ -10,6 +10,8 @@ obj-y     = sched.o fork.o exec_domain.o
19010             kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
19011             hrtimer.o
19012  
19013 +obj-y    += vserver/
19014 +
19015  obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
19016  obj-$(CONFIG_FUTEX) += futex.o
19017  ifeq ($(CONFIG_COMPAT),y)
19018 diff -NurpP --minimal linux-2.6.17.11/kernel/capability.c linux-2.6.17.11-vs2.1.1-rc31/kernel/capability.c
19019 --- linux-2.6.17.11/kernel/capability.c 2006-06-18 04:55:30 +0200
19020 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/capability.c    2006-08-17 01:24:55 +0200
19021 @@ -12,6 +12,7 @@
19022  #include <linux/module.h>
19023  #include <linux/security.h>
19024  #include <linux/syscalls.h>
19025 +#include <linux/vs_pid.h>
19026  #include <asm/uaccess.h>
19027  
19028  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
19029 @@ -246,6 +247,9 @@ EXPORT_SYMBOL(__capable);
19030  
19031  int capable(int cap)
19032  {
19033 +       /* here for now so we don't require task locking */
19034 +       if (vx_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap))
19035 +               return 0;
19036         return __capable(current, cap);
19037  }
19038  EXPORT_SYMBOL(capable);
19039 diff -NurpP --minimal linux-2.6.17.11/kernel/compat.c linux-2.6.17.11-vs2.1.1-rc31/kernel/compat.c
19040 --- linux-2.6.17.11/kernel/compat.c     2006-06-18 04:55:30 +0200
19041 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/compat.c        2006-07-09 17:07:13 +0200
19042 @@ -819,7 +819,7 @@ asmlinkage long compat_sys_time(compat_t
19043         compat_time_t i;
19044         struct timeval tv;
19045  
19046 -       do_gettimeofday(&tv);
19047 +       vx_gettimeofday(&tv);
19048         i = tv.tv_sec;
19049  
19050         if (tloc) {
19051 @@ -843,7 +843,7 @@ asmlinkage long compat_sys_stime(compat_
19052         if (err)
19053                 return err;
19054  
19055 -       do_settimeofday(&tv);
19056 +       vx_settimeofday(&tv);
19057         return 0;
19058  }
19059  
19060 diff -NurpP --minimal linux-2.6.17.11/kernel/cpuset.c linux-2.6.17.11-vs2.1.1-rc31/kernel/cpuset.c
19061 --- linux-2.6.17.11/kernel/cpuset.c     2006-06-18 04:55:30 +0200
19062 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/cpuset.c        2006-07-09 17:07:13 +0200
19063 @@ -49,6 +49,7 @@
19064  #include <linux/time.h>
19065  #include <linux/backing-dev.h>
19066  #include <linux/sort.h>
19067 +#include <linux/vs_pid.h>
19068  
19069  #include <asm/uaccess.h>
19070  #include <asm/atomic.h>
19071 diff -NurpP --minimal linux-2.6.17.11/kernel/exit.c linux-2.6.17.11-vs2.1.1-rc31/kernel/exit.c
19072 --- linux-2.6.17.11/kernel/exit.c       2006-08-25 00:25:37 +0200
19073 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/exit.c  2006-08-17 01:24:55 +0200
19074 @@ -36,6 +36,10 @@
19075  #include <linux/compat.h>
19076  #include <linux/pipe_fs_i.h>
19077  #include <linux/audit.h> /* for audit_free() */
19078 +#include <linux/vs_limit.h>
19079 +#include <linux/vs_context.h>
19080 +#include <linux/vs_network.h>
19081 +#include <linux/vs_pid.h>
19082  
19083  #include <asm/uaccess.h>
19084  #include <asm/unistd.h>
19085 @@ -449,6 +453,7 @@ static void close_files(struct files_str
19086                                 struct file * file = xchg(&fdt->fd[i], NULL);
19087                                 if (file)
19088                                         filp_close(file, files);
19089 +                               vx_openfd_dec(i);
19090                         }
19091                         i++;
19092                         set >>= 1;
19093 @@ -591,6 +596,11 @@ static void exit_mm(struct task_struct *
19094  
19095  static inline void choose_new_parent(task_t *p, task_t *reaper)
19096  {
19097 +       /* check for reaper context */
19098 +       vxwprintk((p->xid != reaper->xid) && (reaper != child_reaper),
19099 +               "rogue reaper: %p[%d,#%u] <> %p[%d,#%u]",
19100 +               p, p->pid, p->xid, reaper, reaper->pid, reaper->xid);
19101 +
19102         /*
19103          * Make sure we're not reparenting to ourselves and that
19104          * the parent is not a zombie.
19105 @@ -672,7 +682,7 @@ static void forget_original_parent(struc
19106         do {
19107                 reaper = next_thread(reaper);
19108                 if (reaper == father) {
19109 -                       reaper = child_reaper;
19110 +                       reaper = vx_child_reaper(father);
19111                         break;
19112                 }
19113         } while (reaper->exit_state);
19114 @@ -696,7 +706,7 @@ static void forget_original_parent(struc
19115  
19116                 if (father == p->real_parent) {
19117                         /* reparent with a reaper, real father it's us */
19118 -                       choose_new_parent(p, reaper);
19119 +                       choose_new_parent(p, vx_child_reaper(p));
19120                         reparent_thread(p, father, 0);
19121                 } else {
19122                         /* reparent ptraced task to its real parent */
19123 @@ -911,6 +921,8 @@ fastcall NORET_TYPE void do_exit(long co
19124         __exit_files(tsk);
19125         __exit_fs(tsk);
19126         exit_namespace(tsk);
19127 +       exit_vx_info(tsk, code);
19128 +       exit_nx_info(tsk);
19129         exit_thread();
19130         cpuset_exit(tsk);
19131         exit_keys(tsk);
19132 diff -NurpP --minimal linux-2.6.17.11/kernel/fork.c linux-2.6.17.11-vs2.1.1-rc31/kernel/fork.c
19133 --- linux-2.6.17.11/kernel/fork.c       2006-06-18 04:55:30 +0200
19134 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/fork.c  2006-08-17 01:24:55 +0200
19135 @@ -44,6 +44,10 @@
19136  #include <linux/rmap.h>
19137  #include <linux/acct.h>
19138  #include <linux/cn_proc.h>
19139 +#include <linux/vs_context.h>
19140 +#include <linux/vs_network.h>
19141 +#include <linux/vs_limit.h>
19142 +#include <linux/vs_memory.h>
19143  
19144  #include <asm/pgtable.h>
19145  #include <asm/pgalloc.h>
19146 @@ -104,6 +108,8 @@ static kmem_cache_t *mm_cachep;
19147  void free_task(struct task_struct *tsk)
19148  {
19149         free_thread_info(tsk->thread_info);
19150 +       clr_vx_info(&tsk->vx_info);
19151 +       clr_nx_info(&tsk->nx_info);
19152         free_task_struct(tsk);
19153  }
19154  EXPORT_SYMBOL(free_task);
19155 @@ -201,6 +207,8 @@ static inline int dup_mmap(struct mm_str
19156         mm->free_area_cache = oldmm->mmap_base;
19157         mm->cached_hole_size = ~0UL;
19158         mm->map_count = 0;
19159 +       __set_mm_counter(mm, file_rss, 0);
19160 +       __set_mm_counter(mm, anon_rss, 0);
19161         cpus_clear(mm->cpu_vm_mask);
19162         mm->mm_rb = RB_ROOT;
19163         rb_link = &mm->mm_rb.rb_node;
19164 @@ -212,7 +220,7 @@ static inline int dup_mmap(struct mm_str
19165  
19166                 if (mpnt->vm_flags & VM_DONTCOPY) {
19167                         long pages = vma_pages(mpnt);
19168 -                       mm->total_vm -= pages;
19169 +                       vx_vmpages_sub(mm, pages);
19170                         vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
19171                                                                 -pages);
19172                         continue;
19173 @@ -319,8 +327,6 @@ static struct mm_struct * mm_init(struct
19174         INIT_LIST_HEAD(&mm->mmlist);
19175         mm->core_waiters = 0;
19176         mm->nr_ptes = 0;
19177 -       set_mm_counter(mm, file_rss, 0);
19178 -       set_mm_counter(mm, anon_rss, 0);
19179         spin_lock_init(&mm->page_table_lock);
19180         rwlock_init(&mm->ioctx_list_lock);
19181         mm->ioctx_list = NULL;
19182 @@ -329,6 +335,7 @@ static struct mm_struct * mm_init(struct
19183  
19184         if (likely(!mm_alloc_pgd(mm))) {
19185                 mm->def_flags = 0;
19186 +               set_vx_info(&mm->mm_vx_info, current->vx_info);
19187                 return mm;
19188         }
19189         free_mm(mm);
19190 @@ -360,6 +367,7 @@ void fastcall __mmdrop(struct mm_struct 
19191         BUG_ON(mm == &init_mm);
19192         mm_free_pgd(mm);
19193         destroy_context(mm);
19194 +       clr_vx_info(&mm->mm_vx_info);
19195         free_mm(mm);
19196  }
19197  
19198 @@ -463,6 +471,7 @@ static struct mm_struct *dup_mm(struct t
19199                 goto fail_nomem;
19200  
19201         memcpy(mm, oldmm, sizeof(*mm));
19202 +       mm->mm_vx_info = NULL;
19203  
19204         if (!mm_init(mm))
19205                 goto fail_nomem;
19206 @@ -490,6 +499,7 @@ fail_nocontext:
19207          * If init_new_context() failed, we cannot use mmput() to free the mm
19208          * because it calls destroy_context()
19209          */
19210 +       clr_vx_info(&mm->mm_vx_info);
19211         mm_free_pgd(mm);
19212         free_mm(mm);
19213         return NULL;
19214 @@ -683,6 +693,8 @@ static struct files_struct *dup_fd(struc
19215                 struct file *f = *old_fds++;
19216                 if (f) {
19217                         get_file(f);
19218 +                       /* FIXME: sum it first for check and performance */
19219 +                       vx_openfd_inc(open_files - i);
19220                 } else {
19221                         /*
19222                          * The fd may be claimed in the fd bitmap but not yet
19223 @@ -927,6 +939,8 @@ static task_t *copy_process(unsigned lon
19224  {
19225         int retval;
19226         struct task_struct *p = NULL;
19227 +       struct vx_info *vxi;
19228 +       struct nx_info *nxi;
19229  
19230         if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
19231                 return ERR_PTR(-EINVAL);
19232 @@ -955,12 +969,30 @@ static task_t *copy_process(unsigned lon
19233         if (!p)
19234                 goto fork_out;
19235  
19236 +       init_vx_info(&p->vx_info, current->vx_info);
19237 +       init_nx_info(&p->nx_info, current->nx_info);
19238 +
19239 +       /* check vserver memory */
19240 +       if (p->mm && !(clone_flags & CLONE_VM)) {
19241 +               if (vx_vmpages_avail(p->mm, p->mm->total_vm))
19242 +                       vx_pages_add(p->vx_info, RLIMIT_AS, p->mm->total_vm);
19243 +               else
19244 +                       goto bad_fork_free;
19245 +       }
19246 +       if (p->mm && vx_flags(VXF_FORK_RSS, 0)) {
19247 +               if (!vx_rsspages_avail(p->mm, get_mm_counter(p->mm, file_rss)))
19248 +                       goto bad_fork_cleanup_vm;
19249 +       }
19250 +
19251         retval = -EAGAIN;
19252 +       if (!vx_nproc_avail(1))
19253 +               goto bad_fork_cleanup_vm;
19254 +
19255         if (atomic_read(&p->user->processes) >=
19256                         p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
19257                 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
19258                                 p->user != &root_user)
19259 -                       goto bad_fork_free;
19260 +                       goto bad_fork_cleanup_vm;
19261         }
19262  
19263         atomic_inc(&p->user->__count);
19264 @@ -1212,6 +1244,18 @@ static task_t *copy_process(unsigned lon
19265  
19266         total_forks++;
19267         spin_unlock(&current->sighand->siglock);
19268 +
19269 +       /* p is copy of current */
19270 +       vxi = p->vx_info;
19271 +       if (vxi) {
19272 +               claim_vx_info(vxi, p);
19273 +               atomic_inc(&vxi->cvirt.nr_threads);
19274 +               atomic_inc(&vxi->cvirt.total_forks);
19275 +               vx_nproc_inc(p);
19276 +       }
19277 +       nxi = p->nx_info;
19278 +       if (nxi)
19279 +               claim_nx_info(nxi, p);
19280         write_unlock_irq(&tasklist_lock);
19281         proc_fork_connector(p);
19282         return p;
19283 @@ -1252,6 +1296,9 @@ bad_fork_cleanup_count:
19284         put_group_info(p->group_info);
19285         atomic_dec(&p->user->processes);
19286         free_uid(p->user);
19287 +bad_fork_cleanup_vm:
19288 +       if (p->mm && !(clone_flags & CLONE_VM))
19289 +               vx_pages_sub(p->vx_info, RLIMIT_AS, p->mm->total_vm);
19290  bad_fork_free:
19291         free_task(p);
19292  fork_out:
19293 @@ -1313,6 +1360,15 @@ long do_fork(unsigned long clone_flags,
19294  
19295         if (!pid)
19296                 return -EAGAIN;
19297 +
19298 +       /* kernel threads are host only */
19299 +       if ((clone_flags & CLONE_KTHREAD) && !vx_check(0, VX_ADMIN)) {
19300 +               vxwprintk(1, "xid=%d tried to spawn a kernel thread.",
19301 +                       vx_current_xid());
19302 +               free_pid(pid);
19303 +               return -EPERM;
19304 +       }
19305 +
19306         nr = pid->nr;
19307         if (unlikely(current->ptrace)) {
19308                 trace = fork_traceflag (clone_flags);
19309 diff -NurpP --minimal linux-2.6.17.11/kernel/futex.c linux-2.6.17.11-vs2.1.1-rc31/kernel/futex.c
19310 --- linux-2.6.17.11/kernel/futex.c      2006-06-18 04:55:30 +0200
19311 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/futex.c 2006-07-09 17:07:13 +0200
19312 @@ -44,6 +44,7 @@
19313  #include <linux/pagemap.h>
19314  #include <linux/syscalls.h>
19315  #include <linux/signal.h>
19316 +#include <linux/vs_pid.h>
19317  #include <asm/futex.h>
19318  
19319  #define FUTEX_HASHBITS (CONFIG_BASE_SMALL ? 4 : 8)
19320 diff -NurpP --minimal linux-2.6.17.11/kernel/futex_compat.c linux-2.6.17.11-vs2.1.1-rc31/kernel/futex_compat.c
19321 --- linux-2.6.17.11/kernel/futex_compat.c       2006-06-18 04:55:30 +0200
19322 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/futex_compat.c  2006-07-09 17:07:13 +0200
19323 @@ -9,6 +9,7 @@
19324  #include <linux/linkage.h>
19325  #include <linux/compat.h>
19326  #include <linux/futex.h>
19327 +#include <linux/vs_pid.h>
19328  
19329  #include <asm/uaccess.h>
19330  
19331 diff -NurpP --minimal linux-2.6.17.11/kernel/kthread.c linux-2.6.17.11-vs2.1.1-rc31/kernel/kthread.c
19332 --- linux-2.6.17.11/kernel/kthread.c    2006-06-18 04:55:30 +0200
19333 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/kthread.c       2006-07-09 17:07:13 +0200
19334 @@ -116,7 +116,7 @@ static void keventd_create_kthread(void 
19335         } else {
19336                 wait_for_completion(&create->started);
19337                 read_lock(&tasklist_lock);
19338 -               create->result = find_task_by_pid(pid);
19339 +               create->result = find_task_by_real_pid(pid);
19340                 read_unlock(&tasklist_lock);
19341         }
19342         complete(&create->done);
19343 diff -NurpP --minimal linux-2.6.17.11/kernel/posix-cpu-timers.c linux-2.6.17.11-vs2.1.1-rc31/kernel/posix-cpu-timers.c
19344 --- linux-2.6.17.11/kernel/posix-cpu-timers.c   2006-06-18 04:55:30 +0200
19345 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/posix-cpu-timers.c      2006-07-09 17:07:13 +0200
19346 @@ -6,6 +6,7 @@
19347  #include <linux/posix-timers.h>
19348  #include <asm/uaccess.h>
19349  #include <linux/errno.h>
19350 +#include <linux/vs_pid.h>
19351  
19352  static int check_clock(const clockid_t which_clock)
19353  {
19354 diff -NurpP --minimal linux-2.6.17.11/kernel/posix-timers.c linux-2.6.17.11-vs2.1.1-rc31/kernel/posix-timers.c
19355 --- linux-2.6.17.11/kernel/posix-timers.c       2006-06-18 04:55:31 +0200
19356 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/posix-timers.c  2006-08-17 01:24:55 +0200
19357 @@ -48,6 +48,8 @@
19358  #include <linux/wait.h>
19359  #include <linux/workqueue.h>
19360  #include <linux/module.h>
19361 +#include <linux/vs_context.h>
19362 +#include <linux/vs_pid.h>
19363  
19364  /*
19365   * Management arrays for POSIX timers.  Timers are kept in slab memory
19366 @@ -298,6 +300,10 @@ void do_schedule_next_timer(struct sigin
19367  
19368  int posix_timer_event(struct k_itimer *timr,int si_private)
19369  {
19370 +       struct vx_info_save vxis;
19371 +       int ret;
19372 +
19373 +       enter_vx_info(task_get_vx_info(timr->it_process), &vxis);
19374         memset(&timr->sigq->info, 0, sizeof(siginfo_t));
19375         timr->sigq->info.si_sys_private = si_private;
19376         /* Send signal to the process that owns this timer.*/
19377 @@ -310,11 +316,11 @@ int posix_timer_event(struct k_itimer *t
19378  
19379         if (timr->it_sigev_notify & SIGEV_THREAD_ID) {
19380                 struct task_struct *leader;
19381 -               int ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
19382 -                                       timr->it_process);
19383  
19384 +               ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
19385 +                                   timr->it_process);
19386                 if (likely(ret >= 0))
19387 -                       return ret;
19388 +                       goto out;
19389  
19390                 timr->it_sigev_notify = SIGEV_SIGNAL;
19391                 leader = timr->it_process->group_leader;
19392 @@ -322,8 +328,12 @@ int posix_timer_event(struct k_itimer *t
19393                 timr->it_process = leader;
19394         }
19395  
19396 -       return send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
19397 -                                  timr->it_process);
19398 +       ret = send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
19399 +                                 timr->it_process);
19400 +out:
19401 +       leave_vx_info(&vxis);
19402 +       put_vx_info(vxis.vxi);
19403 +       return ret;
19404  }
19405  EXPORT_SYMBOL_GPL(posix_timer_event);
19406  
19407 @@ -372,7 +382,7 @@ static struct task_struct * good_sigeven
19408         struct task_struct *rtn = current->group_leader;
19409  
19410         if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
19411 -               (!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
19412 +               (!(rtn = find_task_by_real_pid(event->sigev_notify_thread_id)) ||
19413                  rtn->tgid != current->tgid ||
19414                  (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
19415                 return NULL;
19416 diff -NurpP --minimal linux-2.6.17.11/kernel/printk.c linux-2.6.17.11-vs2.1.1-rc31/kernel/printk.c
19417 --- linux-2.6.17.11/kernel/printk.c     2006-06-18 04:55:31 +0200
19418 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/printk.c        2006-07-09 17:07:13 +0200
19419 @@ -31,6 +31,8 @@
19420  #include <linux/security.h>
19421  #include <linux/bootmem.h>
19422  #include <linux/syscalls.h>
19423 +#include <linux/vs_context.h>
19424 +#include <linux/vserver/cvirt.h>
19425  
19426  #include <asm/uaccess.h>
19427  
19428 @@ -183,18 +185,13 @@ int do_syslog(int type, char __user *buf
19429         unsigned long i, j, limit, count;
19430         int do_clear = 0;
19431         char c;
19432 -       int error = 0;
19433 +       int error;
19434  
19435         error = security_syslog(type);
19436         if (error)
19437                 return error;
19438  
19439 -       switch (type) {
19440 -       case 0:         /* Close log */
19441 -               break;
19442 -       case 1:         /* Open log */
19443 -               break;
19444 -       case 2:         /* Read from log */
19445 +       if ((type >= 2) && (type <= 4)) {
19446                 error = -EINVAL;
19447                 if (!buf || len < 0)
19448                         goto out;
19449 @@ -205,6 +202,16 @@ int do_syslog(int type, char __user *buf
19450                         error = -EFAULT;
19451                         goto out;
19452                 }
19453 +       }
19454 +       if (!vx_check(0, VX_ADMIN|VX_WATCH))
19455 +               return vx_do_syslog(type, buf, len);
19456 +
19457 +       switch (type) {
19458 +       case 0:         /* Close log */
19459 +               break;
19460 +       case 1:         /* Open log */
19461 +               break;
19462 +       case 2:         /* Read from log */
19463                 error = wait_event_interruptible(log_wait,
19464                                                         (log_start - log_end));
19465                 if (error)
19466 @@ -229,16 +236,6 @@ int do_syslog(int type, char __user *buf
19467                 do_clear = 1;
19468                 /* FALL THRU */
19469         case 3:         /* Read last kernel messages */
19470 -               error = -EINVAL;
19471 -               if (!buf || len < 0)
19472 -                       goto out;
19473 -               error = 0;
19474 -               if (!len)
19475 -                       goto out;
19476 -               if (!access_ok(VERIFY_WRITE, buf, len)) {
19477 -                       error = -EFAULT;
19478 -                       goto out;
19479 -               }
19480                 count = len;
19481                 if (count > log_buf_len)
19482                         count = log_buf_len;
19483 @@ -474,11 +471,14 @@ __attribute__((weak)) unsigned long long
19484  
19485  asmlinkage int printk(const char *fmt, ...)
19486  {
19487 +       struct vx_info_save vxis;
19488         va_list args;
19489         int r;
19490  
19491         va_start(args, fmt);
19492 +       __enter_vx_admin(&vxis);
19493         r = vprintk(fmt, args);
19494 +       __leave_vx_admin(&vxis);
19495         va_end(args);
19496  
19497         return r;
19498 diff -NurpP --minimal linux-2.6.17.11/kernel/ptrace.c linux-2.6.17.11-vs2.1.1-rc31/kernel/ptrace.c
19499 --- linux-2.6.17.11/kernel/ptrace.c     2006-06-18 04:55:31 +0200
19500 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/ptrace.c        2006-08-06 17:55:50 +0200
19501 @@ -18,6 +18,7 @@
19502  #include <linux/ptrace.h>
19503  #include <linux/security.h>
19504  #include <linux/signal.h>
19505 +#include <linux/vs_pid.h>
19506  
19507  #include <asm/pgtable.h>
19508  #include <asm/uaccess.h>
19509 @@ -132,6 +133,11 @@ static int may_attach(struct task_struct
19510         smp_rmb();
19511         if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
19512                 return -EPERM;
19513 +       if (!vx_check(task->xid, VX_ADMIN_P|VX_IDENT))
19514 +               return -EPERM;
19515 +       if (!vx_check(task->xid, VX_IDENT) &&
19516 +               !task_vx_flags(task, VXF_STATE_ADMIN, 0))
19517 +               return -EACCES;
19518  
19519         return security_ptrace(current, task);
19520  }
19521 @@ -506,6 +512,10 @@ asmlinkage long sys_ptrace(long request,
19522                 goto out;
19523         }
19524  
19525 +       ret = -EPERM;
19526 +       if (!vx_check(vx_task_xid(child), VX_WATCH_P|VX_IDENT))
19527 +               goto out_put_task_struct;
19528 +
19529         if (request == PTRACE_ATTACH) {
19530                 ret = ptrace_attach(child);
19531                 goto out_put_task_struct;
19532 diff -NurpP --minimal linux-2.6.17.11/kernel/sched.c linux-2.6.17.11-vs2.1.1-rc31/kernel/sched.c
19533 --- linux-2.6.17.11/kernel/sched.c      2006-08-25 00:25:37 +0200
19534 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/sched.c 2006-08-17 00:42:17 +0200
19535 @@ -53,6 +53,10 @@
19536  #include <asm/tlb.h>
19537  
19538  #include <asm/unistd.h>
19539 +#include <linux/vs_context.h>
19540 +#include <linux/vs_cvirt.h>
19541 +#include <linux/vs_pid.h>
19542 +#include <linux/vs_sched.h>
19543  
19544  /*
19545   * Convert user-nice values [ -20 ... 0 ... 19 ]
19546 @@ -241,6 +245,16 @@ struct runqueue {
19547         struct list_head migration_queue;
19548         int cpu;
19549  #endif
19550 +       unsigned long norm_time;
19551 +       unsigned long idle_time;
19552 +#ifdef CONFIG_VSERVER_IDLETIME
19553 +       int idle_skip;
19554 +#endif
19555 +#ifdef CONFIG_VSERVER_HARDCPU
19556 +       struct list_head hold_queue;
19557 +       unsigned long nr_onhold;
19558 +       int idle_tokens;
19559 +#endif
19560  
19561  #ifdef CONFIG_SCHEDSTATS
19562         /* latency stats */
19563 @@ -601,6 +615,7 @@ static inline void sched_info_switch(tas
19564   */
19565  static void dequeue_task(struct task_struct *p, prio_array_t *array)
19566  {
19567 +       BUG_ON(p->state & TASK_ONHOLD);
19568         array->nr_active--;
19569         list_del(&p->run_list);
19570         if (list_empty(array->queue + p->prio))
19571 @@ -609,6 +624,7 @@ static void dequeue_task(struct task_str
19572  
19573  static void enqueue_task(struct task_struct *p, prio_array_t *array)
19574  {
19575 +       BUG_ON(p->state & TASK_ONHOLD);
19576         sched_info_queued(p);
19577         list_add_tail(&p->run_list, array->queue + p->prio);
19578         __set_bit(p->prio, array->bitmap);
19579 @@ -622,11 +638,13 @@ static void enqueue_task(struct task_str
19580   */
19581  static void requeue_task(struct task_struct *p, prio_array_t *array)
19582  {
19583 +       BUG_ON(p->state & TASK_ONHOLD);
19584         list_move_tail(&p->run_list, array->queue + p->prio);
19585  }
19586  
19587  static inline void enqueue_task_head(struct task_struct *p, prio_array_t *array)
19588  {
19589 +       BUG_ON(p->state & TASK_ONHOLD);
19590         list_add(&p->run_list, array->queue + p->prio);
19591         __set_bit(p->prio, array->bitmap);
19592         array->nr_active++;
19593 @@ -657,6 +675,10 @@ static int effective_prio(task_t *p)
19594         bonus = CURRENT_BONUS(p) - MAX_BONUS / 2;
19595  
19596         prio = p->static_prio - bonus;
19597 +
19598 +       /* adjust effective priority */
19599 +       prio = vx_adjust_prio(p, prio, MAX_USER_PRIO);
19600 +
19601         if (prio < MAX_RT_PRIO)
19602                 prio = MAX_RT_PRIO;
19603         if (prio > MAX_PRIO-1)
19604 @@ -664,6 +686,9 @@ static int effective_prio(task_t *p)
19605         return prio;
19606  }
19607  
19608 +#include "sched_mon.h"
19609 +
19610 +
19611  /*
19612   * __activate_task - move a task to the runqueue.
19613   */
19614 @@ -673,6 +698,7 @@ static void __activate_task(task_t *p, r
19615  
19616         if (batch_task(p))
19617                 target = rq->expired;
19618 +       vxm_activate_task(p, rq);
19619         enqueue_task(p, target);
19620         rq->nr_running++;
19621  }
19622 @@ -682,6 +708,7 @@ static void __activate_task(task_t *p, r
19623   */
19624  static inline void __activate_idle_task(task_t *p, runqueue_t *rq)
19625  {
19626 +       vxm_activate_idle(p, rq);
19627         enqueue_task_head(p, rq->active);
19628         rq->nr_running++;
19629  }
19630 @@ -797,19 +824,31 @@ static void activate_task(task_t *p, run
19631         }
19632         p->timestamp = now;
19633  
19634 +       vx_activate_task(p);
19635         __activate_task(p, rq);
19636  }
19637  
19638  /*
19639   * deactivate_task - remove a task from the runqueue.
19640   */
19641 -static void deactivate_task(struct task_struct *p, runqueue_t *rq)
19642 +static void __deactivate_task(struct task_struct *p, runqueue_t *rq)
19643  {
19644         rq->nr_running--;
19645         dequeue_task(p, p->array);
19646 +       vxm_deactivate_task(p, rq);
19647         p->array = NULL;
19648  }
19649  
19650 +static inline
19651 +void deactivate_task(struct task_struct *p, runqueue_t *rq)
19652 +{
19653 +       vx_deactivate_task(p);
19654 +       __deactivate_task(p, rq);
19655 +}
19656 +
19657 +
19658 +#include "sched_hard.h"
19659 +
19660  /*
19661   * resched_task - mark a task 'to be rescheduled now'.
19662   *
19663 @@ -873,6 +912,7 @@ static int migrate_task(task_t *p, int d
19664  {
19665         runqueue_t *rq = task_rq(p);
19666  
19667 +       vxm_migrate_task(p, rq, dest_cpu);
19668         /*
19669          * If the task is not on a runqueue (and not running), then
19670          * it is sufficient to simply update the task's cpu field.
19671 @@ -1173,6 +1213,12 @@ static int try_to_wake_up(task_t *p, uns
19672  
19673         rq = task_rq_lock(p, &flags);
19674         old_state = p->state;
19675 +
19676 +       /* we need to unhold suspended tasks */
19677 +       if (old_state & TASK_ONHOLD) {
19678 +               vx_unhold_task(p, rq);
19679 +               old_state = p->state;
19680 +       }
19681         if (!(old_state & state))
19682                 goto out;
19683  
19684 @@ -1276,6 +1322,7 @@ out_activate:
19685  #endif /* CONFIG_SMP */
19686         if (old_state == TASK_UNINTERRUPTIBLE) {
19687                 rq->nr_uninterruptible--;
19688 +               vx_uninterruptible_dec(p);
19689                 /*
19690                  * Tasks on involuntary sleep don't earn
19691                  * sleep_avg beyond just interactive state.
19692 @@ -1416,6 +1463,7 @@ void fastcall wake_up_new_task(task_t *p
19693  
19694         p->prio = effective_prio(p);
19695  
19696 +       vx_activate_task(p);
19697         if (likely(cpu == this_cpu)) {
19698                 if (!(clone_flags & CLONE_VM)) {
19699                         /*
19700 @@ -1427,6 +1475,7 @@ void fastcall wake_up_new_task(task_t *p
19701                                 __activate_task(p, rq);
19702                         else {
19703                                 p->prio = current->prio;
19704 +                               BUG_ON(p->state & TASK_ONHOLD);
19705                                 list_add_tail(&p->run_list, &current->run_list);
19706                                 p->array = current->array;
19707                                 p->array->nr_active++;
19708 @@ -2514,13 +2563,16 @@ unsigned long long current_sched_time(co
19709  void account_user_time(struct task_struct *p, cputime_t cputime)
19710  {
19711         struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
19712 +       struct vx_info *vxi = p->vx_info;  /* p is _always_ current */
19713         cputime64_t tmp;
19714 +       int nice = (TASK_NICE(p) > 0);
19715  
19716         p->utime = cputime_add(p->utime, cputime);
19717 +       vx_account_user(vxi, cputime, nice);
19718  
19719         /* Add user time to cpustat. */
19720         tmp = cputime_to_cputime64(cputime);
19721 -       if (TASK_NICE(p) > 0)
19722 +       if (nice)
19723                 cpustat->nice = cputime64_add(cpustat->nice, tmp);
19724         else
19725                 cpustat->user = cputime64_add(cpustat->user, tmp);
19726 @@ -2536,10 +2588,12 @@ void account_system_time(struct task_str
19727                          cputime_t cputime)
19728  {
19729         struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
19730 +       struct vx_info *vxi = p->vx_info;  /* p is _always_ current */
19731         runqueue_t *rq = this_rq();
19732         cputime64_t tmp;
19733  
19734         p->stime = cputime_add(p->stime, cputime);
19735 +       vx_account_system(vxi, cputime, (p == rq->idle));
19736  
19737         /* Add system time to cpustat. */
19738         tmp = cputime_to_cputime64(cputime);
19739 @@ -2593,12 +2647,14 @@ void scheduler_tick(void)
19740         unsigned long long now = sched_clock();
19741  
19742         update_cpu_clock(p, rq, now);
19743 +       vxm_sync(now, cpu);
19744  
19745         rq->timestamp_last_tick = now;
19746  
19747         if (p == rq->idle) {
19748                 if (wake_priority_sleeper(rq))
19749                         goto out;
19750 +               vx_idle_resched(rq);
19751                 rebalance_tick(cpu, rq, SCHED_IDLE);
19752                 return;
19753         }
19754 @@ -2631,7 +2687,7 @@ void scheduler_tick(void)
19755                 }
19756                 goto out_unlock;
19757         }
19758 -       if (!--p->time_slice) {
19759 +       if (vx_need_resched(p, --p->time_slice, cpu)) {
19760                 dequeue_task(p, rq->active);
19761                 set_tsk_need_resched(p);
19762                 p->prio = effective_prio(p);
19763 @@ -2959,15 +3015,26 @@ need_resched_nonpreemptible:
19764                                 unlikely(signal_pending(prev))))
19765                         prev->state = TASK_RUNNING;
19766                 else {
19767 -                       if (prev->state == TASK_UNINTERRUPTIBLE)
19768 +                       if (prev->state == TASK_UNINTERRUPTIBLE) {
19769                                 rq->nr_uninterruptible++;
19770 +                               vx_uninterruptible_inc(prev);
19771 +                       }
19772                         deactivate_task(prev, rq);
19773                 }
19774         }
19775  
19776         cpu = smp_processor_id();
19777 +       vx_set_rq_time(rq, jiffies);
19778 +try_unhold:
19779 +       vx_try_unhold(rq, cpu);
19780 +pick_next:
19781 +
19782         if (unlikely(!rq->nr_running)) {
19783  go_idle:
19784 +               /* can we skip idle time? */
19785 +               if (vx_try_skip(rq, cpu))
19786 +                       goto try_unhold;
19787 +
19788                 idle_balance(cpu, rq);
19789                 if (!rq->nr_running) {
19790                         next = rq->idle;
19791 @@ -3012,6 +3079,10 @@ go_idle:
19792         queue = array->queue + idx;
19793         next = list_entry(queue->next, task_t, run_list);
19794  
19795 +       /* check before we schedule this context */
19796 +       if (!vx_schedule(next, rq, cpu))
19797 +               goto pick_next;
19798 +
19799         if (!rt_task(next) && interactive_sleep(next->sleep_type)) {
19800                 unsigned long long delta = now - next->timestamp;
19801                 if (unlikely((long long)(now - next->timestamp) < 0))
19802 @@ -3566,7 +3637,7 @@ asmlinkage long sys_nice(int increment)
19803                 nice = 19;
19804  
19805         if (increment < 0 && !can_nice(current, nice))
19806 -               return -EPERM;
19807 +               return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
19808  
19809         retval = security_task_setnice(current, nice);
19810         if (retval)
19811 @@ -3726,6 +3797,7 @@ recheck:
19812         oldprio = p->prio;
19813         __setscheduler(p, policy, param->sched_priority);
19814         if (array) {
19815 +               vx_activate_task(p);
19816                 __activate_task(p, rq);
19817                 /*
19818                  * Reschedule if we are currently running on this runqueue and
19819 @@ -6130,7 +6202,10 @@ void __init sched_init(void)
19820                 rq->cpu = i;
19821  #endif
19822                 atomic_set(&rq->nr_iowait, 0);
19823 -
19824 +#ifdef CONFIG_VSERVER_HARDCPU
19825 +               INIT_LIST_HEAD(&rq->hold_queue);
19826 +               rq->nr_onhold = 0;
19827 +#endif
19828                 for (j = 0; j < 2; j++) {
19829                         array = rq->arrays + j;
19830                         for (k = 0; k < MAX_PRIO; k++) {
19831 @@ -6199,6 +6274,7 @@ void normalize_rt_tasks(void)
19832                         deactivate_task(p, task_rq(p));
19833                 __setscheduler(p, SCHED_NORMAL, 0);
19834                 if (array) {
19835 +                       vx_activate_task(p);
19836                         __activate_task(p, task_rq(p));
19837                         resched_task(rq->curr);
19838                 }
19839 diff -NurpP --minimal linux-2.6.17.11/kernel/sched_hard.h linux-2.6.17.11-vs2.1.1-rc31/kernel/sched_hard.h
19840 --- linux-2.6.17.11/kernel/sched_hard.h 1970-01-01 01:00:00 +0100
19841 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/sched_hard.h    2006-07-09 17:07:13 +0200
19842 @@ -0,0 +1,324 @@
19843 +
19844 +#ifdef CONFIG_VSERVER_IDLELIMIT
19845 +
19846 +/*
19847 + * vx_idle_resched - reschedule after maxidle
19848 + */
19849 +static inline
19850 +void vx_idle_resched(runqueue_t *rq)
19851 +{
19852 +       /* maybe have a better criterion for paused */
19853 +       if (!--rq->idle_tokens && !list_empty(&rq->hold_queue))
19854 +               set_need_resched();
19855 +}
19856 +
19857 +#else /* !CONFIG_VSERVER_IDLELIMIT */
19858 +
19859 +#define vx_idle_resched(rq)
19860 +
19861 +#endif /* CONFIG_VSERVER_IDLELIMIT */
19862 +
19863 +
19864 +
19865 +#ifdef CONFIG_VSERVER_IDLETIME
19866 +
19867 +#define vx_set_rq_min_skip(rq, min)            \
19868 +       (rq)->idle_skip = (min)
19869 +
19870 +#define vx_save_min_skip(ret, min, val)                \
19871 +       __vx_save_min_skip(ret, min, val)
19872 +
19873 +static inline
19874 +void __vx_save_min_skip(int ret, int *min, int val)
19875 +{
19876 +       if (ret > -2)
19877 +               return;
19878 +       if ((*min > val) || !*min)
19879 +               *min = val;
19880 +}
19881 +
19882 +static inline
19883 +int vx_try_skip(runqueue_t *rq, int cpu)
19884 +{
19885 +       /* artificially advance time */
19886 +       if (rq->idle_skip > 0) {
19887 +               vxdprintk(list_empty(&rq->hold_queue),
19888 +                       "hold queue empty on cpu %d", cpu);
19889 +               rq->idle_time += rq->idle_skip;
19890 +               vxm_idle_skip(rq, cpu);
19891 +               return 1;
19892 +       }
19893 +       return 0;
19894 +}
19895 +
19896 +#else /* !CONFIG_VSERVER_IDLETIME */
19897 +
19898 +#define vx_set_rq_min_skip(rq, min)            \
19899 +       ({ int dummy = (min); dummy; })
19900 +
19901 +#define vx_save_min_skip(ret, min, val)
19902 +
19903 +static inline
19904 +int vx_try_skip(runqueue_t *rq, int cpu)
19905 +{
19906 +       return 0;
19907 +}
19908 +
19909 +#endif /* CONFIG_VSERVER_IDLETIME */
19910 +
19911 +
19912 +
19913 +#ifdef CONFIG_VSERVER_HARDCPU
19914 +
19915 +#define vx_set_rq_max_idle(rq, max)            \
19916 +       (rq)->idle_tokens = (max)
19917 +
19918 +#define vx_save_max_idle(ret, min, val)                \
19919 +       __vx_save_max_idle(ret, min, val)
19920 +
19921 +static inline
19922 +void __vx_save_max_idle(int ret, int *min, int val)
19923 +{
19924 +       if (*min > val)
19925 +               *min = val;
19926 +}
19927 +
19928 +
19929 +/*
19930 + * vx_hold_task - put a task on the hold queue
19931 + */
19932 +static inline
19933 +void vx_hold_task(struct task_struct *p, runqueue_t *rq)
19934 +{
19935 +       __deactivate_task(p, rq);
19936 +       p->state |= TASK_ONHOLD;
19937 +       /* a new one on hold */
19938 +       rq->nr_onhold++;
19939 +       vxm_hold_task(p, rq);
19940 +       list_add_tail(&p->run_list, &rq->hold_queue);
19941 +}
19942 +
19943 +/*
19944 + * vx_unhold_task - put a task back to the runqueue
19945 + */
19946 +static inline
19947 +void vx_unhold_task(struct task_struct *p, runqueue_t *rq)
19948 +{
19949 +       list_del(&p->run_list);
19950 +       /* one less waiting */
19951 +       rq->nr_onhold--;
19952 +       p->state &= ~TASK_ONHOLD;
19953 +       enqueue_task(p, rq->expired);
19954 +       rq->nr_running++;
19955 +       vxm_unhold_task(p, rq);
19956 +
19957 +       if (p->static_prio < rq->best_expired_prio)
19958 +               rq->best_expired_prio = p->static_prio;
19959 +}
19960 +
19961 +unsigned long nr_onhold(void)
19962 +{
19963 +       unsigned long i, sum = 0;
19964 +
19965 +       for_each_online_cpu(i)
19966 +               sum += cpu_rq(i)->nr_onhold;
19967 +
19968 +       return sum;
19969 +}
19970 +
19971 +
19972 +
19973 +static inline
19974 +int __vx_tokens_avail(struct _vx_sched_pc *sched_pc)
19975 +{
19976 +       return sched_pc->tokens;
19977 +}
19978 +
19979 +static inline
19980 +void __vx_consume_token(struct _vx_sched_pc *sched_pc)
19981 +{
19982 +       sched_pc->tokens--;
19983 +}
19984 +
19985 +static inline
19986 +int vx_need_resched(struct task_struct *p, int slice, int cpu)
19987 +{
19988 +       struct vx_info *vxi = p->vx_info;
19989 +
19990 +       if (vx_info_flags(vxi, VXF_SCHED_HARD|VXF_SCHED_PRIO, 0)) {
19991 +               struct _vx_sched_pc *sched_pc =
19992 +                       &vx_per_cpu(vxi, sched_pc, cpu);
19993 +               int tokens;
19994 +
19995 +               /* maybe we can simplify that to decrement
19996 +                  the token counter unconditional? */
19997 +
19998 +               if ((tokens = __vx_tokens_avail(sched_pc)) > 0)
19999 +                       __vx_consume_token(sched_pc);
20000 +
20001 +               /* for tokens > 0, one token was consumed */
20002 +               if (tokens < 2)
20003 +                       slice = 0;
20004 +       }
20005 +       vxm_need_resched(p, slice, cpu);
20006 +       return (slice == 0);
20007 +}
20008 +
20009 +
20010 +#define vx_set_rq_time(rq, time) do {  \
20011 +       rq->norm_time = time;           \
20012 +} while (0)
20013 +
20014 +
20015 +static inline
20016 +void vx_try_unhold(runqueue_t *rq, int cpu)
20017 +{
20018 +       struct vx_info *vxi = NULL;
20019 +       struct list_head *l, *n;
20020 +       int maxidle = HZ;
20021 +       int minskip = 0;
20022 +
20023 +       /* nothing to do? what about pause? */
20024 +       if (list_empty(&rq->hold_queue))
20025 +               return;
20026 +
20027 +       list_for_each_safe(l, n, &rq->hold_queue) {
20028 +               int ret, delta_min[2];
20029 +               struct _vx_sched_pc *sched_pc;
20030 +               struct task_struct *p;
20031 +
20032 +               p = list_entry(l, task_t, run_list);
20033 +               /* don't bother with same context */
20034 +               if (vxi == p->vx_info)
20035 +                       continue;
20036 +
20037 +               vxi = p->vx_info;
20038 +               /* ignore paused contexts */
20039 +               if (vx_info_flags(vxi, VXF_SCHED_PAUSE, 0))
20040 +                       continue;
20041 +
20042 +               sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
20043 +
20044 +               /* recalc tokens */
20045 +               vxm_sched_info(sched_pc, vxi, cpu);
20046 +               ret = vx_tokens_recalc(sched_pc,
20047 +                       &rq->norm_time, &rq->idle_time, delta_min);
20048 +               vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
20049 +
20050 +               if (ret > 0) {
20051 +                       /* we found a runable context */
20052 +                       vx_unhold_task(p, rq);
20053 +                       break;
20054 +               }
20055 +               vx_save_max_idle(ret, &maxidle, delta_min[0]);
20056 +               vx_save_min_skip(ret, &minskip, delta_min[1]);
20057 +       }
20058 +       vx_set_rq_max_idle(rq, maxidle);
20059 +       vx_set_rq_min_skip(rq, minskip);
20060 +       vxm_rq_max_min(rq, cpu);
20061 +}
20062 +
20063 +
20064 +static inline
20065 +int vx_schedule(struct task_struct *next, runqueue_t *rq, int cpu)
20066 +{
20067 +       struct vx_info *vxi = next->vx_info;
20068 +       struct _vx_sched_pc *sched_pc;
20069 +       int delta_min[2];
20070 +       int flags, ret;
20071 +
20072 +       if (!vxi)
20073 +               return 1;
20074 +
20075 +       flags = vxi->vx_flags;
20076 +
20077 +       if (unlikely(vx_check_flags(flags , VXF_SCHED_PAUSE, 0)))
20078 +               goto put_on_hold;
20079 +       if (!vx_check_flags(flags , VXF_SCHED_HARD|VXF_SCHED_PRIO, 0))
20080 +               return 1;
20081 +
20082 +       sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
20083 +#ifdef CONFIG_SMP
20084 +       /* update scheduler params */
20085 +       if (cpu_isset(cpu, vxi->sched.update)) {
20086 +               vx_update_sched_param(&vxi->sched, sched_pc);
20087 +               vxm_update_sched(sched_pc, vxi, cpu);
20088 +               cpu_clear(cpu, vxi->sched.update);
20089 +       }
20090 +#endif
20091 +       vxm_sched_info(sched_pc, vxi, cpu);
20092 +       ret  = vx_tokens_recalc(sched_pc,
20093 +               &rq->norm_time, &rq->idle_time, delta_min);
20094 +       vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
20095 +
20096 +       if (!vx_check_flags(flags , VXF_SCHED_HARD, 0))
20097 +               return 1;
20098 +
20099 +       if (unlikely(ret < 0)) {
20100 +               vx_save_max_idle(ret, &rq->idle_tokens, delta_min[0]);
20101 +               vx_save_min_skip(ret, &rq->idle_skip, delta_min[1]);
20102 +               vxm_rq_max_min(rq, cpu);
20103 +       put_on_hold:
20104 +               vx_hold_task(next, rq);
20105 +               return 0;
20106 +       }
20107 +       return 1;
20108 +}
20109 +
20110 +
20111 +#else /* CONFIG_VSERVER_HARDCPU */
20112 +
20113 +static inline
20114 +void vx_hold_task(struct task_struct *p, runqueue_t *rq)
20115 +{
20116 +       return;
20117 +}
20118 +
20119 +static inline
20120 +void vx_unhold_task(struct task_struct *p, runqueue_t *rq)
20121 +{
20122 +       return;
20123 +}
20124 +
20125 +unsigned long nr_onhold(void)
20126 +{
20127 +       return 0;
20128 +}
20129 +
20130 +
20131 +static inline
20132 +int vx_need_resched(struct task_struct *p, int slice, int cpu)
20133 +{
20134 +       return (slice == 0);
20135 +}
20136 +
20137 +
20138 +#define vx_set_rq_time(rq, time)
20139 +
20140 +static inline
20141 +void vx_try_unhold(runqueue_t *rq, int cpu)
20142 +{
20143 +       return;
20144 +}
20145 +
20146 +static inline
20147 +int vx_schedule(struct task_struct *next, runqueue_t *rq, int cpu)
20148 +{
20149 +       struct vx_info *vxi = next->vx_info;
20150 +       struct _vx_sched_pc *sched_pc;
20151 +       int delta_min[2];
20152 +       int ret;
20153 +
20154 +       if (!vx_info_flags(vxi, VXF_SCHED_PRIO, 0))
20155 +               return 1;
20156 +
20157 +       sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
20158 +       vxm_sched_info(sched_pc, vxi, cpu);
20159 +       ret  = vx_tokens_recalc(sched_pc,
20160 +               &rq->norm_time, &rq->idle_time, delta_min);
20161 +       vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
20162 +       return 1;
20163 +}
20164 +
20165 +#endif /* CONFIG_VSERVER_HARDCPU */
20166 +
20167 diff -NurpP --minimal linux-2.6.17.11/kernel/sched_mon.h linux-2.6.17.11-vs2.1.1-rc31/kernel/sched_mon.h
20168 --- linux-2.6.17.11/kernel/sched_mon.h  1970-01-01 01:00:00 +0100
20169 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/sched_mon.h     2006-07-09 17:07:13 +0200
20170 @@ -0,0 +1,188 @@
20171 +
20172 +#include <linux/vserver/monitor.h>
20173 +
20174 +#ifdef  CONFIG_VSERVER_MONITOR
20175 +
20176 +struct _vx_mon_entry *vxm_advance(int cpu);
20177 +
20178 +
20179 +static inline
20180 +void   __vxm_basic(struct _vx_mon_entry *entry, xid_t xid, int type)
20181 +{
20182 +       entry->type = type;
20183 +       entry->xid = xid;
20184 +}
20185 +
20186 +static inline
20187 +void   __vxm_sync(int cpu)
20188 +{
20189 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20190 +
20191 +       __vxm_basic(entry, 0, VXM_SYNC);
20192 +       entry->ev.sec = xtime.tv_sec;
20193 +       entry->ev.nsec = xtime.tv_nsec;
20194 +}
20195 +
20196 +static inline
20197 +void   __vxm_task(struct task_struct *p, int type)
20198 +{
20199 +       struct _vx_mon_entry *entry = vxm_advance(task_cpu(p));
20200 +
20201 +       __vxm_basic(entry, p->xid, type);
20202 +       entry->ev.tsk.pid = p->pid;
20203 +       entry->ev.tsk.state = p->state;
20204 +}
20205 +
20206 +static inline
20207 +void   __vxm_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20208 +{
20209 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20210 +
20211 +       __vxm_basic(entry, vxi->vx_id, (VXM_SCHED | s->flags));
20212 +       entry->sd.tokens = s->tokens;
20213 +       entry->sd.norm_time = s->norm_time;
20214 +       entry->sd.idle_time = s->idle_time;
20215 +}
20216 +
20217 +static inline
20218 +void   __vxm_rqinfo1(runqueue_t *q, int cpu)
20219 +{
20220 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20221 +
20222 +       entry->type = VXM_RQINFO_1;
20223 +       entry->xid = ((unsigned long)q >> 16) & 0xffff;
20224 +       entry->q1.running = q->nr_running;
20225 +       entry->q1.onhold = q->nr_onhold;
20226 +       entry->q1.iowait = atomic_read(&q->nr_iowait);
20227 +       entry->q1.uintr = q->nr_uninterruptible;
20228 +       entry->q1.idle_tokens = q->idle_tokens;
20229 +}
20230 +
20231 +static inline
20232 +void   __vxm_rqinfo2(runqueue_t *q, int cpu)
20233 +{
20234 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20235 +
20236 +       entry->type = VXM_RQINFO_2;
20237 +       entry->xid = (unsigned long)q & 0xffff;
20238 +       entry->q2.norm_time = q->norm_time;
20239 +       entry->q2.idle_time = q->idle_time;
20240 +       entry->q2.idle_skip = q->idle_skip;
20241 +}
20242 +
20243 +static inline
20244 +void   __vxm_update(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20245 +{
20246 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20247 +
20248 +       __vxm_basic(entry, vxi->vx_id, VXM_UPDATE);
20249 +       entry->ev.tokens = s->tokens;
20250 +}
20251 +
20252 +static inline
20253 +void   __vxm_update1(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20254 +{
20255 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20256 +
20257 +       __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_1);
20258 +       entry->u1.tokens_max = s->tokens_max;
20259 +       entry->u1.fill_rate = s->fill_rate[0];
20260 +       entry->u1.interval = s->interval[0];
20261 +}
20262 +
20263 +static inline
20264 +void   __vxm_update2(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20265 +{
20266 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20267 +
20268 +       __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_2);
20269 +       entry->u2.tokens_min = s->tokens_min;
20270 +       entry->u2.fill_rate = s->fill_rate[1];
20271 +       entry->u2.interval = s->interval[1];
20272 +}
20273 +
20274 +
20275 +#define        vxm_activate_task(p,q)          __vxm_task(p, VXM_ACTIVATE)
20276 +#define        vxm_activate_idle(p,q)          __vxm_task(p, VXM_IDLE)
20277 +#define        vxm_deactivate_task(p,q)        __vxm_task(p, VXM_DEACTIVATE)
20278 +#define        vxm_hold_task(p,q)              __vxm_task(p, VXM_HOLD)
20279 +#define        vxm_unhold_task(p,q)            __vxm_task(p, VXM_UNHOLD)
20280 +
20281 +static inline
20282 +void   vxm_migrate_task(struct task_struct *p, runqueue_t *rq, int dest)
20283 +{
20284 +       __vxm_task(p, VXM_MIGRATE);
20285 +       __vxm_rqinfo1(rq, task_cpu(p));
20286 +       __vxm_rqinfo2(rq, task_cpu(p));
20287 +}
20288 +
20289 +static inline
20290 +void   vxm_idle_skip(runqueue_t *rq, int cpu)
20291 +{
20292 +       __vxm_rqinfo1(rq, cpu);
20293 +       __vxm_rqinfo2(rq, cpu);
20294 +}
20295 +
20296 +static inline
20297 +void   vxm_need_resched(struct task_struct *p, int slice, int cpu)
20298 +{
20299 +       if (slice)
20300 +               return;
20301 +
20302 +       __vxm_task(p, VXM_RESCHED);
20303 +}
20304 +
20305 +static inline
20306 +void   vxm_sync(unsigned long now, int cpu)
20307 +{
20308 +       if (!CONFIG_VSERVER_MONITOR_SYNC ||
20309 +               (now % CONFIG_VSERVER_MONITOR_SYNC))
20310 +               return;
20311 +
20312 +       __vxm_sync(cpu);
20313 +}
20314 +
20315 +#define        vxm_sched_info(s,v,c)           __vxm_sched(s,v,c)
20316 +
20317 +static inline
20318 +void   vxm_tokens_recalc(struct _vx_sched_pc *s, runqueue_t *rq,
20319 +       struct vx_info *vxi, int cpu)
20320 +{
20321 +       __vxm_sched(s, vxi, cpu);
20322 +       __vxm_rqinfo2(rq, cpu);
20323 +}
20324 +
20325 +static inline
20326 +void   vxm_update_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20327 +{
20328 +       __vxm_sched(s, vxi, cpu);
20329 +       __vxm_update(s, vxi, cpu);
20330 +       __vxm_update1(s, vxi, cpu);
20331 +       __vxm_update2(s, vxi, cpu);
20332 +}
20333 +
20334 +static inline
20335 +void   vxm_rq_max_min(runqueue_t *rq, int cpu)
20336 +{
20337 +       __vxm_rqinfo1(rq, cpu);
20338 +       __vxm_rqinfo2(rq, cpu);
20339 +}
20340 +
20341 +#else  /* CONFIG_VSERVER_MONITOR */
20342 +
20343 +#define        vxm_activate_task(t,q)          do { } while (0)
20344 +#define        vxm_activate_idle(t,q)          do { } while (0)
20345 +#define        vxm_deactivate_task(t,q)        do { } while (0)
20346 +#define        vxm_hold_task(t,q)              do { } while (0)
20347 +#define        vxm_unhold_task(t,q)            do { } while (0)
20348 +#define        vxm_migrate_task(t,q,d)         do { } while (0)
20349 +#define        vxm_idle_skip(q,c)              do { } while (0)
20350 +#define        vxm_need_resched(t,s,c)         do { } while (0)
20351 +#define        vxm_sync(s,c)                   do { } while (0)
20352 +#define        vxm_sched_info(s,v,c)           do { } while (0)
20353 +#define        vxm_tokens_recalc(s,q,v,c)      do { } while (0)
20354 +#define        vxm_update_sched(s,v,c)         do { } while (0)
20355 +#define        vxm_rq_max_min(q,c)             do { } while (0)
20356 +
20357 +#endif /* CONFIG_VSERVER_MONITOR */
20358 +
20359 diff -NurpP --minimal linux-2.6.17.11/kernel/signal.c linux-2.6.17.11-vs2.1.1-rc31/kernel/signal.c
20360 --- linux-2.6.17.11/kernel/signal.c     2006-06-18 04:55:34 +0200
20361 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/signal.c        2006-08-06 06:17:14 +0200
20362 @@ -25,6 +25,7 @@
20363  #include <linux/signal.h>
20364  #include <linux/audit.h>
20365  #include <linux/capability.h>
20366 +#include <linux/vs_pid.h>
20367  #include <asm/param.h>
20368  #include <asm/uaccess.h>
20369  #include <asm/unistd.h>
20370 @@ -572,18 +573,27 @@ static int rm_from_queue(unsigned long m
20371  static int check_kill_permission(int sig, struct siginfo *info,
20372                                  struct task_struct *t)
20373  {
20374 +       int user;
20375         int error = -EINVAL;
20376 +
20377         if (!valid_signal(sig))
20378                 return error;
20379 +
20380 +       user = ((info == SEND_SIG_NOINFO) ||
20381 +               (!is_si_special(info) && SI_FROMUSER(info)));
20382 +
20383         error = -EPERM;
20384 -       if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
20385 -           && ((sig != SIGCONT) ||
20386 +       if (user && ((sig != SIGCONT) ||
20387                 (current->signal->session != t->signal->session))
20388             && (current->euid ^ t->suid) && (current->euid ^ t->uid)
20389             && (current->uid ^ t->suid) && (current->uid ^ t->uid)
20390             && !capable(CAP_KILL))
20391                 return error;
20392  
20393 +       error = -ESRCH;
20394 +       if (user && !vx_check(vx_task_xid(t), VX_WATCH_P|VX_IDENT))
20395 +               return error;
20396 +
20397         error = security_task_kill(t, info, sig);
20398         if (!error)
20399                 audit_signal_info(sig, t); /* Let audit system see the signal */
20400 @@ -1803,6 +1813,11 @@ relock:
20401                 if (current == child_reaper)
20402                         continue;
20403  
20404 +               /* virtual init is protected against user signals */
20405 +               if ((info->si_code == SI_USER) &&
20406 +                       vx_current_initpid(current->pid))
20407 +                       continue;
20408 +
20409                 if (sig_kernel_stop(signr)) {
20410                         /*
20411                          * The default action is to stop all threads in
20412 diff -NurpP --minimal linux-2.6.17.11/kernel/softirq.c linux-2.6.17.11-vs2.1.1-rc31/kernel/softirq.c
20413 --- linux-2.6.17.11/kernel/softirq.c    2006-06-18 04:55:34 +0200
20414 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/softirq.c       2006-07-09 17:07:14 +0200
20415 @@ -17,6 +17,7 @@
20416  #include <linux/kthread.h>
20417  #include <linux/rcupdate.h>
20418  #include <linux/smp.h>
20419 +#include <linux/vs_context.h>
20420  
20421  #include <asm/irq.h>
20422  /*
20423 @@ -74,6 +75,7 @@ static inline void wakeup_softirqd(void)
20424  
20425  asmlinkage void __do_softirq(void)
20426  {
20427 +       struct vx_info_save vxis;
20428         struct softirq_action *h;
20429         __u32 pending;
20430         int max_restart = MAX_SOFTIRQ_RESTART;
20431 @@ -82,6 +84,7 @@ asmlinkage void __do_softirq(void)
20432         pending = local_softirq_pending();
20433  
20434         local_bh_disable();
20435 +       __enter_vx_admin(&vxis);
20436         cpu = smp_processor_id();
20437  restart:
20438         /* Reset the pending bitmask before enabling irqs */
20439 @@ -109,6 +112,7 @@ restart:
20440         if (pending)
20441                 wakeup_softirqd();
20442  
20443 +       __leave_vx_admin(&vxis);
20444         __local_bh_enable();
20445  }
20446  
20447 diff -NurpP --minimal linux-2.6.17.11/kernel/sys.c linux-2.6.17.11-vs2.1.1-rc31/kernel/sys.c
20448 --- linux-2.6.17.11/kernel/sys.c        2006-08-25 00:25:37 +0200
20449 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/sys.c   2006-07-26 21:36:47 +0200
20450 @@ -11,6 +11,7 @@
20451  #include <linux/mman.h>
20452  #include <linux/smp_lock.h>
20453  #include <linux/notifier.h>
20454 +#include <linux/kmod.h>
20455  #include <linux/reboot.h>
20456  #include <linux/prctl.h>
20457  #include <linux/init.h>
20458 @@ -30,6 +31,8 @@
20459  #include <linux/tty.h>
20460  #include <linux/signal.h>
20461  #include <linux/cn_proc.h>
20462 +#include <linux/vs_cvirt.h>
20463 +#include <linux/vs_pid.h>
20464  
20465  #include <linux/compat.h>
20466  #include <linux/syscalls.h>
20467 @@ -439,7 +442,10 @@ static int set_one_prio(struct task_stru
20468                 goto out;
20469         }
20470         if (niceval < task_nice(p) && !can_nice(p, niceval)) {
20471 -               error = -EACCES;
20472 +               if (vx_flags(VXF_IGNEG_NICE, 0))
20473 +                       error = 0;
20474 +               else
20475 +                       error = -EACCES;
20476                 goto out;
20477         }
20478         no_nice = security_task_setnice(p, niceval);
20479 @@ -491,7 +497,8 @@ asmlinkage long sys_setpriority(int whic
20480                         if (!who)
20481                                 who = current->uid;
20482                         else
20483 -                               if ((who != current->uid) && !(user = find_user(who)))
20484 +                               if ((who != current->uid) &&
20485 +                                       !(user = find_user(vx_current_xid(), who)))
20486                                         goto out_unlock;        /* No processes for this user */
20487  
20488                         do_each_thread(g, p)
20489 @@ -549,7 +556,8 @@ asmlinkage long sys_getpriority(int whic
20490                         if (!who)
20491                                 who = current->uid;
20492                         else
20493 -                               if ((who != current->uid) && !(user = find_user(who)))
20494 +                               if ((who != current->uid) &&
20495 +                                       !(user = find_user(vx_current_xid(), who)))
20496                                         goto out_unlock;        /* No processes for this user */
20497  
20498                         do_each_thread(g, p)
20499 @@ -666,6 +674,9 @@ void kernel_power_off(void)
20500         machine_power_off();
20501  }
20502  EXPORT_SYMBOL_GPL(kernel_power_off);
20503 +
20504 +long vs_reboot(unsigned int, void __user *);
20505 +
20506  /*
20507   * Reboot system call: for obvious reasons only root may call it,
20508   * and even root needs to set up some magic numbers in the registers
20509 @@ -696,6 +707,9 @@ asmlinkage long sys_reboot(int magic1, i
20510         if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
20511                 cmd = LINUX_REBOOT_CMD_HALT;
20512  
20513 +       if (!vx_check(0, VX_ADMIN|VX_WATCH))
20514 +               return vs_reboot(cmd, arg);
20515 +
20516         lock_kernel();
20517         switch (cmd) {
20518         case LINUX_REBOOT_CMD_RESTART:
20519 @@ -883,7 +897,7 @@ static int set_user(uid_t new_ruid, int 
20520  {
20521         struct user_struct *new_user;
20522  
20523 -       new_user = alloc_uid(new_ruid);
20524 +       new_user = alloc_uid(vx_current_xid(), new_ruid);
20525         if (!new_user)
20526                 return -EAGAIN;
20527  
20528 @@ -1247,15 +1261,18 @@ asmlinkage long sys_setpgid(pid_t pid, p
20529  {
20530         struct task_struct *p;
20531         struct task_struct *group_leader = current->group_leader;
20532 +       pid_t rpgid;
20533         int err = -EINVAL;
20534  
20535         if (!pid)
20536 -               pid = group_leader->pid;
20537 +               pid = vx_map_pid(group_leader->pid);
20538         if (!pgid)
20539                 pgid = pid;
20540         if (pgid < 0)
20541                 return -EINVAL;
20542  
20543 +       rpgid = vx_rmap_pid(pgid);
20544 +
20545         /* From this point forward we keep holding onto the tasklist lock
20546          * so that our parent does not change from under us. -DaveM
20547          */
20548 @@ -1290,22 +1307,22 @@ asmlinkage long sys_setpgid(pid_t pid, p
20549         if (pgid != pid) {
20550                 struct task_struct *p;
20551  
20552 -               do_each_task_pid(pgid, PIDTYPE_PGID, p) {
20553 +               do_each_task_pid(rpgid, PIDTYPE_PGID, p) {
20554                         if (p->signal->session == group_leader->signal->session)
20555                                 goto ok_pgid;
20556 -               } while_each_task_pid(pgid, PIDTYPE_PGID, p);
20557 +               } while_each_task_pid(rpgid, PIDTYPE_PGID, p);
20558                 goto out;
20559         }
20560  
20561  ok_pgid:
20562 -       err = security_task_setpgid(p, pgid);
20563 +       err = security_task_setpgid(p, rpgid);
20564         if (err)
20565                 goto out;
20566  
20567 -       if (process_group(p) != pgid) {
20568 +       if (process_group(p) != rpgid) {
20569                 detach_pid(p, PIDTYPE_PGID);
20570 -               p->signal->pgrp = pgid;
20571 -               attach_pid(p, PIDTYPE_PGID, pgid);
20572 +               p->signal->pgrp = rpgid;
20573 +               attach_pid(p, PIDTYPE_PGID, rpgid);
20574         }
20575  
20576         err = 0;
20577 @@ -1318,7 +1335,7 @@ out:
20578  asmlinkage long sys_getpgid(pid_t pid)
20579  {
20580         if (!pid) {
20581 -               return process_group(current);
20582 +               return vx_rmap_pid(process_group(current));
20583         } else {
20584                 int retval;
20585                 struct task_struct *p;
20586 @@ -1330,7 +1347,7 @@ asmlinkage long sys_getpgid(pid_t pid)
20587                 if (p) {
20588                         retval = security_task_getpgid(p);
20589                         if (!retval)
20590 -                               retval = process_group(p);
20591 +                               retval = vx_rmap_pid(process_group(p));
20592                 }
20593                 read_unlock(&tasklist_lock);
20594                 return retval;
20595 @@ -1671,7 +1688,7 @@ asmlinkage long sys_newuname(struct new_
20596         int errno = 0;
20597  
20598         down_read(&uts_sem);
20599 -       if (copy_to_user(name,&system_utsname,sizeof *name))
20600 +       if (copy_to_user(name, vx_new_utsname(), sizeof *name))
20601                 errno = -EFAULT;
20602         up_read(&uts_sem);
20603         return errno;
20604 @@ -1682,15 +1699,17 @@ asmlinkage long sys_sethostname(char __u
20605         int errno;
20606         char tmp[__NEW_UTS_LEN];
20607  
20608 -       if (!capable(CAP_SYS_ADMIN))
20609 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME))
20610                 return -EPERM;
20611         if (len < 0 || len > __NEW_UTS_LEN)
20612                 return -EINVAL;
20613         down_write(&uts_sem);
20614         errno = -EFAULT;
20615         if (!copy_from_user(tmp, name, len)) {
20616 -               memcpy(system_utsname.nodename, tmp, len);
20617 -               system_utsname.nodename[len] = 0;
20618 +               char *ptr = vx_new_uts(nodename);
20619 +
20620 +               memcpy(ptr, tmp, len);
20621 +               ptr[len] = 0;
20622                 errno = 0;
20623         }
20624         up_write(&uts_sem);
20625 @@ -1702,15 +1721,17 @@ asmlinkage long sys_sethostname(char __u
20626  asmlinkage long sys_gethostname(char __user *name, int len)
20627  {
20628         int i, errno;
20629 +       char *ptr;
20630  
20631         if (len < 0)
20632                 return -EINVAL;
20633         down_read(&uts_sem);
20634 -       i = 1 + strlen(system_utsname.nodename);
20635 +       ptr = vx_new_uts(nodename);
20636 +       i = 1 + strlen(ptr);
20637         if (i > len)
20638                 i = len;
20639         errno = 0;
20640 -       if (copy_to_user(name, system_utsname.nodename, i))
20641 +       if (copy_to_user(name, ptr, i))
20642                 errno = -EFAULT;
20643         up_read(&uts_sem);
20644         return errno;
20645 @@ -1727,7 +1748,7 @@ asmlinkage long sys_setdomainname(char _
20646         int errno;
20647         char tmp[__NEW_UTS_LEN];
20648  
20649 -       if (!capable(CAP_SYS_ADMIN))
20650 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME))
20651                 return -EPERM;
20652         if (len < 0 || len > __NEW_UTS_LEN)
20653                 return -EINVAL;
20654 @@ -1735,8 +1756,10 @@ asmlinkage long sys_setdomainname(char _
20655         down_write(&uts_sem);
20656         errno = -EFAULT;
20657         if (!copy_from_user(tmp, name, len)) {
20658 -               memcpy(system_utsname.domainname, tmp, len);
20659 -               system_utsname.domainname[len] = 0;
20660 +               char *ptr = vx_new_uts(domainname);
20661 +
20662 +               memcpy(ptr, tmp, len);
20663 +               ptr[len] = 0;
20664                 errno = 0;
20665         }
20666         up_write(&uts_sem);
20667 @@ -1794,7 +1817,7 @@ asmlinkage long sys_setrlimit(unsigned i
20668                 return -EINVAL;
20669         old_rlim = current->signal->rlim + resource;
20670         if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
20671 -           !capable(CAP_SYS_RESOURCE))
20672 +           !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
20673                 return -EPERM;
20674         if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN)
20675                 return -EPERM;
20676 diff -NurpP --minimal linux-2.6.17.11/kernel/sysctl.c linux-2.6.17.11-vs2.1.1-rc31/kernel/sysctl.c
20677 --- linux-2.6.17.11/kernel/sysctl.c     2006-06-18 04:55:34 +0200
20678 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/sysctl.c        2006-07-09 17:07:14 +0200
20679 @@ -46,6 +46,7 @@
20680  #include <linux/syscalls.h>
20681  #include <linux/nfs_fs.h>
20682  #include <linux/acpi.h>
20683 +#include <linux/vserver/cvirt.h>
20684  
20685  #include <asm/uaccess.h>
20686  #include <asm/processor.h>
20687 @@ -89,6 +90,7 @@ static int ngroups_max = NGROUPS_MAX;
20688  #ifdef CONFIG_KMOD
20689  extern char modprobe_path[];
20690  #endif
20691 +extern char vshelper_path[];
20692  #ifdef CONFIG_CHR_DEV_SG
20693  extern int sg_big_buff;
20694  #endif
20695 @@ -237,6 +239,7 @@ static ctl_table kern_table[] = {
20696                 .maxlen         = sizeof(system_utsname.sysname),
20697                 .mode           = 0444,
20698                 .proc_handler   = &proc_doutsstring,
20699 +               .virt_handler   = &vx_uts_virt_handler,
20700                 .strategy       = &sysctl_string,
20701         },
20702         {
20703 @@ -246,6 +249,7 @@ static ctl_table kern_table[] = {
20704                 .maxlen         = sizeof(system_utsname.release),
20705                 .mode           = 0444,
20706                 .proc_handler   = &proc_doutsstring,
20707 +               .virt_handler   = &vx_uts_virt_handler,
20708                 .strategy       = &sysctl_string,
20709         },
20710         {
20711 @@ -255,6 +259,7 @@ static ctl_table kern_table[] = {
20712                 .maxlen         = sizeof(system_utsname.version),
20713                 .mode           = 0444,
20714                 .proc_handler   = &proc_doutsstring,
20715 +               .virt_handler   = &vx_uts_virt_handler,
20716                 .strategy       = &sysctl_string,
20717         },
20718         {
20719 @@ -264,6 +269,7 @@ static ctl_table kern_table[] = {
20720                 .maxlen         = sizeof(system_utsname.nodename),
20721                 .mode           = 0644,
20722                 .proc_handler   = &proc_doutsstring,
20723 +               .virt_handler   = &vx_uts_virt_handler,
20724                 .strategy       = &sysctl_string,
20725         },
20726         {
20727 @@ -273,6 +279,7 @@ static ctl_table kern_table[] = {
20728                 .maxlen         = sizeof(system_utsname.domainname),
20729                 .mode           = 0644,
20730                 .proc_handler   = &proc_doutsstring,
20731 +               .virt_handler   = &vx_uts_virt_handler,
20732                 .strategy       = &sysctl_string,
20733         },
20734         {
20735 @@ -409,6 +416,15 @@ static ctl_table kern_table[] = {
20736                 .strategy       = &sysctl_string,
20737         },
20738  #endif
20739 +       {
20740 +               .ctl_name       = KERN_VSHELPER,
20741 +               .procname       = "vshelper",
20742 +               .data           = &vshelper_path,
20743 +               .maxlen         = 256,
20744 +               .mode           = 0644,
20745 +               .proc_handler   = &proc_dostring,
20746 +               .strategy       = &sysctl_string,
20747 +       },
20748  #ifdef CONFIG_CHR_DEV_SG
20749         {
20750                 .ctl_name       = KERN_SG_BIG_BUFF,
20751 @@ -1563,16 +1579,20 @@ static ssize_t proc_writesys(struct file
20752  int proc_dostring(ctl_table *table, int write, struct file *filp,
20753                   void __user *buffer, size_t *lenp, loff_t *ppos)
20754  {
20755 -       size_t len;
20756 +       size_t len, maxlen;
20757         char __user *p;
20758         char c;
20759 +       void *data;
20760 +
20761 +       data = table->data;
20762 +       maxlen = table->maxlen;
20763 +
20764 +       if (!data || !maxlen || !*lenp || (*ppos && !write))
20765 +               return (*lenp = 0);
20766         
20767 -       if (!table->data || !table->maxlen || !*lenp ||
20768 -           (*ppos && !write)) {
20769 -               *lenp = 0;
20770 -               return 0;
20771 -       }
20772 -       
20773 +       if (table->virt_handler)
20774 +               table->virt_handler(table, write, filp->f_xid, &data, &maxlen);
20775 +
20776         if (write) {
20777                 len = 0;
20778                 p = buffer;
20779 @@ -1583,20 +1603,20 @@ int proc_dostring(ctl_table *table, int 
20780                                 break;
20781                         len++;
20782                 }
20783 -               if (len >= table->maxlen)
20784 -                       len = table->maxlen-1;
20785 -               if(copy_from_user(table->data, buffer, len))
20786 +               if (len >= maxlen)
20787 +                       len = maxlen-1;
20788 +               if(copy_from_user(data, buffer, len))
20789                         return -EFAULT;
20790 -               ((char *) table->data)[len] = 0;
20791 +               ((char *) data)[len] = 0;
20792                 *ppos += *lenp;
20793         } else {
20794 -               len = strlen(table->data);
20795 -               if (len > table->maxlen)
20796 -                       len = table->maxlen;
20797 +               len = strlen(data);
20798 +               if (len > maxlen)
20799 +                       len = maxlen;
20800                 if (len > *lenp)
20801                         len = *lenp;
20802                 if (len)
20803 -                       if(copy_to_user(buffer, table->data, len))
20804 +                       if(copy_to_user(buffer, data, len))
20805                                 return -EFAULT;
20806                 if (len < *lenp) {
20807                         if(put_user('\n', ((char __user *) buffer) + len))
20808 diff -NurpP --minimal linux-2.6.17.11/kernel/time.c linux-2.6.17.11-vs2.1.1-rc31/kernel/time.c
20809 --- linux-2.6.17.11/kernel/time.c       2006-06-18 04:55:34 +0200
20810 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/time.c  2006-07-09 17:07:14 +0200
20811 @@ -61,7 +61,7 @@ asmlinkage long sys_time(time_t __user *
20812         time_t i;
20813         struct timeval tv;
20814  
20815 -       do_gettimeofday(&tv);
20816 +       vx_gettimeofday(&tv);
20817         i = tv.tv_sec;
20818  
20819         if (tloc) {
20820 @@ -92,7 +92,7 @@ asmlinkage long sys_stime(time_t __user 
20821         if (err)
20822                 return err;
20823  
20824 -       do_settimeofday(&tv);
20825 +       vx_settimeofday(&tv);
20826         return 0;
20827  }
20828  
20829 @@ -102,7 +102,7 @@ asmlinkage long sys_gettimeofday(struct 
20830  {
20831         if (likely(tv != NULL)) {
20832                 struct timeval ktv;
20833 -               do_gettimeofday(&ktv);
20834 +               vx_gettimeofday(&ktv);
20835                 if (copy_to_user(tv, &ktv, sizeof(ktv)))
20836                         return -EFAULT;
20837         }
20838 @@ -176,7 +176,7 @@ int do_sys_settimeofday(struct timespec 
20839                 /* SMP safe, again the code in arch/foo/time.c should
20840                  * globally block out interrupts when it runs.
20841                  */
20842 -               return do_settimeofday(tv);
20843 +               return vx_settimeofday(tv);
20844         }
20845         return 0;
20846  }
20847 @@ -531,7 +531,7 @@ void getnstimeofday(struct timespec *tv)
20848  {
20849         struct timeval x;
20850  
20851 -       do_gettimeofday(&x);
20852 +       vx_gettimeofday(&x);
20853         tv->tv_sec = x.tv_sec;
20854         tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
20855  }
20856 diff -NurpP --minimal linux-2.6.17.11/kernel/timer.c linux-2.6.17.11-vs2.1.1-rc31/kernel/timer.c
20857 --- linux-2.6.17.11/kernel/timer.c      2006-08-25 00:25:37 +0200
20858 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/timer.c 2006-08-25 00:15:32 +0200
20859 @@ -34,7 +34,10 @@
20860  #include <linux/cpu.h>
20861  #include <linux/syscalls.h>
20862  #include <linux/delay.h>
20863  #include <linux/freezer.h>
20864 +#include <linux/vs_cvirt.h>
20865 +#include <linux/vs_pid.h>
20866 +#include <linux/vserver/sched.h>
20867  
20868  #include <asm/uaccess.h>
20869  #include <asm/unistd.h>
20870 @@ -953,12 +956,6 @@ asmlinkage unsigned long sys_alarm(unsig
20871  
20872  #endif
20873  
20874 -#ifndef __alpha__
20875 -
20876 -/*
20877 - * The Alpha uses getxpid, getxuid, and getxgid instead.  Maybe this
20878 - * should be moved into arch/i386 instead?
20879 - */
20880  
20881  /**
20882   * sys_getpid - return the thread group id of the current process
20883 @@ -971,7 +968,7 @@ asmlinkage unsigned long sys_alarm(unsig
20884   */
20885  asmlinkage long sys_getpid(void)
20886  {
20887 -       return current->tgid;
20888 +       return vx_map_tgid(current->tgid);
20889  }
20890  
20891  /*
20892 @@ -983,14 +980,26 @@ asmlinkage long sys_getpid(void)
20893  asmlinkage long sys_getppid(void)
20894  {
20895         int pid;
20896 -
20897         rcu_read_lock();
20898         pid = rcu_dereference(current->real_parent)->tgid;
20899         rcu_read_unlock();
20900 +       return vx_map_pid(pid);
20901 +}
20902  
20903 -       return pid;
20904 +#ifdef __alpha__
20905 +
20906 +/*
20907 + * The Alpha uses getxpid, getxuid, and getxgid instead.
20908 + */
20909 +
20910 +asmlinkage long do_getxpid(long *ppid)
20911 +{
20912 +       *ppid = sys_getppid();
20913 +       return sys_getpid();
20914  }
20915  
20916 +#else /* _alpha_ */
20917 +
20918  asmlinkage long sys_getuid(void)
20919  {
20920         /* Only we change this so SMP safe */
20921 @@ -1151,6 +1160,8 @@ asmlinkage long sys_sysinfo(struct sysin
20922                         tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC;
20923                         tp.tv_sec++;
20924                 }
20925 +               if (vx_flags(VXF_VIRT_UPTIME, 0))
20926 +                       vx_vsi_uptime(&tp, NULL);
20927                 val.uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0);
20928  
20929                 val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
20930 diff -NurpP --minimal linux-2.6.17.11/kernel/user.c linux-2.6.17.11-vs2.1.1-rc31/kernel/user.c
20931 --- linux-2.6.17.11/kernel/user.c       2006-06-18 04:55:35 +0200
20932 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/user.c  2006-07-09 17:07:14 +0200
20933 @@ -23,8 +23,8 @@
20934  #define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 8)
20935  #define UIDHASH_SZ             (1 << UIDHASH_BITS)
20936  #define UIDHASH_MASK           (UIDHASH_SZ - 1)
20937 -#define __uidhashfn(uid)       (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK)
20938 -#define uidhashentry(uid)      (uidhash_table + __uidhashfn((uid)))
20939 +#define __uidhashfn(xid,uid)   ((((uid) >> UIDHASH_BITS) + ((uid)^(xid))) & UIDHASH_MASK)
20940 +#define uidhashentry(xid,uid)  (uidhash_table + __uidhashfn((xid),(uid)))
20941  
20942  static kmem_cache_t *uid_cachep;
20943  static struct list_head uidhash_table[UIDHASH_SZ];
20944 @@ -66,7 +66,7 @@ static inline void uid_hash_remove(struc
20945         list_del(&up->uidhash_list);
20946  }
20947  
20948 -static inline struct user_struct *uid_hash_find(uid_t uid, struct list_head *hashent)
20949 +static inline struct user_struct *uid_hash_find(xid_t xid, uid_t uid, struct list_head *hashent)
20950  {
20951         struct list_head *up;
20952  
20953 @@ -75,7 +75,7 @@ static inline struct user_struct *uid_ha
20954  
20955                 user = list_entry(up, struct user_struct, uidhash_list);
20956  
20957 -               if(user->uid == uid) {
20958 +               if(user->uid == uid && user->xid == xid) {
20959                         atomic_inc(&user->__count);
20960                         return user;
20961                 }
20962 @@ -90,13 +90,13 @@ static inline struct user_struct *uid_ha
20963   *
20964   * If the user_struct could not be found, return NULL.
20965   */
20966 -struct user_struct *find_user(uid_t uid)
20967 +struct user_struct *find_user(xid_t xid, uid_t uid)
20968  {
20969         struct user_struct *ret;
20970         unsigned long flags;
20971  
20972         spin_lock_irqsave(&uidhash_lock, flags);
20973 -       ret = uid_hash_find(uid, uidhashentry(uid));
20974 +       ret = uid_hash_find(xid, uid, uidhashentry(xid, uid));
20975         spin_unlock_irqrestore(&uidhash_lock, flags);
20976         return ret;
20977  }
20978 @@ -120,13 +120,13 @@ void free_uid(struct user_struct *up)
20979         }
20980  }
20981  
20982 -struct user_struct * alloc_uid(uid_t uid)
20983 +struct user_struct * alloc_uid(xid_t xid, uid_t uid)
20984  {
20985 -       struct list_head *hashent = uidhashentry(uid);
20986 +       struct list_head *hashent = uidhashentry(xid, uid);
20987         struct user_struct *up;
20988  
20989         spin_lock_irq(&uidhash_lock);
20990 -       up = uid_hash_find(uid, hashent);
20991 +       up = uid_hash_find(xid, uid, hashent);
20992         spin_unlock_irq(&uidhash_lock);
20993  
20994         if (!up) {
20995 @@ -136,6 +136,7 @@ struct user_struct * alloc_uid(uid_t uid
20996                 if (!new)
20997                         return NULL;
20998                 new->uid = uid;
20999 +               new->xid = xid;
21000                 atomic_set(&new->__count, 1);
21001                 atomic_set(&new->processes, 0);
21002                 atomic_set(&new->files, 0);
21003 @@ -158,7 +159,7 @@ struct user_struct * alloc_uid(uid_t uid
21004                  * on adding the same user already..
21005                  */
21006                 spin_lock_irq(&uidhash_lock);
21007 -               up = uid_hash_find(uid, hashent);
21008 +               up = uid_hash_find(xid, uid, hashent);
21009                 if (up) {
21010                         key_put(new->uid_keyring);
21011                         key_put(new->session_keyring);
21012 @@ -204,7 +205,7 @@ static int __init uid_cache_init(void)
21013  
21014         /* Insert the root user immediately (init already runs as root) */
21015         spin_lock_irq(&uidhash_lock);
21016 -       uid_hash_insert(&root_user, uidhashentry(0));
21017 +       uid_hash_insert(&root_user, uidhashentry(0,0));
21018         spin_unlock_irq(&uidhash_lock);
21019  
21020         return 0;
21021 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/Kconfig linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/Kconfig
21022 --- linux-2.6.17.11/kernel/vserver/Kconfig      1970-01-01 01:00:00 +0100
21023 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/Kconfig 2006-08-25 21:33:32 +0200
21024 @@ -0,0 +1,273 @@
21025 +#
21026 +# Linux VServer configuration
21027 +#
21028 +
21029 +menu "Linux VServer"
21030 +
21031 +config VSERVER_LEGACY
21032 +       bool    "Enable Legacy Kernel API"
21033 +       default y
21034 +       help
21035 +         This enables the legacy API used in vs1.xx, maintaining
21036 +         compatibility with older vserver tools, and guest images
21037 +         that are configured using the legacy method.  This is
21038 +         probably a good idea for now, for migration purposes.
21039 +
21040 +         Note that some tools have not yet been altered to use
21041 +         this API, so disabling this option may reduce some
21042 +         functionality.
21043 +
21044 +config VSERVER_LEGACY_VERSION
21045 +       bool    "Show a Legacy Version ID"
21046 +       depends on VSERVER_LEGACY
21047 +       default n
21048 +       help
21049 +         This shows a special legacy version to very old tools
21050 +         which do not handle the current version correctly.
21051 +
21052 +         This will probably disable some features of newer tools
21053 +         so better avoid it, unless you really, really need it
21054 +         for backwards compatibility.
21055 +
21056 +config VSERVER_DYNAMIC_IDS
21057 +       bool    "Enable dynamic context IDs"
21058 +       depends on VSERVER_LEGACY
21059 +       default y
21060 +       help
21061 +         This enables support of in kernel dynamic context IDs,
21062 +         which is deprecated and will probably be removed in the
21063 +         next release.
21064 +
21065 +config VSERVER_NGNET
21066 +       bool    "Disable Legacy Networking Kernel API"
21067 +       depends on EXPERIMENTAL
21068 +       default n
21069 +       help
21070 +         This disables the legacy networking API which is required
21071 +         by the chbind tool. Do not disable it unless you exactly
21072 +         know what you are doing.
21073 +
21074 +config VSERVER_REMAP_SADDR
21075 +       bool    "Remap Source IP Address"
21076 +       depends on EXPERIMENTAL && !VSERVER_LEGACY
21077 +       default n
21078 +       help
21079 +         This allows to remap the source IP address of 'local'
21080 +         connections from 127.0.0.1 to the first assigned
21081 +         guest IP.
21082 +
21083 +config VSERVER_COWBL
21084 +       bool    "Enable COW Immutable Link Breaking"
21085 +       depends on EXPERIMENTAL
21086 +       default y
21087 +       help
21088 +         This enables the COW (Copy-On-Write) link break code.
21089 +         It allows you to treat unified files like normal files
21090 +         when writing to them (which will implicitely break the
21091 +         link and create a copy of the unified file)
21092 +
21093 +config VSERVER_VTIME
21094 +       bool    "Enable Virtualized Guest Time"
21095 +       depends on EXPERIMENTAL
21096 +       default n
21097 +       help
21098 +         This enables per guest time offsets to allow for
21099 +         adjusting the system clock individually per guest.
21100 +         this adds some overhead to the time functions and
21101 +         therefore should not be enabled without good reason.
21102 +
21103 +config VSERVER_PROC_SECURE
21104 +       bool    "Enable Proc Security"
21105 +       depends on PROC_FS
21106 +       default y
21107 +       help
21108 +         This configures ProcFS security to initially hide
21109 +         non-process entries for all contexts except the main and
21110 +         spectator context (i.e. for all guests), which is a secure
21111 +         default.
21112 +
21113 +         (note: on 1.2x the entries were visible by default)
21114 +
21115 +config VSERVER_HARDCPU
21116 +       bool    "Enable Hard CPU Limits"
21117 +       depends on EXPERIMENTAL
21118 +       default n
21119 +       help
21120 +         Activate the Hard CPU Limits
21121 +
21122 +         This will compile in code that allows the Token Bucket
21123 +         Scheduler to put processes on hold when a context's
21124 +         tokens are depleted (provided that its per-context
21125 +         sched_hard flag is set).
21126 +
21127 +         Processes belonging to that context will not be able
21128 +         to consume CPU resources again until a per-context
21129 +         configured minimum of tokens has been reached.
21130 +
21131 +config VSERVER_IDLETIME
21132 +       bool    "Avoid idle CPUs by skipping Time"
21133 +       depends on VSERVER_HARDCPU
21134 +       default n
21135 +       help
21136 +         This option allows the scheduler to artificially
21137 +         advance time (per cpu) when otherwise the idle
21138 +         task would be scheduled, thus keeping the cpu
21139 +         busy and sharing the available resources among
21140 +         certain contexts.
21141 +
21142 +config VSERVER_IDLELIMIT
21143 +       bool    "Limit the IDLE task"
21144 +       depends on VSERVER_HARDCPU
21145 +       default n
21146 +       help
21147 +         Limit the idle slices, so the the next context
21148 +         will be scheduled as soon as possible.
21149 +
21150 +         This might improve interactivity and latency, but
21151 +         will also marginally increase scheduling overhead.
21152 +
21153 +choice
21154 +       prompt  "Persistent Inode Tagging"
21155 +       default TAGGING_ID24
21156 +       help
21157 +         This adds persistent context information to filesystems
21158 +         mounted with the tagxid option. Tagging is a requirement
21159 +         for per-context disk limits and per-context quota.
21160 +
21161 +
21162 +config TAGGING_NONE
21163 +       bool    "Disabled"
21164 +       help
21165 +         do not store per-context information in inodes.
21166 +
21167 +config TAGGING_UID16
21168 +       bool    "UID16/GID32"
21169 +       help
21170 +         reduces UID to 16 bit, but leaves GID at 32 bit.
21171 +
21172 +config TAGGING_GID16
21173 +       bool    "UID32/GID16"
21174 +       help
21175 +         reduces GID to 16 bit, but leaves UID at 32 bit.
21176 +
21177 +config TAGGING_ID24
21178 +       bool    "UID24/GID24"
21179 +       help
21180 +         uses the upper 8bit from UID and GID for XID tagging
21181 +         which leaves 24bit for UID/GID each, which should be
21182 +         more than sufficient for normal use.
21183 +
21184 +config TAGGING_INTERN
21185 +       bool    "UID32/GID32"
21186 +       help
21187 +         this uses otherwise reserved inode fields in the on
21188 +         disk representation, which limits the use to a few
21189 +         filesystems (currently ext2 and ext3)
21190 +
21191 +config TAGGING_RUNTIME
21192 +       bool    "Runtime"
21193 +       depends on EXPERIMENTAL
21194 +       help
21195 +         inodes are tagged when first accessed, this doesn't
21196 +         require any persistant information, but might give
21197 +         funny results for mixed access.
21198 +
21199 +endchoice
21200 +
21201 +config TAG_NFSD
21202 +       bool    "Tag NFSD User Auth and Files"
21203 +       default n
21204 +       help
21205 +         Enable this if you do want the in-kernel NFS
21206 +         Server to use the tagging specified above.
21207 +         (will require patched clients too)
21208 +
21209 +config PROPAGATE
21210 +       bool    "Enable Inode Tag Propagation"
21211 +       default n
21212 +       depends on EXPERIMENTAL
21213 +       help
21214 +         This allows for the tagid= mount option to specify
21215 +         a tagid which is to be used for the entire mount
21216 +         tree.
21217 +
21218 +config VSERVER_PRIVACY
21219 +       bool    "Honor Privacy Aspects of Guests"
21220 +       default y
21221 +       help
21222 +         When enabled, most context checks will disallow
21223 +         access to structures assigned to a specific context,
21224 +         like ptys or loop devices.
21225 +
21226 +config VSERVER_DEBUG
21227 +       bool    "VServer Debugging Code"
21228 +       default n
21229 +       help
21230 +         Set this to yes if you want to be able to activate
21231 +         debugging output at runtime. It adds a probably small
21232 +         overhead to all vserver related functions and
21233 +         increases the kernel size by about 20k.
21234 +
21235 +config VSERVER_HISTORY
21236 +       bool    "VServer History Tracing"
21237 +       depends on VSERVER_DEBUG
21238 +       default n
21239 +       help
21240 +         Set this to yes if you want to record the history of
21241 +         linux-vserver activities, so they can be replayed in
21242 +         the event of a kernel panic or oops.
21243 +
21244 +config VSERVER_HISTORY_SIZE
21245 +       int "Per-CPU History Size (32-65536)"
21246 +       depends on VSERVER_HISTORY
21247 +       range 32 65536
21248 +       default 64
21249 +       help
21250 +         This allows you to specify the number of entries in
21251 +         the per-CPU history buffer.
21252 +
21253 +config VSERVER_MONITOR
21254 +       bool    "VServer Scheduling Monitor"
21255 +       depends on VSERVER_DEBUG
21256 +       default n
21257 +       help
21258 +         Set this to yes if you want to record the scheduling
21259 +         decisions, so that they can be relayed to userspace
21260 +         for detailed analysis.
21261 +
21262 +config VSERVER_MONITOR_SIZE
21263 +       int "Per-CPU Monitor Queue Size (32-65536)"
21264 +       depends on VSERVER_MONITOR
21265 +       range 32 65536
21266 +       default 1024
21267 +       help
21268 +         This allows you to specify the number of entries in
21269 +         the per-CPU scheduling monitor buffer.
21270 +
21271 +config VSERVER_MONITOR_SYNC
21272 +       int "Per-CPU Monitor Sync Interval (0-65536)"
21273 +       depends on VSERVER_MONITOR
21274 +       range 0 65536
21275 +       default 256
21276 +       help
21277 +         This allows you to specify the interval in ticks
21278 +         when a time sync entry is inserted.
21279 +
21280 +endmenu
21281 +
21282 +
21283 +config VSERVER
21284 +       bool
21285 +       default y
21286 +
21287 +config VSERVER_SECURITY
21288 +       bool
21289 +       depends on SECURITY
21290 +       default y
21291 +       select SECURITY_CAPABILITIES
21292 +
21293 +config VSERVER_LEGACYNET
21294 +       bool
21295 +       depends on !VSERVER_NGNET
21296 +       default y
21297 +
21298 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/Makefile linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/Makefile
21299 --- linux-2.6.17.11/kernel/vserver/Makefile     1970-01-01 01:00:00 +0100
21300 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/Makefile        2006-08-19 04:03:39 +0200
21301 @@ -0,0 +1,17 @@
21302 +#
21303 +# Makefile for the Linux vserver routines.
21304 +#
21305 +
21306 +
21307 +obj-y          += vserver.o
21308 +
21309 +vserver-y      := switch.o context.o namespace.o sched.o network.o inode.o \
21310 +                  limit.o cvirt.o cacct.o signal.o helper.o init.o dlimit.o
21311 +
21312 +vserver-$(CONFIG_PROC_FS) += proc.o
21313 +vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
21314 +vserver-$(CONFIG_VSERVER_LEGACY) += legacy.o
21315 +vserver-$(CONFIG_VSERVER_LEGACYNET) += legacynet.o
21316 +vserver-$(CONFIG_VSERVER_HISTORY) += history.o
21317 +vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
21318 +
21319 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/cacct.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cacct.c
21320 --- linux-2.6.17.11/kernel/vserver/cacct.c      1970-01-01 01:00:00 +0100
21321 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cacct.c 2006-08-19 04:06:16 +0200
21322 @@ -0,0 +1,43 @@
21323 +/*
21324 + *  linux/kernel/vserver/cacct.c
21325 + *
21326 + *  Virtual Server: Context Accounting
21327 + *
21328 + *  Copyright (C) 2006  Herbert Pötzl
21329 + *
21330 + *  V0.01  added accounting stats
21331 + *
21332 + */
21333 +
21334 +#include <linux/types.h>
21335 +#include <linux/vs_base.h>
21336 +#include <linux/vserver/switch.h>
21337 +#include <linux/vserver/cacct_cmd.h>
21338 +#include <linux/vserver/cacct_int.h>
21339 +
21340 +#include <asm/errno.h>
21341 +#include <asm/uaccess.h>
21342 +
21343 +
21344 +int vc_sock_stat(struct vx_info *vxi, void __user *data)
21345 +{
21346 +       struct vcmd_sock_stat_v0 vc_data;
21347 +       int j, field;
21348 +
21349 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
21350 +               return -EFAULT;
21351 +
21352 +       field = vc_data.field;
21353 +       if ((field < 0) || (field >= VXA_SOCK_SIZE))
21354 +               return -EINVAL;
21355 +
21356 +       for (j=0; j<3; j++) {
21357 +               vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
21358 +               vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
21359 +       }
21360 +
21361 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
21362 +               return -EFAULT;
21363 +       return 0;
21364 +}
21365 +
21366 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/cacct_init.h linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cacct_init.h
21367 --- linux-2.6.17.11/kernel/vserver/cacct_init.h 1970-01-01 01:00:00 +0100
21368 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cacct_init.h    2006-08-19 02:59:48 +0200
21369 @@ -0,0 +1,25 @@
21370 +
21371 +
21372 +static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
21373 +{
21374 +       int i,j;
21375 +
21376 +
21377 +       for (i=0; i<VXA_SOCK_SIZE; i++) {
21378 +               for (j=0; j<3; j++) {
21379 +                       atomic_set(&cacct->sock[i][j].count, 0);
21380 +                       atomic_set(&cacct->sock[i][j].total, 0);
21381 +               }
21382 +       }
21383 +       for (i=0; i<8; i++)
21384 +               atomic_set(&cacct->slab[i], 0);
21385 +       for (i=0; i<5; i++)
21386 +               for (j=0; j<4; j++)
21387 +                       atomic_set(&cacct->page[i][j], 0);
21388 +}
21389 +
21390 +static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
21391 +{
21392 +       return;
21393 +}
21394 +
21395 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/cacct_proc.h linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cacct_proc.h
21396 --- linux-2.6.17.11/kernel/vserver/cacct_proc.h 1970-01-01 01:00:00 +0100
21397 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cacct_proc.h    2006-08-19 03:52:45 +0200
21398 @@ -0,0 +1,58 @@
21399 +#ifndef _VX_CACCT_PROC_H
21400 +#define _VX_CACCT_PROC_H
21401 +
21402 +#include <linux/vserver/cacct_int.h>
21403 +
21404 +
21405 +#define VX_SOCKA_TOP   \
21406 +       "Type\t    recv #/bytes\t\t   send #/bytes\t\t    fail #/bytes\n"
21407 +
21408 +static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
21409 +{
21410 +       int i,j, length = 0;
21411 +       static char *type[VXA_SOCK_SIZE] = {
21412 +               "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER" };
21413 +
21414 +       length += sprintf(buffer + length, VX_SOCKA_TOP);
21415 +       for (i=0; i<VXA_SOCK_SIZE; i++) {
21416 +               length += sprintf(buffer + length,
21417 +                       "%s:", type[i]);
21418 +               for (j=0; j<3; j++) {
21419 +                       length += sprintf(buffer + length,
21420 +                               "\t%10lu/%-10lu"
21421 +                               ,vx_sock_count(cacct, i, j)
21422 +                               ,vx_sock_total(cacct, i, j)
21423 +                               );
21424 +               }
21425 +               buffer[length++] = '\n';
21426 +       }
21427 +
21428 +       length += sprintf(buffer + length, "\n");
21429 +       length += sprintf(buffer + length,
21430 +               "slab:\t %8u %8u %8u %8u\n"
21431 +               ,atomic_read(&cacct->slab[1])
21432 +               ,atomic_read(&cacct->slab[4])
21433 +               ,atomic_read(&cacct->slab[0])
21434 +               ,atomic_read(&cacct->slab[2])
21435 +               );
21436 +
21437 +       length += sprintf(buffer + length, "\n");
21438 +       for (i=0; i<5; i++) {
21439 +               length += sprintf(buffer + length,
21440 +                       "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n"
21441 +                       ,i
21442 +                       ,atomic_read(&cacct->page[i][0])
21443 +                       ,atomic_read(&cacct->page[i][1])
21444 +                       ,atomic_read(&cacct->page[i][2])
21445 +                       ,atomic_read(&cacct->page[i][3])
21446 +                       ,atomic_read(&cacct->page[i][4])
21447 +                       ,atomic_read(&cacct->page[i][5])
21448 +                       ,atomic_read(&cacct->page[i][6])
21449 +                       ,atomic_read(&cacct->page[i][7])
21450 +                       );
21451 +       }
21452 +
21453 +       return length;
21454 +}
21455 +
21456 +#endif /* _VX_CACCT_PROC_H */
21457 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/context.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/context.c
21458 --- linux-2.6.17.11/kernel/vserver/context.c    1970-01-01 01:00:00 +0100
21459 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/context.c       2006-08-26 00:52:08 +0200
21460 @@ -0,0 +1,1049 @@
21461 +/*
21462 + *  linux/kernel/vserver/context.c
21463 + *
21464 + *  Virtual Server: Context Support
21465 + *
21466 + *  Copyright (C) 2003-2006  Herbert Pötzl
21467 + *
21468 + *  V0.01  context helper
21469 + *  V0.02  vx_ctx_kill syscall command
21470 + *  V0.03  replaced context_info calls
21471 + *  V0.04  redesign of struct (de)alloc
21472 + *  V0.05  rlimit basic implementation
21473 + *  V0.06  task_xid and info commands
21474 + *  V0.07  context flags and caps
21475 + *  V0.08  switch to RCU based hash
21476 + *  V0.09  revert to non RCU for now
21477 + *  V0.10  and back to working RCU hash
21478 + *  V0.11  and back to locking again
21479 + *  V0.12  referenced context store
21480 + *  V0.13  separate per cpu data
21481 + *  V0.14  changed vcmds to vxi arg
21482 + *
21483 + */
21484 +
21485 +#include <linux/slab.h>
21486 +#include <linux/types.h>
21487 +#include <linux/namespace.h>
21488 +
21489 +#include <linux/sched.h>
21490 +#include <linux/vserver/network.h>
21491 +#include <linux/vserver/legacy.h>
21492 +#include <linux/vserver/limit.h>
21493 +#include <linux/vserver/debug.h>
21494 +#include <linux/vserver/limit_int.h>
21495 +
21496 +#include <linux/vs_context.h>
21497 +#include <linux/vs_limit.h>
21498 +#include <linux/vserver/context_cmd.h>
21499 +
21500 +#include <linux/err.h>
21501 +#include <asm/errno.h>
21502 +
21503 +#include "cvirt_init.h"
21504 +#include "cacct_init.h"
21505 +#include "limit_init.h"
21506 +#include "sched_init.h"
21507 +
21508 +
21509 +atomic_t vx_global_ctotal      = ATOMIC_INIT(0);
21510 +atomic_t vx_global_cactive     = ATOMIC_INIT(0);
21511 +
21512 +
21513 +/*     now inactive context structures */
21514 +
21515 +static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
21516 +
21517 +static spinlock_t vx_info_inactive_lock = SPIN_LOCK_UNLOCKED;
21518 +
21519 +
21520 +/*     __alloc_vx_info()
21521 +
21522 +       * allocate an initialized vx_info struct
21523 +       * doesn't make it visible (hash)                        */
21524 +
21525 +static struct vx_info *__alloc_vx_info(xid_t xid)
21526 +{
21527 +       struct vx_info *new = NULL;
21528 +       int cpu;
21529 +
21530 +       vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
21531 +
21532 +       /* would this benefit from a slab cache? */
21533 +       new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
21534 +       if (!new)
21535 +               return 0;
21536 +
21537 +       memset (new, 0, sizeof(struct vx_info));
21538 +#ifdef CONFIG_SMP
21539 +       new->ptr_pc = alloc_percpu(struct _vx_info_pc);
21540 +       if (!new->ptr_pc)
21541 +               goto error;
21542 +#endif
21543 +       new->vx_id = xid;
21544 +       INIT_HLIST_NODE(&new->vx_hlist);
21545 +       atomic_set(&new->vx_usecnt, 0);
21546 +       atomic_set(&new->vx_tasks, 0);
21547 +       new->vx_parent = NULL;
21548 +       new->vx_state = 0;
21549 +       init_waitqueue_head(&new->vx_wait);
21550 +
21551 +       /* prepare reaper */
21552 +       get_task_struct(child_reaper);
21553 +       new->vx_reaper = child_reaper;
21554 +
21555 +       /* rest of init goes here */
21556 +       vx_info_init_limit(&new->limit);
21557 +       vx_info_init_sched(&new->sched);
21558 +       vx_info_init_cvirt(&new->cvirt);
21559 +       vx_info_init_cacct(&new->cacct);
21560 +
21561 +       /* per cpu data structures */
21562 +       for_each_cpu(cpu) {
21563 +               vx_info_init_sched_pc(
21564 +                       &vx_per_cpu(new, sched_pc, cpu), cpu);
21565 +               vx_info_init_cvirt_pc(
21566 +                       &vx_per_cpu(new, cvirt_pc, cpu), cpu);
21567 +       }
21568 +
21569 +       new->vx_flags = VXF_INIT_SET;
21570 +       new->vx_bcaps = CAP_INIT_EFF_SET;
21571 +       new->vx_ccaps = 0;
21572 +       new->vx_cap_bset = cap_bset;
21573 +
21574 +       new->reboot_cmd = 0;
21575 +       new->exit_code = 0;
21576 +
21577 +       vxdprintk(VXD_CBIT(xid, 0),
21578 +               "alloc_vx_info(%d) = %p", xid, new);
21579 +       vxh_alloc_vx_info(new);
21580 +       atomic_inc(&vx_global_ctotal);
21581 +       return new;
21582 +#ifdef CONFIG_SMP
21583 +error:
21584 +       kfree(new);
21585 +       return 0;
21586 +#endif
21587 +}
21588 +
21589 +/*     __dealloc_vx_info()
21590 +
21591 +       * final disposal of vx_info                             */
21592 +
21593 +static void __dealloc_vx_info(struct vx_info *vxi)
21594 +{
21595 +       int cpu;
21596 +
21597 +       vxdprintk(VXD_CBIT(xid, 0),
21598 +               "dealloc_vx_info(%p)", vxi);
21599 +       vxh_dealloc_vx_info(vxi);
21600 +
21601 +       vxi->vx_id = -1;
21602 +
21603 +       vx_info_exit_limit(&vxi->limit);
21604 +       vx_info_exit_sched(&vxi->sched);
21605 +       vx_info_exit_cvirt(&vxi->cvirt);
21606 +       vx_info_exit_cacct(&vxi->cacct);
21607 +
21608 +       for_each_cpu(cpu) {
21609 +               vx_info_exit_sched_pc(
21610 +                       &vx_per_cpu(vxi, sched_pc, cpu), cpu);
21611 +               vx_info_exit_cvirt_pc(
21612 +                       &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
21613 +       }
21614 +
21615 +       vxi->vx_state |= VXS_RELEASED;
21616 +
21617 +#ifdef CONFIG_SMP
21618 +       free_percpu(vxi->ptr_pc);
21619 +#endif
21620 +       kfree(vxi);
21621 +       atomic_dec(&vx_global_ctotal);
21622 +}
21623 +
21624 +static void __shutdown_vx_info(struct vx_info *vxi)
21625 +{
21626 +       struct namespace *namespace;
21627 +       struct fs_struct *fs;
21628 +
21629 +       might_sleep();
21630 +
21631 +       vxi->vx_state |= VXS_SHUTDOWN;
21632 +       vs_state_change(vxi, VSC_SHUTDOWN);
21633 +
21634 +       namespace = xchg(&vxi->vx_namespace, NULL);
21635 +       if (namespace)
21636 +               put_namespace(namespace);
21637 +
21638 +       fs = xchg(&vxi->vx_fs, NULL);
21639 +       if (fs)
21640 +               put_fs_struct(fs);
21641 +}
21642 +
21643 +/* exported stuff */
21644 +
21645 +void free_vx_info(struct vx_info *vxi)
21646 +{
21647 +       /* context shutdown is mandatory */
21648 +       BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
21649 +
21650 +       BUG_ON(atomic_read(&vxi->vx_usecnt));
21651 +       BUG_ON(atomic_read(&vxi->vx_tasks));
21652 +
21653 +       BUG_ON(vx_info_state(vxi, VXS_HASHED));
21654 +
21655 +       BUG_ON(vxi->vx_namespace);
21656 +       BUG_ON(vxi->vx_fs);
21657 +
21658 +       spin_lock(&vx_info_inactive_lock);
21659 +       hlist_del(&vxi->vx_hlist);
21660 +       spin_unlock(&vx_info_inactive_lock);
21661 +
21662 +       __dealloc_vx_info(vxi);
21663 +}
21664 +
21665 +
21666 +/*     hash table for vx_info hash */
21667 +
21668 +#define VX_HASH_SIZE   13
21669 +
21670 +static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
21671 +       { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
21672 +
21673 +static spinlock_t vx_info_hash_lock = SPIN_LOCK_UNLOCKED;
21674 +
21675 +
21676 +static inline unsigned int __hashval(xid_t xid)
21677 +{
21678 +       return (xid % VX_HASH_SIZE);
21679 +}
21680 +
21681 +
21682 +
21683 +/*     __hash_vx_info()
21684 +
21685 +       * add the vxi to the global hash table
21686 +       * requires the hash_lock to be held                     */
21687 +
21688 +static inline void __hash_vx_info(struct vx_info *vxi)
21689 +{
21690 +       struct hlist_head *head;
21691 +
21692 +       vxd_assert_lock(&vx_info_hash_lock);
21693 +       vxdprintk(VXD_CBIT(xid, 4),
21694 +               "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
21695 +       vxh_hash_vx_info(vxi);
21696 +
21697 +       /* context must not be hashed */
21698 +       BUG_ON(vx_info_state(vxi, VXS_HASHED));
21699 +
21700 +       vxi->vx_state |= VXS_HASHED;
21701 +       head = &vx_info_hash[__hashval(vxi->vx_id)];
21702 +       hlist_add_head(&vxi->vx_hlist, head);
21703 +       atomic_inc(&vx_global_cactive);
21704 +}
21705 +
21706 +/*     __unhash_vx_info()
21707 +
21708 +       * remove the vxi from the global hash table
21709 +       * requires the hash_lock to be held                     */
21710 +
21711 +static inline void __unhash_vx_info(struct vx_info *vxi)
21712 +{
21713 +       vxd_assert_lock(&vx_info_hash_lock);
21714 +       vxdprintk(VXD_CBIT(xid, 4),
21715 +               "__unhash_vx_info: %p[#%d]", vxi, vxi->vx_id);
21716 +       vxh_unhash_vx_info(vxi);
21717 +
21718 +       /* context must be hashed */
21719 +       BUG_ON(!vx_info_state(vxi, VXS_HASHED));
21720 +
21721 +       vxi->vx_state &= ~VXS_HASHED;
21722 +       hlist_del_init(&vxi->vx_hlist);
21723 +       spin_lock(&vx_info_inactive_lock);
21724 +       hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
21725 +       spin_unlock(&vx_info_inactive_lock);
21726 +       atomic_dec(&vx_global_cactive);
21727 +}
21728 +
21729 +
21730 +/*     __lookup_vx_info()
21731 +
21732 +       * requires the hash_lock to be held
21733 +       * doesn't increment the vx_refcnt                       */
21734 +
21735 +static inline struct vx_info *__lookup_vx_info(xid_t xid)
21736 +{
21737 +       struct hlist_head *head = &vx_info_hash[__hashval(xid)];
21738 +       struct hlist_node *pos;
21739 +       struct vx_info *vxi;
21740 +
21741 +       vxd_assert_lock(&vx_info_hash_lock);
21742 +       hlist_for_each(pos, head) {
21743 +               vxi = hlist_entry(pos, struct vx_info, vx_hlist);
21744 +
21745 +               if (vxi->vx_id == xid)
21746 +                       goto found;
21747 +       }
21748 +       vxi = NULL;
21749 +found:
21750 +       vxdprintk(VXD_CBIT(xid, 0),
21751 +               "__lookup_vx_info(#%u): %p[#%u]",
21752 +               xid, vxi, vxi?vxi->vx_id:0);
21753 +       vxh_lookup_vx_info(vxi, xid);
21754 +       return vxi;
21755 +}
21756 +
21757 +
21758 +/*     __vx_dynamic_id()
21759 +
21760 +       * find unused dynamic xid
21761 +       * requires the hash_lock to be held                     */
21762 +
21763 +static inline xid_t __vx_dynamic_id(void)
21764 +{
21765 +       static xid_t seq = MAX_S_CONTEXT;
21766 +       xid_t barrier = seq;
21767 +
21768 +       vxd_assert_lock(&vx_info_hash_lock);
21769 +       do {
21770 +               if (++seq > MAX_S_CONTEXT)
21771 +                       seq = MIN_D_CONTEXT;
21772 +               if (!__lookup_vx_info(seq)) {
21773 +                       vxdprintk(VXD_CBIT(xid, 4),
21774 +                               "__vx_dynamic_id: [#%d]", seq);
21775 +                       return seq;
21776 +               }
21777 +       } while (barrier != seq);
21778 +       return 0;
21779 +}
21780 +
21781 +#ifdef CONFIG_VSERVER_LEGACY
21782 +
21783 +/*     __loc_vx_info()
21784 +
21785 +       * locate or create the requested context
21786 +       * get() it and if new hash it                           */
21787 +
21788 +static struct vx_info * __loc_vx_info(int id, int *err)
21789 +{
21790 +       struct vx_info *new, *vxi = NULL;
21791 +
21792 +       vxdprintk(VXD_CBIT(xid, 1), "loc_vx_info(%d)*", id);
21793 +
21794 +       if (!(new = __alloc_vx_info(id))) {
21795 +               *err = -ENOMEM;
21796 +               return NULL;
21797 +       }
21798 +
21799 +       /* required to make dynamic xids unique */
21800 +       spin_lock(&vx_info_hash_lock);
21801 +
21802 +       /* dynamic context requested */
21803 +       if (id == VX_DYNAMIC_ID) {
21804 +#ifdef CONFIG_VSERVER_DYNAMIC_IDS
21805 +               id = __vx_dynamic_id();
21806 +               if (!id) {
21807 +                       printk(KERN_ERR "no dynamic context available.\n");
21808 +                       goto out_unlock;
21809 +               }
21810 +               new->vx_id = id;
21811 +#else
21812 +               printk(KERN_ERR "dynamic contexts disabled.\n");
21813 +               goto out_unlock;
21814 +#endif
21815 +       }
21816 +       /* existing context requested */
21817 +       else if ((vxi = __lookup_vx_info(id))) {
21818 +               /* context in setup is not available */
21819 +               if (vxi->vx_flags & VXF_STATE_SETUP) {
21820 +                       vxdprintk(VXD_CBIT(xid, 0),
21821 +                               "loc_vx_info(%d) = %p (not available)", id, vxi);
21822 +                       vxi = NULL;
21823 +                       *err = -EBUSY;
21824 +               } else {
21825 +                       vxdprintk(VXD_CBIT(xid, 0),
21826 +                               "loc_vx_info(%d) = %p (found)", id, vxi);
21827 +                       get_vx_info(vxi);
21828 +                       *err = 0;
21829 +               }
21830 +               goto out_unlock;
21831 +       }
21832 +
21833 +       /* new context requested */
21834 +       vxdprintk(VXD_CBIT(xid, 0),
21835 +               "loc_vx_info(%d) = %p (new)", id, new);
21836 +       __hash_vx_info(get_vx_info(new));
21837 +       vxi = new, new = NULL;
21838 +       *err = 1;
21839 +
21840 +out_unlock:
21841 +       spin_unlock(&vx_info_hash_lock);
21842 +       vxh_loc_vx_info(vxi, id);
21843 +       if (new)
21844 +               __dealloc_vx_info(new);
21845 +       return vxi;
21846 +}
21847 +
21848 +#endif
21849 +
21850 +/*     __create_vx_info()
21851 +
21852 +       * create the requested context
21853 +       * get() and hash it                                     */
21854 +
21855 +static struct vx_info * __create_vx_info(int id)
21856 +{
21857 +       struct vx_info *new, *vxi = NULL;
21858 +
21859 +       vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
21860 +
21861 +       if (!(new = __alloc_vx_info(id)))
21862 +               return ERR_PTR(-ENOMEM);
21863 +
21864 +       /* required to make dynamic xids unique */
21865 +       spin_lock(&vx_info_hash_lock);
21866 +
21867 +       /* dynamic context requested */
21868 +       if (id == VX_DYNAMIC_ID) {
21869 +#ifdef CONFIG_VSERVER_DYNAMIC_IDS
21870 +               id = __vx_dynamic_id();
21871 +               if (!id) {
21872 +                       printk(KERN_ERR "no dynamic context available.\n");
21873 +                       vxi = ERR_PTR(-EAGAIN);
21874 +                       goto out_unlock;
21875 +               }
21876 +               new->vx_id = id;
21877 +#else
21878 +               printk(KERN_ERR "dynamic contexts disabled.\n");
21879 +               vxi = ERR_PTR(-EINVAL);
21880 +               goto out_unlock;
21881 +#endif
21882 +       }
21883 +       /* static context requested */
21884 +       else if ((vxi = __lookup_vx_info(id))) {
21885 +               vxdprintk(VXD_CBIT(xid, 0),
21886 +                       "create_vx_info(%d) = %p (already there)", id, vxi);
21887 +               if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
21888 +                       vxi = ERR_PTR(-EBUSY);
21889 +               else
21890 +                       vxi = ERR_PTR(-EEXIST);
21891 +               goto out_unlock;
21892 +       }
21893 +#ifdef CONFIG_VSERVER_DYNAMIC_IDS
21894 +       /* dynamic xid creation blocker */
21895 +       else if (id >= MIN_D_CONTEXT) {
21896 +               vxdprintk(VXD_CBIT(xid, 0),
21897 +                       "create_vx_info(%d) (dynamic rejected)", id);
21898 +               vxi = ERR_PTR(-EINVAL);
21899 +               goto out_unlock;
21900 +       }
21901 +#endif
21902 +
21903 +       /* new context */
21904 +       vxdprintk(VXD_CBIT(xid, 0),
21905 +               "create_vx_info(%d) = %p (new)", id, new);
21906 +       __hash_vx_info(get_vx_info(new));
21907 +       vxi = new, new = NULL;
21908 +
21909 +out_unlock:
21910 +       spin_unlock(&vx_info_hash_lock);
21911 +       vxh_create_vx_info(IS_ERR(vxi)?NULL:vxi, id);
21912 +       if (new)
21913 +               __dealloc_vx_info(new);
21914 +       return vxi;
21915 +}
21916 +
21917 +
21918 +/*     exported stuff                                          */
21919 +
21920 +
21921 +void unhash_vx_info(struct vx_info *vxi)
21922 +{
21923 +       __shutdown_vx_info(vxi);
21924 +       spin_lock(&vx_info_hash_lock);
21925 +       __unhash_vx_info(vxi);
21926 +       spin_unlock(&vx_info_hash_lock);
21927 +       __wakeup_vx_info(vxi);
21928 +}
21929 +
21930 +
21931 +/*     lookup_vx_info()
21932 +
21933 +       * search for a vx_info and get() it
21934 +       * negative id means current                             */
21935 +
21936 +struct vx_info *lookup_vx_info(int id)
21937 +{
21938 +       struct vx_info *vxi = NULL;
21939 +
21940 +       if (id < 0) {
21941 +               vxi = get_vx_info(current->vx_info);
21942 +       } else if (id > 1) {
21943 +               spin_lock(&vx_info_hash_lock);
21944 +               vxi = get_vx_info(__lookup_vx_info(id));
21945 +               spin_unlock(&vx_info_hash_lock);
21946 +       }
21947 +       return vxi;
21948 +}
21949 +
21950 +/*     xid_is_hashed()
21951 +
21952 +       * verify that xid is still hashed                       */
21953 +
21954 +int xid_is_hashed(xid_t xid)
21955 +{
21956 +       int hashed;
21957 +
21958 +       spin_lock(&vx_info_hash_lock);
21959 +       hashed = (__lookup_vx_info(xid) != NULL);
21960 +       spin_unlock(&vx_info_hash_lock);
21961 +       return hashed;
21962 +}
21963 +
21964 +#ifdef CONFIG_VSERVER_LEGACY
21965 +
21966 +struct vx_info *lookup_or_create_vx_info(int id)
21967 +{
21968 +       int err;
21969 +
21970 +       return __loc_vx_info(id, &err);
21971 +}
21972 +
21973 +#endif
21974 +
21975 +#ifdef CONFIG_PROC_FS
21976 +
21977 +/*     get_xid_list()
21978 +
21979 +       * get a subset of hashed xids for proc
21980 +       * assumes size is at least one                          */
21981 +
21982 +int get_xid_list(int index, unsigned int *xids, int size)
21983 +{
21984 +       int hindex, nr_xids = 0;
21985 +
21986 +       /* only show current and children */
21987 +       if (!vx_check(0, VX_ADMIN|VX_WATCH)) {
21988 +               if (index > 0)
21989 +                       return 0;
21990 +               xids[nr_xids] = vx_current_xid();
21991 +               return 1;
21992 +       }
21993 +
21994 +       for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
21995 +               struct hlist_head *head = &vx_info_hash[hindex];
21996 +               struct hlist_node *pos;
21997 +
21998 +               spin_lock(&vx_info_hash_lock);
21999 +               hlist_for_each(pos, head) {
22000 +                       struct vx_info *vxi;
22001 +
22002 +                       if (--index > 0)
22003 +                               continue;
22004 +
22005 +                       vxi = hlist_entry(pos, struct vx_info, vx_hlist);
22006 +                       xids[nr_xids] = vxi->vx_id;
22007 +                       if (++nr_xids >= size) {
22008 +                               spin_unlock(&vx_info_hash_lock);
22009 +                               goto out;
22010 +                       }
22011 +               }
22012 +               /* keep the lock time short */
22013 +               spin_unlock(&vx_info_hash_lock);
22014 +       }
22015 +out:
22016 +       return nr_xids;
22017 +}
22018 +#endif
22019 +
22020 +#ifdef CONFIG_VSERVER_DEBUG
22021 +
22022 +void   dump_vx_info_inactive(int level)
22023 +{
22024 +       struct hlist_node *entry, *next;
22025 +
22026 +       hlist_for_each_safe(entry, next, &vx_info_inactive) {
22027 +               struct vx_info *vxi =
22028 +                       list_entry(entry, struct vx_info, vx_hlist);
22029 +
22030 +               dump_vx_info(vxi, level);
22031 +       }
22032 +}
22033 +
22034 +#endif
22035 +
22036 +int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
22037 +{
22038 +       struct user_struct *new_user, *old_user;
22039 +
22040 +       if (!p || !vxi)
22041 +               BUG();
22042 +
22043 +       if (vx_info_flags(vxi, VXF_INFO_LOCK, 0))
22044 +               return -EACCES;
22045 +
22046 +       new_user = alloc_uid(vxi->vx_id, p->uid);
22047 +       if (!new_user)
22048 +               return -ENOMEM;
22049 +
22050 +       old_user = p->user;
22051 +       if (new_user != old_user) {
22052 +               atomic_inc(&new_user->processes);
22053 +               atomic_dec(&old_user->processes);
22054 +               p->user = new_user;
22055 +       }
22056 +       free_uid(old_user);
22057 +       return 0;
22058 +}
22059 +
22060 +void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
22061 +{
22062 +       p->cap_effective &= vxi->vx_cap_bset;
22063 +       p->cap_inheritable &= vxi->vx_cap_bset;
22064 +       p->cap_permitted &= vxi->vx_cap_bset;
22065 +}
22066 +
22067 +
22068 +#include <linux/file.h>
22069 +
22070 +static int vx_openfd_task(struct task_struct *tsk)
22071 +{
22072 +       struct files_struct *files = tsk->files;
22073 +       struct fdtable *fdt;
22074 +       const unsigned long *bptr;
22075 +       int count, total;
22076 +
22077 +       /* no rcu_read_lock() because of spin_lock() */
22078 +       spin_lock(&files->file_lock);
22079 +       fdt = files_fdtable(files);
22080 +       bptr = fdt->open_fds->fds_bits;
22081 +       count = fdt->max_fds / (sizeof(unsigned long) * 8);
22082 +       for (total = 0; count > 0; count--) {
22083 +               if (*bptr)
22084 +                       total += hweight_long(*bptr);
22085 +               bptr++;
22086 +       }
22087 +       spin_unlock(&files->file_lock);
22088 +       return total;
22089 +}
22090 +
22091 +/*
22092 + *     migrate task to new context
22093 + *     gets vxi, puts old_vxi on change
22094 + */
22095 +
22096 +int vx_migrate_task(struct task_struct *p, struct vx_info *vxi)
22097 +{
22098 +       struct vx_info *old_vxi;
22099 +       int ret = 0;
22100 +
22101 +       if (!p || !vxi)
22102 +               BUG();
22103 +
22104 +       vxdprintk(VXD_CBIT(xid, 5),
22105 +               "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
22106 +               vxi->vx_id, atomic_read(&vxi->vx_usecnt));
22107 +
22108 +       if (vx_info_flags(vxi, VXF_INFO_LOCK, 0))
22109 +               return -EACCES;
22110 +
22111 +       old_vxi = task_get_vx_info(p);
22112 +       if (old_vxi == vxi)
22113 +               goto out;
22114 +
22115 +       if (!(ret = vx_migrate_user(p, vxi))) {
22116 +               int openfd;
22117 +
22118 +               task_lock(p);
22119 +               openfd = vx_openfd_task(p);
22120 +
22121 +               if (old_vxi) {
22122 +                       atomic_dec(&old_vxi->cvirt.nr_threads);
22123 +                       atomic_dec(&old_vxi->cvirt.nr_running);
22124 +                       __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
22125 +                       /* FIXME: what about the struct files here? */
22126 +                       __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
22127 +                       /* account for the executable */
22128 +                       __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
22129 +               }
22130 +               atomic_inc(&vxi->cvirt.nr_threads);
22131 +               atomic_inc(&vxi->cvirt.nr_running);
22132 +               __rlim_inc(&vxi->limit, RLIMIT_NPROC);
22133 +               /* FIXME: what about the struct files here? */
22134 +               __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
22135 +               /* account for the executable */
22136 +               __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
22137 +
22138 +               if (old_vxi) {
22139 +                       release_vx_info(old_vxi, p);
22140 +                       clr_vx_info(&p->vx_info);
22141 +               }
22142 +               claim_vx_info(vxi, p);
22143 +               set_vx_info(&p->vx_info, vxi);
22144 +               p->xid = vxi->vx_id;
22145 +
22146 +               vxdprintk(VXD_CBIT(xid, 5),
22147 +                       "moved task %p into vxi:%p[#%d]",
22148 +                       p, vxi, vxi->vx_id);
22149 +
22150 +               vx_mask_cap_bset(vxi, p);
22151 +               task_unlock(p);
22152 +       }
22153 +out:
22154 +       put_vx_info(old_vxi);
22155 +       return ret;
22156 +}
22157 +
22158 +int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
22159 +{
22160 +       struct task_struct *old_reaper;
22161 +
22162 +       if (!vxi)
22163 +               return -EINVAL;
22164 +
22165 +       vxdprintk(VXD_CBIT(xid, 6),
22166 +               "vx_set_reaper(%p[#%d],%p[#%d,%d])",
22167 +               vxi, vxi->vx_id, p, p->xid, p->pid);
22168 +
22169 +       old_reaper = vxi->vx_reaper;
22170 +       if (old_reaper == p)
22171 +               return 0;
22172 +
22173 +       /* set new child reaper */
22174 +       get_task_struct(p);
22175 +       vxi->vx_reaper = p;
22176 +       put_task_struct(old_reaper);
22177 +       return 0;
22178 +}
22179 +
22180 +int vx_set_init(struct vx_info *vxi, struct task_struct *p)
22181 +{
22182 +       if (!vxi)
22183 +               return -EINVAL;
22184 +
22185 +       vxdprintk(VXD_CBIT(xid, 6),
22186 +               "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
22187 +               vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
22188 +
22189 +       vxi->vx_initpid = p->tgid;
22190 +       return 0;
22191 +}
22192 +
22193 +void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
22194 +{
22195 +       vxdprintk(VXD_CBIT(xid, 6),
22196 +               "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
22197 +               vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
22198 +
22199 +       vxi->exit_code = code;
22200 +       vxi->vx_initpid = 0;
22201 +}
22202 +
22203 +
22204 +void vx_set_persistent(struct vx_info *vxi)
22205 +{
22206 +       vxdprintk(VXD_CBIT(xid, 6),
22207 +               "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
22208 +
22209 +       get_vx_info(vxi);
22210 +       claim_vx_info(vxi, current);
22211 +}
22212 +
22213 +void vx_clear_persistent(struct vx_info *vxi)
22214 +{
22215 +       vxdprintk(VXD_CBIT(xid, 6),
22216 +               "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
22217 +
22218 +       release_vx_info(vxi, current);
22219 +       put_vx_info(vxi);
22220 +}
22221 +
22222 +void vx_update_persistent(struct vx_info *vxi)
22223 +{
22224 +       if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
22225 +               vx_set_persistent(vxi);
22226 +       else
22227 +               vx_clear_persistent(vxi);
22228 +}
22229 +
22230 +
22231 +/*     task must be current or locked          */
22232 +
22233 +void   exit_vx_info(struct task_struct *p, int code)
22234 +{
22235 +       struct vx_info *vxi = p->vx_info;
22236 +
22237 +       if (vxi) {
22238 +               atomic_dec(&vxi->cvirt.nr_threads);
22239 +               vx_nproc_dec(p);
22240 +
22241 +               vxi->exit_code = code;
22242 +               if (vxi->vx_initpid == p->tgid)
22243 +                       vx_exit_init(vxi, p, code);
22244 +               if (vxi->vx_reaper == p)
22245 +                       vx_set_reaper(vxi, child_reaper);
22246 +               release_vx_info(vxi, p);
22247 +       }
22248 +}
22249 +
22250 +
22251 +/* vserver syscall commands below here */
22252 +
22253 +/* taks xid and vx_info functions */
22254 +
22255 +#include <asm/uaccess.h>
22256 +
22257 +
22258 +int vc_task_xid(uint32_t id, void __user *data)
22259 +{
22260 +       xid_t xid;
22261 +
22262 +       if (id) {
22263 +               struct task_struct *tsk;
22264 +
22265 +               if (!vx_check(0, VX_ADMIN|VX_WATCH))
22266 +                       return -EPERM;
22267 +
22268 +               read_lock(&tasklist_lock);
22269 +               tsk = find_task_by_real_pid(id);
22270 +               xid = (tsk) ? tsk->xid : -ESRCH;
22271 +               read_unlock(&tasklist_lock);
22272 +       }
22273 +       else
22274 +               xid = vx_current_xid();
22275 +       return xid;
22276 +}
22277 +
22278 +
22279 +int vc_vx_info(struct vx_info *vxi, void __user *data)
22280 +{
22281 +       struct vcmd_vx_info_v0 vc_data;
22282 +
22283 +       vc_data.xid = vxi->vx_id;
22284 +       vc_data.initpid = vxi->vx_initpid;
22285 +
22286 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22287 +               return -EFAULT;
22288 +       return 0;
22289 +}
22290 +
22291 +
22292 +/* context functions */
22293 +
22294 +int vc_ctx_create(uint32_t xid, void __user *data)
22295 +{
22296 +       struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
22297 +       struct vx_info *new_vxi;
22298 +       int ret;
22299 +
22300 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
22301 +               return -EFAULT;
22302 +
22303 +       if ((xid > MAX_S_CONTEXT) && (xid != VX_DYNAMIC_ID))
22304 +               return -EINVAL;
22305 +       if (xid < 2)
22306 +               return -EINVAL;
22307 +
22308 +       new_vxi = __create_vx_info(xid);
22309 +       if (IS_ERR(new_vxi))
22310 +               return PTR_ERR(new_vxi);
22311 +
22312 +       /* initial flags */
22313 +       new_vxi->vx_flags = vc_data.flagword;
22314 +
22315 +       /* get a reference for persistent contexts */
22316 +       if ((vc_data.flagword & VXF_PERSISTENT))
22317 +               vx_set_persistent(new_vxi);
22318 +
22319 +       ret = -ENOEXEC;
22320 +       if (vs_state_change(new_vxi, VSC_STARTUP))
22321 +               goto out_unhash;
22322 +       ret = vx_migrate_task(current, new_vxi);
22323 +       if (!ret) {
22324 +               /* return context id on success */
22325 +               ret = new_vxi->vx_id;
22326 +               goto out;
22327 +       }
22328 +out_unhash:
22329 +       /* prepare for context disposal */
22330 +       new_vxi->vx_state |= VXS_SHUTDOWN;
22331 +       if ((vc_data.flagword & VXF_PERSISTENT))
22332 +               vx_clear_persistent(new_vxi);
22333 +       __unhash_vx_info(new_vxi);
22334 +out:
22335 +       put_vx_info(new_vxi);
22336 +       return ret;
22337 +}
22338 +
22339 +
22340 +int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
22341 +{
22342 +       struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
22343 +       int ret;
22344 +
22345 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
22346 +               return -EFAULT;
22347 +
22348 +       ret = vx_migrate_task(current, vxi);
22349 +       if (ret)
22350 +               return ret;
22351 +       if (vc_data.flagword & VXM_SET_INIT)
22352 +               ret = vx_set_init(vxi, current);
22353 +       if (ret)
22354 +               return ret;
22355 +       if (vc_data.flagword & VXM_SET_REAPER)
22356 +               ret = vx_set_reaper(vxi, current);
22357 +       return ret;
22358 +}
22359 +
22360 +
22361 +int vc_get_cflags(struct vx_info *vxi, void __user *data)
22362 +{
22363 +       struct vcmd_ctx_flags_v0 vc_data;
22364 +
22365 +       vc_data.flagword = vxi->vx_flags;
22366 +
22367 +       /* special STATE flag handling */
22368 +       vc_data.mask = vx_mask_flags(~0UL, vxi->vx_flags, VXF_ONE_TIME);
22369 +
22370 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22371 +               return -EFAULT;
22372 +       return 0;
22373 +}
22374 +
22375 +int vc_set_cflags(struct vx_info *vxi, void __user *data)
22376 +{
22377 +       struct vcmd_ctx_flags_v0 vc_data;
22378 +       uint64_t mask, trigger;
22379 +
22380 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22381 +               return -EFAULT;
22382 +
22383 +       /* special STATE flag handling */
22384 +       mask = vx_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
22385 +       trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
22386 +
22387 +       if (vxi == current->vx_info) {
22388 +               if (trigger & VXF_STATE_SETUP)
22389 +                       vx_mask_cap_bset(vxi, current);
22390 +               if (trigger & VXF_STATE_INIT) {
22391 +                       int ret;
22392 +
22393 +                       ret = vx_set_init(vxi, current);
22394 +                       if (ret)
22395 +                               return ret;
22396 +                       ret = vx_set_reaper(vxi, current);
22397 +                       if (ret)
22398 +                               return ret;
22399 +               }
22400 +       }
22401 +
22402 +       vxi->vx_flags = vx_mask_flags(vxi->vx_flags,
22403 +               vc_data.flagword, mask);
22404 +       if (trigger & VXF_PERSISTENT)
22405 +               vx_update_persistent(vxi);
22406 +
22407 +       return 0;
22408 +}
22409 +
22410 +static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
22411 +{
22412 +       if (bcaps)
22413 +               *bcaps = vxi->vx_bcaps;
22414 +       if (ccaps)
22415 +               *ccaps = vxi->vx_ccaps;
22416 +
22417 +       return 0;
22418 +}
22419 +
22420 +int vc_get_ccaps_v0(struct vx_info *vxi, void __user *data)
22421 +{
22422 +       struct vcmd_ctx_caps_v0 vc_data;
22423 +       int ret;
22424 +
22425 +       ret = do_get_caps(vxi, &vc_data.bcaps, &vc_data.ccaps);
22426 +       if (ret)
22427 +               return ret;
22428 +       vc_data.cmask = ~0UL;
22429 +
22430 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22431 +               return -EFAULT;
22432 +       return 0;
22433 +}
22434 +
22435 +int vc_get_ccaps(struct vx_info *vxi, void __user *data)
22436 +{
22437 +       struct vcmd_ctx_caps_v1 vc_data;
22438 +       int ret;
22439 +
22440 +       ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
22441 +       if (ret)
22442 +               return ret;
22443 +       vc_data.cmask = ~0UL;
22444 +
22445 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22446 +               return -EFAULT;
22447 +       return 0;
22448 +}
22449 +
22450 +static int do_set_caps(struct vx_info *vxi,
22451 +       uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
22452 +{
22453 +       vxi->vx_bcaps = vx_mask_flags(vxi->vx_bcaps, bcaps, bmask);
22454 +       vxi->vx_ccaps = vx_mask_flags(vxi->vx_ccaps, ccaps, cmask);
22455 +
22456 +       return 0;
22457 +}
22458 +
22459 +int vc_set_ccaps_v0(struct vx_info *vxi, void __user *data)
22460 +{
22461 +       struct vcmd_ctx_caps_v0 vc_data;
22462 +
22463 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22464 +               return -EFAULT;
22465 +
22466 +       /* simulate old &= behaviour for bcaps */
22467 +       return do_set_caps(vxi, 0, ~vc_data.bcaps,
22468 +               vc_data.ccaps, vc_data.cmask);
22469 +}
22470 +
22471 +int vc_set_ccaps(struct vx_info *vxi, void __user *data)
22472 +{
22473 +       struct vcmd_ctx_caps_v1 vc_data;
22474 +
22475 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22476 +               return -EFAULT;
22477 +
22478 +       return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
22479 +}
22480 +
22481 +int vc_get_bcaps(struct vx_info *vxi, void __user *data)
22482 +{
22483 +       struct vcmd_bcaps vc_data;
22484 +       int ret;
22485 +
22486 +       ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
22487 +       if (ret)
22488 +               return ret;
22489 +       vc_data.bmask = ~0UL;
22490 +
22491 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22492 +               return -EFAULT;
22493 +       return 0;
22494 +}
22495 +
22496 +int vc_set_bcaps(struct vx_info *vxi, void __user *data)
22497 +{
22498 +       struct vcmd_bcaps vc_data;
22499 +
22500 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22501 +               return -EFAULT;
22502 +
22503 +       return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
22504 +}
22505 +
22506 +#include <linux/module.h>
22507 +
22508 +EXPORT_SYMBOL_GPL(free_vx_info);
22509 +
22510 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/cvirt.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cvirt.c
22511 --- linux-2.6.17.11/kernel/vserver/cvirt.c      1970-01-01 01:00:00 +0100
22512 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cvirt.c 2006-08-19 03:50:09 +0200
22513 @@ -0,0 +1,289 @@
22514 +/*
22515 + *  linux/kernel/vserver/cvirt.c
22516 + *
22517 + *  Virtual Server: Context Virtualization
22518 + *
22519 + *  Copyright (C) 2004-2006  Herbert Pötzl
22520 + *
22521 + *  V0.01  broken out from limit.c
22522 + *  V0.02  added utsname stuff
22523 + *  V0.03  changed vcmds to vxi arg
22524 + *
22525 + */
22526 +
22527 +#include <linux/sched.h>
22528 +#include <linux/sysctl.h>
22529 +#include <linux/types.h>
22530 +#include <linux/vs_context.h>
22531 +#include <linux/vs_cvirt.h>
22532 +#include <linux/vserver/switch.h>
22533 +#include <linux/vserver/cvirt_cmd.h>
22534 +//#include <linux/vserver/cacct_cmd.h>
22535 +
22536 +#include <asm/errno.h>
22537 +#include <asm/uaccess.h>
22538 +
22539 +
22540 +void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
22541 +{
22542 +       struct vx_info *vxi = current->vx_info;
22543 +
22544 +       set_normalized_timespec(uptime,
22545 +               uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
22546 +               uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
22547 +       if (!idle)
22548 +               return;
22549 +       set_normalized_timespec(idle,
22550 +               idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
22551 +               idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
22552 +       return;
22553 +}
22554 +
22555 +uint64_t vx_idle_jiffies(void)
22556 +{
22557 +       return init_task.utime + init_task.stime;
22558 +}
22559 +
22560 +
22561 +
22562 +static inline uint32_t __update_loadavg(uint32_t load,
22563 +       int wsize, int delta, int n)
22564 +{
22565 +       unsigned long long calc, prev;
22566 +
22567 +       /* just set it to n */
22568 +       if (unlikely(delta >= wsize))
22569 +               return (n << FSHIFT);
22570 +
22571 +       calc = delta * n;
22572 +       calc <<= FSHIFT;
22573 +       prev = (wsize - delta);
22574 +       prev *= load;
22575 +       calc += prev;
22576 +       do_div(calc, wsize);
22577 +       return calc;
22578 +}
22579 +
22580 +
22581 +void vx_update_load(struct vx_info *vxi)
22582 +{
22583 +       uint32_t now, last, delta;
22584 +       unsigned int nr_running, nr_uninterruptible;
22585 +       unsigned int total;
22586 +       unsigned long flags;
22587 +
22588 +       spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
22589 +
22590 +       now = jiffies;
22591 +       last = vxi->cvirt.load_last;
22592 +       delta = now - last;
22593 +
22594 +       if (delta < 5*HZ)
22595 +               goto out;
22596 +
22597 +       nr_running = atomic_read(&vxi->cvirt.nr_running);
22598 +       nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
22599 +       total = nr_running + nr_uninterruptible;
22600 +
22601 +       vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
22602 +               60*HZ, delta, total);
22603 +       vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
22604 +               5*60*HZ, delta, total);
22605 +       vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
22606 +               15*60*HZ, delta, total);
22607 +
22608 +       vxi->cvirt.load_last = now;
22609 +out:
22610 +       atomic_inc(&vxi->cvirt.load_updates);
22611 +       spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
22612 +}
22613 +
22614 +
22615 +int vx_uts_virt_handler(struct ctl_table *ctl, int write, xid_t xid,
22616 +       void **datap, size_t *lenp)
22617 +{
22618 +       switch (ctl->ctl_name) {
22619 +       case KERN_OSTYPE:
22620 +               *datap = vx_new_uts(sysname);
22621 +               break;
22622 +       case KERN_OSRELEASE:
22623 +               *datap = vx_new_uts(release);
22624 +               break;
22625 +       case KERN_VERSION:
22626 +               *datap = vx_new_uts(version);
22627 +               break;
22628 +       case KERN_NODENAME:
22629 +               *datap = vx_new_uts(nodename);
22630 +               break;
22631 +       case KERN_DOMAINNAME:
22632 +               *datap = vx_new_uts(domainname);
22633 +               break;
22634 +       }
22635 +
22636 +       return 0;
22637 +}
22638 +
22639 +
22640 +
22641 +/*
22642 + * Commands to do_syslog:
22643 + *
22644 + *      0 -- Close the log.  Currently a NOP.
22645 + *      1 -- Open the log. Currently a NOP.
22646 + *      2 -- Read from the log.
22647 + *      3 -- Read all messages remaining in the ring buffer.
22648 + *      4 -- Read and clear all messages remaining in the ring buffer
22649 + *      5 -- Clear ring buffer.
22650 + *      6 -- Disable printk's to console
22651 + *      7 -- Enable printk's to console
22652 + *      8 -- Set level of messages printed to console
22653 + *      9 -- Return number of unread characters in the log buffer
22654 + *     10 -- Return size of the log buffer
22655 + */
22656 +int vx_do_syslog(int type, char __user *buf, int len)
22657 +{
22658 +       int error = 0;
22659 +       int do_clear = 0;
22660 +       struct vx_info *vxi = current->vx_info;
22661 +       struct _vx_syslog *log;
22662 +
22663 +       if (!vxi)
22664 +               return -EINVAL;
22665 +       log = &vxi->cvirt.syslog;
22666 +
22667 +       switch (type) {
22668 +       case 0:         /* Close log */
22669 +       case 1:         /* Open log */
22670 +               break;
22671 +       case 2:         /* Read from log */
22672 +               error = wait_event_interruptible(log->log_wait,
22673 +                       (log->log_start - log->log_end));
22674 +               if (error)
22675 +                       break;
22676 +               spin_lock_irq(&log->logbuf_lock);
22677 +               spin_unlock_irq(&log->logbuf_lock);
22678 +               break;
22679 +       case 4:         /* Read/clear last kernel messages */
22680 +               do_clear = 1;
22681 +               /* fall through */
22682 +       case 3:         /* Read last kernel messages */
22683 +               return 0;
22684 +
22685 +       case 5:         /* Clear ring buffer */
22686 +               return 0;
22687 +
22688 +       case 6:         /* Disable logging to console */
22689 +       case 7:         /* Enable logging to console */
22690 +       case 8:         /* Set level of messages printed to console */
22691 +               break;
22692 +
22693 +       case 9:         /* Number of chars in the log buffer */
22694 +               return 0;
22695 +       case 10:        /* Size of the log buffer */
22696 +               return 0;
22697 +       default:
22698 +               error = -EINVAL;
22699 +               break;
22700 +       }
22701 +       return error;
22702 +}
22703 +
22704 +
22705 +/* virtual host info names */
22706 +
22707 +static char * vx_vhi_name(struct vx_info *vxi, int id)
22708 +{
22709 +       switch (id) {
22710 +       case VHIN_CONTEXT:
22711 +               return vxi->vx_name;
22712 +       case VHIN_SYSNAME:
22713 +               return vxi->cvirt.utsname.sysname;
22714 +       case VHIN_NODENAME:
22715 +               return vxi->cvirt.utsname.nodename;
22716 +       case VHIN_RELEASE:
22717 +               return vxi->cvirt.utsname.release;
22718 +       case VHIN_VERSION:
22719 +               return vxi->cvirt.utsname.version;
22720 +       case VHIN_MACHINE:
22721 +               return vxi->cvirt.utsname.machine;
22722 +       case VHIN_DOMAINNAME:
22723 +               return vxi->cvirt.utsname.domainname;
22724 +       default:
22725 +               return NULL;
22726 +       }
22727 +       return NULL;
22728 +}
22729 +
22730 +int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
22731 +{
22732 +       struct vcmd_vhi_name_v0 vc_data;
22733 +       char *name;
22734 +
22735 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22736 +               return -EFAULT;
22737 +
22738 +       name = vx_vhi_name(vxi, vc_data.field);
22739 +       if (!name)
22740 +               return -EINVAL;
22741 +
22742 +       memcpy(name, vc_data.name, 65);
22743 +       return 0;
22744 +}
22745 +
22746 +int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
22747 +{
22748 +       struct vcmd_vhi_name_v0 vc_data;
22749 +       char *name;
22750 +
22751 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22752 +               return -EFAULT;
22753 +
22754 +       name = vx_vhi_name(vxi, vc_data.field);
22755 +       if (!name)
22756 +               return -EINVAL;
22757 +
22758 +       memcpy(vc_data.name, name, 65);
22759 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22760 +               return -EFAULT;
22761 +       return 0;
22762 +}
22763 +
22764 +#ifdef CONFIG_VSERVER_VTIME
22765 +
22766 +/* virtualized time base */
22767 +
22768 +void vx_gettimeofday(struct timeval *tv)
22769 +{
22770 +       do_gettimeofday(tv);
22771 +       if (!vx_flags(VXF_VIRT_TIME, 0))
22772 +               return;
22773 +
22774 +       tv->tv_sec += current->vx_info->cvirt.bias_tv.tv_sec;
22775 +       tv->tv_usec += current->vx_info->cvirt.bias_tv.tv_usec;
22776 +
22777 +       if (tv->tv_usec >= USEC_PER_SEC) {
22778 +               tv->tv_sec++;
22779 +               tv->tv_usec -= USEC_PER_SEC;
22780 +       } else if (tv->tv_usec < 0) {
22781 +               tv->tv_sec--;
22782 +               tv->tv_usec += USEC_PER_SEC;
22783 +       }
22784 +}
22785 +
22786 +int vx_settimeofday(struct timespec *ts)
22787 +{
22788 +       struct timeval tv;
22789 +
22790 +       if (!vx_flags(VXF_VIRT_TIME, 0))
22791 +               return do_settimeofday(ts);
22792 +
22793 +       do_gettimeofday(&tv);
22794 +       current->vx_info->cvirt.bias_tv.tv_sec =
22795 +               ts->tv_sec - tv.tv_sec;
22796 +       current->vx_info->cvirt.bias_tv.tv_usec =
22797 +               (ts->tv_nsec/NSEC_PER_USEC) - tv.tv_usec;
22798 +       return 0;
22799 +}
22800 +
22801 +#endif
22802 +
22803 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/cvirt_init.h linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cvirt_init.h
22804 --- linux-2.6.17.11/kernel/vserver/cvirt_init.h 1970-01-01 01:00:00 +0100
22805 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cvirt_init.h    2006-07-30 16:52:39 +0200
22806 @@ -0,0 +1,75 @@
22807 +
22808 +
22809 +extern uint64_t vx_idle_jiffies(void);
22810 +
22811 +static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
22812 +{
22813 +       uint64_t idle_jiffies = vx_idle_jiffies();
22814 +       uint64_t nsuptime;
22815 +
22816 +       do_posix_clock_monotonic_gettime(&cvirt->bias_uptime);
22817 +       nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
22818 +               * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
22819 +       cvirt->bias_clock = nsec_to_clock_t(nsuptime);
22820 +       cvirt->bias_tv.tv_sec = 0;
22821 +       cvirt->bias_tv.tv_usec = 0;
22822 +
22823 +       jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle);
22824 +       atomic_set(&cvirt->nr_threads, 0);
22825 +       atomic_set(&cvirt->nr_running, 0);
22826 +       atomic_set(&cvirt->nr_uninterruptible, 0);
22827 +       atomic_set(&cvirt->nr_onhold, 0);
22828 +
22829 +       down_read(&uts_sem);
22830 +       cvirt->utsname = system_utsname;
22831 +       up_read(&uts_sem);
22832 +
22833 +       spin_lock_init(&cvirt->load_lock);
22834 +       cvirt->load_last = jiffies;
22835 +       atomic_set(&cvirt->load_updates, 0);
22836 +       cvirt->load[0] = 0;
22837 +       cvirt->load[1] = 0;
22838 +       cvirt->load[2] = 0;
22839 +       atomic_set(&cvirt->total_forks, 0);
22840 +
22841 +       spin_lock_init(&cvirt->syslog.logbuf_lock);
22842 +       init_waitqueue_head(&cvirt->syslog.log_wait);
22843 +       cvirt->syslog.log_start = 0;
22844 +       cvirt->syslog.log_end = 0;
22845 +       cvirt->syslog.con_start = 0;
22846 +       cvirt->syslog.logged_chars = 0;
22847 +}
22848 +
22849 +static inline
22850 +void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
22851 +{
22852 +       // cvirt_pc->cpustat = { 0 };
22853 +}
22854 +
22855 +static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
22856 +{
22857 +#ifdef CONFIG_VSERVER_DEBUG
22858 +       int value;
22859 +
22860 +       vxwprintk((value = atomic_read(&cvirt->nr_threads)),
22861 +               "!!! cvirt: %p[nr_threads] = %d on exit.",
22862 +               cvirt, value);
22863 +       vxwprintk((value = atomic_read(&cvirt->nr_running)),
22864 +               "!!! cvirt: %p[nr_running] = %d on exit.",
22865 +               cvirt, value);
22866 +       vxwprintk((value = atomic_read(&cvirt->nr_uninterruptible)),
22867 +               "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
22868 +               cvirt, value);
22869 +       vxwprintk((value = atomic_read(&cvirt->nr_onhold)),
22870 +               "!!! cvirt: %p[nr_onhold] = %d on exit.",
22871 +               cvirt, value);
22872 +#endif
22873 +       return;
22874 +}
22875 +
22876 +static inline
22877 +void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
22878 +{
22879 +       return;
22880 +}
22881 +
22882 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/cvirt_proc.h linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cvirt_proc.h
22883 --- linux-2.6.17.11/kernel/vserver/cvirt_proc.h 1970-01-01 01:00:00 +0100
22884 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/cvirt_proc.h    2006-07-30 17:01:29 +0200
22885 @@ -0,0 +1,67 @@
22886 +#ifndef _VX_CVIRT_PROC_H
22887 +#define _VX_CVIRT_PROC_H
22888 +
22889 +#include <linux/sched.h>
22890 +
22891 +
22892 +#define LOAD_INT(x) ((x) >> FSHIFT)
22893 +#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
22894 +
22895 +static inline
22896 +int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
22897 +{
22898 +       int length = 0;
22899 +       int a, b, c;
22900 +
22901 +       length += sprintf(buffer + length,
22902 +               "BiasUptime:\t%lu.%02lu\n",
22903 +                       (unsigned long)cvirt->bias_uptime.tv_sec,
22904 +                       (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
22905 +       length += sprintf(buffer + length,
22906 +               "SysName:\t%.*s\n"
22907 +               "NodeName:\t%.*s\n"
22908 +               "Release:\t%.*s\n"
22909 +               "Version:\t%.*s\n"
22910 +               "Machine:\t%.*s\n"
22911 +               "DomainName:\t%.*s\n"
22912 +               ,__NEW_UTS_LEN, cvirt->utsname.sysname
22913 +               ,__NEW_UTS_LEN, cvirt->utsname.nodename
22914 +               ,__NEW_UTS_LEN, cvirt->utsname.release
22915 +               ,__NEW_UTS_LEN, cvirt->utsname.version
22916 +               ,__NEW_UTS_LEN, cvirt->utsname.machine
22917 +               ,__NEW_UTS_LEN, cvirt->utsname.domainname
22918 +               );
22919 +
22920 +       a = cvirt->load[0] + (FIXED_1/200);
22921 +       b = cvirt->load[1] + (FIXED_1/200);
22922 +       c = cvirt->load[2] + (FIXED_1/200);
22923 +       length += sprintf(buffer + length,
22924 +               "nr_threads:\t%d\n"
22925 +               "nr_running:\t%d\n"
22926 +               "nr_unintr:\t%d\n"
22927 +               "nr_onhold:\t%d\n"
22928 +               "load_updates:\t%d\n"
22929 +               "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
22930 +               "total_forks:\t%d\n"
22931 +               ,atomic_read(&cvirt->nr_threads)
22932 +               ,atomic_read(&cvirt->nr_running)
22933 +               ,atomic_read(&cvirt->nr_uninterruptible)
22934 +               ,atomic_read(&cvirt->nr_onhold)
22935 +               ,atomic_read(&cvirt->load_updates)
22936 +               ,LOAD_INT(a), LOAD_FRAC(a)
22937 +               ,LOAD_INT(b), LOAD_FRAC(b)
22938 +               ,LOAD_INT(c), LOAD_FRAC(c)
22939 +               ,atomic_read(&cvirt->total_forks)
22940 +               );
22941 +       return length;
22942 +}
22943 +
22944 +static inline
22945 +int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
22946 +       char *buffer, int cpu)
22947 +{
22948 +       int length = 0;
22949 +       return length;
22950 +}
22951 +
22952 +#endif /* _VX_CVIRT_PROC_H */
22953 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/debug.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/debug.c
22954 --- linux-2.6.17.11/kernel/vserver/debug.c      1970-01-01 01:00:00 +0100
22955 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/debug.c 2006-07-30 16:50:27 +0200
22956 @@ -0,0 +1,37 @@
22957 +/*
22958 + *  kernel/vserver/debug.c
22959 + *
22960 + *  Copyright (C) 2005  Herbert Pötzl
22961 + *
22962 + *  V0.01  vx_info dump support
22963 + *
22964 + */
22965 +
22966 +#include <linux/errno.h>
22967 +#include <linux/kernel.h>
22968 +#include <linux/module.h>
22969 +
22970 +#include <linux/vserver/cvirt_def.h>
22971 +#include <linux/vserver/cacct_def.h>
22972 +#include <linux/vserver/limit_def.h>
22973 +#include <linux/vserver/sched_def.h>
22974 +
22975 +
22976 +void   dump_vx_info(struct vx_info *vxi, int level)
22977 +{
22978 +       printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
22979 +               atomic_read(&vxi->vx_usecnt),
22980 +               atomic_read(&vxi->vx_tasks),
22981 +               vxi->vx_state);
22982 +       if (level > 0) {
22983 +               __dump_vx_limit(&vxi->limit);
22984 +               __dump_vx_sched(&vxi->sched);
22985 +               __dump_vx_cvirt(&vxi->cvirt);
22986 +               __dump_vx_cacct(&vxi->cacct);
22987 +       }
22988 +       printk("---\n");
22989 +}
22990 +
22991 +
22992 +EXPORT_SYMBOL_GPL(dump_vx_info);
22993 +
22994 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/dlimit.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/dlimit.c
22995 --- linux-2.6.17.11/kernel/vserver/dlimit.c     1970-01-01 01:00:00 +0100
22996 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/dlimit.c        2006-08-17 01:24:16 +0200
22997 @@ -0,0 +1,527 @@
22998 +/*
22999 + *  linux/kernel/vserver/dlimit.c
23000 + *
23001 + *  Virtual Server: Context Disk Limits
23002 + *
23003 + *  Copyright (C) 2004-2005  Herbert Pötzl
23004 + *
23005 + *  V0.01  initial version
23006 + *  V0.02  compat32 splitup
23007 + *
23008 + */
23009 +
23010 +#include <linux/fs.h>
23011 +#include <linux/namespace.h>
23012 +#include <linux/namei.h>
23013 +#include <linux/statfs.h>
23014 +#include <linux/compat.h>
23015 +#include <linux/vserver/switch.h>
23016 +#include <linux/vs_context.h>
23017 +#include <linux/vs_tag.h>
23018 +#include <linux/vs_dlimit.h>
23019 +#include <linux/vserver/dlimit_cmd.h>
23020 +
23021 +#include <asm/errno.h>
23022 +#include <asm/uaccess.h>
23023 +
23024 +/*     __alloc_dl_info()
23025 +
23026 +       * allocate an initialized dl_info struct
23027 +       * doesn't make it visible (hash)                        */
23028 +
23029 +static struct dl_info *__alloc_dl_info(struct super_block *sb, tag_t tag)
23030 +{
23031 +       struct dl_info *new = NULL;
23032 +
23033 +       vxdprintk(VXD_CBIT(dlim, 5),
23034 +               "alloc_dl_info(%p,%d)*", sb, tag);
23035 +
23036 +       /* would this benefit from a slab cache? */
23037 +       new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
23038 +       if (!new)
23039 +               return 0;
23040 +
23041 +       memset (new, 0, sizeof(struct dl_info));
23042 +       new->dl_tag = tag;
23043 +       new->dl_sb = sb;
23044 +       INIT_RCU_HEAD(&new->dl_rcu);
23045 +       INIT_HLIST_NODE(&new->dl_hlist);
23046 +       spin_lock_init(&new->dl_lock);
23047 +       atomic_set(&new->dl_refcnt, 0);
23048 +       atomic_set(&new->dl_usecnt, 0);
23049 +
23050 +       /* rest of init goes here */
23051 +
23052 +       vxdprintk(VXD_CBIT(dlim, 4),
23053 +               "alloc_dl_info(%p,%d) = %p", sb, tag, new);
23054 +       return new;
23055 +}
23056 +
23057 +/*     __dealloc_dl_info()
23058 +
23059 +       * final disposal of dl_info                             */
23060 +
23061 +static void __dealloc_dl_info(struct dl_info *dli)
23062 +{
23063 +       vxdprintk(VXD_CBIT(dlim, 4),
23064 +               "dealloc_dl_info(%p)", dli);
23065 +
23066 +       dli->dl_hlist.next = LIST_POISON1;
23067 +       dli->dl_tag = -1;
23068 +       dli->dl_sb = 0;
23069 +
23070 +       BUG_ON(atomic_read(&dli->dl_usecnt));
23071 +       BUG_ON(atomic_read(&dli->dl_refcnt));
23072 +
23073 +       kfree(dli);
23074 +}
23075 +
23076 +
23077 +/*     hash table for dl_info hash */
23078 +
23079 +#define DL_HASH_SIZE   13
23080 +
23081 +struct hlist_head dl_info_hash[DL_HASH_SIZE];
23082 +
23083 +static spinlock_t dl_info_hash_lock = SPIN_LOCK_UNLOCKED;
23084 +
23085 +
23086 +static inline unsigned int __hashval(struct super_block *sb, tag_t tag)
23087 +{
23088 +       return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
23089 +}
23090 +
23091 +
23092 +
23093 +/*     __hash_dl_info()
23094 +
23095 +       * add the dli to the global hash table
23096 +       * requires the hash_lock to be held                     */
23097 +
23098 +static inline void __hash_dl_info(struct dl_info *dli)
23099 +{
23100 +       struct hlist_head *head;
23101 +
23102 +       vxdprintk(VXD_CBIT(dlim, 6),
23103 +               "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
23104 +       get_dl_info(dli);
23105 +       head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
23106 +       hlist_add_head_rcu(&dli->dl_hlist, head);
23107 +}
23108 +
23109 +/*     __unhash_dl_info()
23110 +
23111 +       * remove the dli from the global hash table
23112 +       * requires the hash_lock to be held                     */
23113 +
23114 +static inline void __unhash_dl_info(struct dl_info *dli)
23115 +{
23116 +       vxdprintk(VXD_CBIT(dlim, 6),
23117 +               "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
23118 +       hlist_del_rcu(&dli->dl_hlist);
23119 +       put_dl_info(dli);
23120 +}
23121 +
23122 +
23123 +/*     __lookup_dl_info()
23124 +
23125 +       * requires the rcu_read_lock()
23126 +       * doesn't increment the dl_refcnt                       */
23127 +
23128 +static inline struct dl_info *__lookup_dl_info(struct super_block *sb, tag_t tag)
23129 +{
23130 +       struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
23131 +       struct hlist_node *pos;
23132 +       struct dl_info *dli;
23133 +
23134 +       hlist_for_each_entry_rcu(dli, pos, head, dl_hlist) {
23135 +
23136 +               if (dli->dl_tag == tag && dli->dl_sb == sb) {
23137 +                       return dli;
23138 +               }
23139 +       }
23140 +       return NULL;
23141 +}
23142 +
23143 +
23144 +struct dl_info *locate_dl_info(struct super_block *sb, tag_t tag)
23145 +{
23146 +       struct dl_info *dli;
23147 +
23148 +       rcu_read_lock();
23149 +       dli = get_dl_info(__lookup_dl_info(sb, tag));
23150 +       vxdprintk(VXD_CBIT(dlim, 7),
23151 +               "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
23152 +       rcu_read_unlock();
23153 +       return dli;
23154 +}
23155 +
23156 +void rcu_free_dl_info(struct rcu_head *head)
23157 +{
23158 +       struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
23159 +       int usecnt, refcnt;
23160 +
23161 +       BUG_ON(!dli || !head);
23162 +
23163 +       usecnt = atomic_read(&dli->dl_usecnt);
23164 +       BUG_ON(usecnt < 0);
23165 +
23166 +       refcnt = atomic_read(&dli->dl_refcnt);
23167 +       BUG_ON(refcnt < 0);
23168 +
23169 +       vxdprintk(VXD_CBIT(dlim, 3),
23170 +               "rcu_free_dl_info(%p)", dli);
23171 +       if (!usecnt)
23172 +               __dealloc_dl_info(dli);
23173 +       else
23174 +               printk("!!! rcu didn't free\n");
23175 +}
23176 +
23177 +
23178 +
23179 +
23180 +static int do_addrem_dlimit(uint32_t id, const char __user *name,
23181 +       uint32_t flags, int add)
23182 +{
23183 +       struct nameidata nd;
23184 +       int ret;
23185 +
23186 +       ret = user_path_walk_link(name, &nd);
23187 +       if (!ret) {
23188 +               struct super_block *sb;
23189 +               struct dl_info *dli;
23190 +
23191 +               ret = -EINVAL;
23192 +               if (!nd.dentry->d_inode)
23193 +                       goto out_release;
23194 +               if (!(sb = nd.dentry->d_inode->i_sb))
23195 +                       goto out_release;
23196 +
23197 +               if (add) {
23198 +                       dli = __alloc_dl_info(sb, id);
23199 +                       spin_lock(&dl_info_hash_lock);
23200 +
23201 +                       ret = -EEXIST;
23202 +                       if (__lookup_dl_info(sb, id))
23203 +                               goto out_unlock;
23204 +                       __hash_dl_info(dli);
23205 +                       dli = NULL;
23206 +               } else {
23207 +                       spin_lock(&dl_info_hash_lock);
23208 +                       dli = __lookup_dl_info(sb, id);
23209 +
23210 +                       ret = -ESRCH;
23211 +                       if (!dli)
23212 +                               goto out_unlock;
23213 +                       __unhash_dl_info(dli);
23214 +               }
23215 +               ret = 0;
23216 +       out_unlock:
23217 +               spin_unlock(&dl_info_hash_lock);
23218 +               if (add && dli)
23219 +                       __dealloc_dl_info(dli);
23220 +       out_release:
23221 +               path_release(&nd);
23222 +       }
23223 +       return ret;
23224 +}
23225 +
23226 +int vc_add_dlimit(uint32_t id, void __user *data)
23227 +{
23228 +       struct vcmd_ctx_dlimit_base_v0 vc_data;
23229 +
23230 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23231 +               return -EFAULT;
23232 +
23233 +       return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
23234 +}
23235 +
23236 +int vc_rem_dlimit(uint32_t id, void __user *data)
23237 +{
23238 +       struct vcmd_ctx_dlimit_base_v0 vc_data;
23239 +
23240 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23241 +               return -EFAULT;
23242 +
23243 +       return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
23244 +}
23245 +
23246 +#ifdef CONFIG_COMPAT
23247 +
23248 +int vc_add_dlimit_x32(uint32_t id, void __user *data)
23249 +{
23250 +       struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
23251 +
23252 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23253 +               return -EFAULT;
23254 +
23255 +       return do_addrem_dlimit(id,
23256 +               compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
23257 +}
23258 +
23259 +int vc_rem_dlimit_x32(uint32_t id, void __user *data)
23260 +{
23261 +       struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
23262 +
23263 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23264 +               return -EFAULT;
23265 +
23266 +       return do_addrem_dlimit(id,
23267 +               compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
23268 +}
23269 +
23270 +#endif /* CONFIG_COMPAT */
23271 +
23272 +
23273 +static inline
23274 +int do_set_dlimit(uint32_t id, const char __user *name,
23275 +       uint32_t space_used, uint32_t space_total,
23276 +       uint32_t inodes_used, uint32_t inodes_total,
23277 +       uint32_t reserved, uint32_t flags)
23278 +{
23279 +       struct nameidata nd;
23280 +       int ret;
23281 +
23282 +       ret = user_path_walk_link(name, &nd);
23283 +       if (!ret) {
23284 +               struct super_block *sb;
23285 +               struct dl_info *dli;
23286 +
23287 +               ret = -EINVAL;
23288 +               if (!nd.dentry->d_inode)
23289 +                       goto out_release;
23290 +               if (!(sb = nd.dentry->d_inode->i_sb))
23291 +                       goto out_release;
23292 +               if ((reserved != CDLIM_KEEP &&
23293 +                       reserved > 100) ||
23294 +                       (inodes_used != CDLIM_KEEP &&
23295 +                       inodes_used > inodes_total) ||
23296 +                       (space_used != CDLIM_KEEP &&
23297 +                       space_used > space_total))
23298 +                       goto out_release;
23299 +
23300 +               ret = -ESRCH;
23301 +               dli = locate_dl_info(sb, id);
23302 +               if (!dli)
23303 +                       goto out_release;
23304 +
23305 +               spin_lock(&dli->dl_lock);
23306 +
23307 +               if (inodes_used != CDLIM_KEEP)
23308 +                       dli->dl_inodes_used = inodes_used;
23309 +               if (inodes_total != CDLIM_KEEP)
23310 +                       dli->dl_inodes_total = inodes_total;
23311 +               if (space_used != CDLIM_KEEP) {
23312 +                       dli->dl_space_used = space_used;
23313 +                       dli->dl_space_used <<= 10;
23314 +               }
23315 +               if (space_total == CDLIM_INFINITY)
23316 +                       dli->dl_space_total = DLIM_INFINITY;
23317 +               else if (space_total != CDLIM_KEEP) {
23318 +                       dli->dl_space_total = space_total;
23319 +                       dli->dl_space_total <<= 10;
23320 +               }
23321 +               if (reserved != CDLIM_KEEP)
23322 +                       dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
23323 +
23324 +               spin_unlock(&dli->dl_lock);
23325 +
23326 +               put_dl_info(dli);
23327 +               ret = 0;
23328 +
23329 +       out_release:
23330 +               path_release(&nd);
23331 +       }
23332 +       return ret;
23333 +}
23334 +
23335 +int vc_set_dlimit(uint32_t id, void __user *data)
23336 +{
23337 +       struct vcmd_ctx_dlimit_v0 vc_data;
23338 +
23339 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23340 +               return -EFAULT;
23341 +
23342 +       return do_set_dlimit(id, vc_data.name,
23343 +               vc_data.space_used, vc_data.space_total,
23344 +               vc_data.inodes_used, vc_data.inodes_total,
23345 +               vc_data.reserved, vc_data.flags);
23346 +}
23347 +
23348 +#ifdef CONFIG_COMPAT
23349 +
23350 +int vc_set_dlimit_x32(uint32_t id, void __user *data)
23351 +{
23352 +       struct vcmd_ctx_dlimit_v0_x32 vc_data;
23353 +
23354 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23355 +               return -EFAULT;
23356 +
23357 +       return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
23358 +               vc_data.space_used, vc_data.space_total,
23359 +               vc_data.inodes_used, vc_data.inodes_total,
23360 +               vc_data.reserved, vc_data.flags);
23361 +}
23362 +
23363 +#endif /* CONFIG_COMPAT */
23364 +
23365 +
23366 +static inline
23367 +int do_get_dlimit(uint32_t id, const char __user *name,
23368 +       uint32_t *space_used, uint32_t *space_total,
23369 +       uint32_t *inodes_used, uint32_t *inodes_total,
23370 +       uint32_t *reserved, uint32_t *flags)
23371 +{
23372 +       struct nameidata nd;
23373 +       int ret;
23374 +
23375 +       ret = user_path_walk_link(name, &nd);
23376 +       if (!ret) {
23377 +               struct super_block *sb;
23378 +               struct dl_info *dli;
23379 +
23380 +               ret = -EINVAL;
23381 +               if (!nd.dentry->d_inode)
23382 +                       goto out_release;
23383 +               if (!(sb = nd.dentry->d_inode->i_sb))
23384 +                       goto out_release;
23385 +
23386 +               ret = -ESRCH;
23387 +               dli = locate_dl_info(sb, id);
23388 +               if (!dli)
23389 +                       goto out_release;
23390 +
23391 +               spin_lock(&dli->dl_lock);
23392 +               *inodes_used = dli->dl_inodes_used;
23393 +               *inodes_total = dli->dl_inodes_total;
23394 +               *space_used = dli->dl_space_used >> 10;
23395 +               if (dli->dl_space_total == DLIM_INFINITY)
23396 +                       *space_total = CDLIM_INFINITY;
23397 +               else
23398 +                       *space_total = dli->dl_space_total >> 10;
23399 +
23400 +               *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
23401 +               spin_unlock(&dli->dl_lock);
23402 +
23403 +               put_dl_info(dli);
23404 +               ret = -EFAULT;
23405 +
23406 +               ret = 0;
23407 +       out_release:
23408 +               path_release(&nd);
23409 +       }
23410 +       return ret;
23411 +}
23412 +
23413 +
23414 +int vc_get_dlimit(uint32_t id, void __user *data)
23415 +{
23416 +       struct vcmd_ctx_dlimit_v0 vc_data;
23417 +       int ret;
23418 +
23419 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23420 +               return -EFAULT;
23421 +
23422 +       ret = do_get_dlimit(id, vc_data.name,
23423 +               &vc_data.space_used, &vc_data.space_total,
23424 +               &vc_data.inodes_used, &vc_data.inodes_total,
23425 +               &vc_data.reserved, &vc_data.flags);
23426 +       if (ret)
23427 +               return ret;
23428 +
23429 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
23430 +               return -EFAULT;
23431 +       return 0;
23432 +}
23433 +
23434 +#ifdef CONFIG_COMPAT
23435 +
23436 +int vc_get_dlimit_x32(uint32_t id, void __user *data)
23437 +{
23438 +       struct vcmd_ctx_dlimit_v0_x32 vc_data;
23439 +       int ret;
23440 +
23441 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23442 +               return -EFAULT;
23443 +
23444 +       ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
23445 +               &vc_data.space_used, &vc_data.space_total,
23446 +               &vc_data.inodes_used, &vc_data.inodes_total,
23447 +               &vc_data.reserved, &vc_data.flags);
23448 +       if (ret)
23449 +               return ret;
23450 +
23451 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
23452 +               return -EFAULT;
23453 +       return 0;
23454 +}
23455 +
23456 +#endif /* CONFIG_COMPAT */
23457 +
23458 +
23459 +void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
23460 +{
23461 +       struct dl_info *dli;
23462 +       __u64 blimit, bfree, bavail;
23463 +       __u32 ifree;
23464 +
23465 +       dli = locate_dl_info(sb, dx_current_tag());
23466 +       if (!dli)
23467 +               return;
23468 +
23469 +       spin_lock(&dli->dl_lock);
23470 +       if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
23471 +               goto no_ilim;
23472 +
23473 +       /* reduce max inodes available to limit */
23474 +       if (buf->f_files > dli->dl_inodes_total)
23475 +               buf->f_files = dli->dl_inodes_total;
23476 +
23477 +       ifree = dli->dl_inodes_total - dli->dl_inodes_used;
23478 +       /* reduce free inodes to min */
23479 +       if (ifree < buf->f_ffree)
23480 +               buf->f_ffree = ifree;
23481 +
23482 +no_ilim:
23483 +       if (dli->dl_space_total == DLIM_INFINITY)
23484 +               goto no_blim;
23485 +
23486 +       blimit = dli->dl_space_total >> sb->s_blocksize_bits;
23487 +
23488 +       if (dli->dl_space_total < dli->dl_space_used)
23489 +               bfree = 0;
23490 +       else
23491 +               bfree = (dli->dl_space_total - dli->dl_space_used)
23492 +                       >> sb->s_blocksize_bits;
23493 +
23494 +       bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
23495 +       if (bavail < dli->dl_space_used)
23496 +               bavail = 0;
23497 +       else
23498 +               bavail = (bavail - dli->dl_space_used)
23499 +                       >> sb->s_blocksize_bits;
23500 +
23501 +       /* reduce max space available to limit */
23502 +       if (buf->f_blocks > blimit)
23503 +               buf->f_blocks = blimit;
23504 +
23505 +       /* reduce free space to min */
23506 +       if (bfree < buf->f_bfree)
23507 +               buf->f_bfree = bfree;
23508 +
23509 +       /* reduce avail space to min */
23510 +       if (bavail < buf->f_bavail)
23511 +               buf->f_bavail = bavail;
23512 +
23513 +no_blim:
23514 +       spin_unlock(&dli->dl_lock);
23515 +       put_dl_info(dli);
23516 +
23517 +       return;
23518 +}
23519 +
23520 +#include <linux/module.h>
23521 +
23522 +EXPORT_SYMBOL_GPL(locate_dl_info);
23523 +EXPORT_SYMBOL_GPL(rcu_free_dl_info);
23524 +
23525 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/helper.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/helper.c
23526 --- linux-2.6.17.11/kernel/vserver/helper.c     1970-01-01 01:00:00 +0100
23527 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/helper.c        2006-08-17 21:19:38 +0200
23528 @@ -0,0 +1,208 @@
23529 +/*
23530 + *  linux/kernel/vserver/helper.c
23531 + *
23532 + *  Virtual Context Support
23533 + *
23534 + *  Copyright (C) 2004-2005  Herbert Pötzl
23535 + *
23536 + *  V0.01  basic helper
23537 + *
23538 + */
23539 +
23540 +#include <linux/errno.h>
23541 +#include <linux/kmod.h>
23542 +#include <linux/sched.h>
23543 +#include <linux/reboot.h>
23544 +#include <linux/vs_context.h>
23545 +#include <linux/vs_network.h>
23546 +#include <linux/vserver/signal.h>
23547 +
23548 +#include <asm/uaccess.h>
23549 +#include <asm/unistd.h>
23550 +
23551 +
23552 +char vshelper_path[255] = "/sbin/vshelper";
23553 +
23554 +
23555 +static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
23556 +{
23557 +       int ret;
23558 +
23559 +       if ((ret = call_usermodehelper(name, argv, envp, sync))) {
23560 +               printk( KERN_WARNING
23561 +                       "%s: (%s %s) returned %s with %d\n",
23562 +                       name, argv[1], argv[2],
23563 +                       sync?"sync":"async", ret);
23564 +       }
23565 +       vxdprintk(VXD_CBIT(switch, 4),
23566 +               "%s: (%s %s) returned %s with %d",
23567 +               name, argv[1], argv[2], sync?"sync":"async", ret);
23568 +       return ret;
23569 +}
23570 +
23571 +/*
23572 + *      vshelper path is set via /proc/sys
23573 + *      invoked by vserver sys_reboot(), with
23574 + *      the following arguments
23575 + *
23576 + *      argv [0] = vshelper_path;
23577 + *      argv [1] = action: "restart", "halt", "poweroff", ...
23578 + *      argv [2] = context identifier
23579 + *
23580 + *      envp [*] = type-specific parameters
23581 + */
23582 +
23583 +long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
23584 +{
23585 +       char id_buf[8], cmd_buf[16];
23586 +       char uid_buf[16], pid_buf[16];
23587 +       int ret;
23588 +
23589 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
23590 +       char *envp[] = {"HOME=/", "TERM=linux",
23591 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
23592 +                       uid_buf, pid_buf, cmd_buf, 0};
23593 +
23594 +       if (vx_info_state(vxi, VXS_HELPER))
23595 +               return -EAGAIN;
23596 +       vxi->vx_state |= VXS_HELPER;
23597 +
23598 +       snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
23599 +
23600 +       snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
23601 +       snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid);
23602 +       snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid);
23603 +
23604 +       switch (cmd) {
23605 +       case LINUX_REBOOT_CMD_RESTART:
23606 +               argv[1] = "restart";
23607 +               break;
23608 +
23609 +       case LINUX_REBOOT_CMD_HALT:
23610 +               argv[1] = "halt";
23611 +               break;
23612 +
23613 +       case LINUX_REBOOT_CMD_POWER_OFF:
23614 +               argv[1] = "poweroff";
23615 +               break;
23616 +
23617 +       case LINUX_REBOOT_CMD_SW_SUSPEND:
23618 +               argv[1] = "swsusp";
23619 +               break;
23620 +
23621 +       default:
23622 +               vxi->vx_state &= ~VXS_HELPER;
23623 +               return 0;
23624 +       }
23625 +
23626 +#ifndef CONFIG_VSERVER_LEGACY
23627 +       ret = do_vshelper(vshelper_path, argv, envp, 1);
23628 +#else
23629 +       ret = do_vshelper(vshelper_path, argv, envp, 0);
23630 +#endif
23631 +       vxi->vx_state &= ~VXS_HELPER;
23632 +       __wakeup_vx_info(vxi);
23633 +       return (ret) ? -EPERM : 0;
23634 +}
23635 +
23636 +
23637 +long vs_reboot(unsigned int cmd, void __user * arg)
23638 +{
23639 +       struct vx_info *vxi = current->vx_info;
23640 +       long ret = 0;
23641 +
23642 +       vxdprintk(VXD_CBIT(misc, 5),
23643 +               "vs_reboot(%p[#%d],%d)",
23644 +               vxi, vxi?vxi->vx_id:0, cmd);
23645 +
23646 +       ret = vs_reboot_helper(vxi, cmd, arg);
23647 +       if (ret)
23648 +               return ret;
23649 +
23650 +       vxi->reboot_cmd = cmd;
23651 +       if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
23652 +               switch (cmd) {
23653 +               case LINUX_REBOOT_CMD_RESTART:
23654 +               case LINUX_REBOOT_CMD_HALT:
23655 +               case LINUX_REBOOT_CMD_POWER_OFF:
23656 +                       vx_info_kill(vxi, 0, SIGKILL);
23657 +                       vx_info_kill(vxi, 1, SIGKILL);
23658 +               default:
23659 +                       break;
23660 +               }
23661 +       }
23662 +       return 0;
23663 +}
23664 +
23665 +
23666 +/*
23667 + *      argv [0] = vshelper_path;
23668 + *      argv [1] = action: "startup", "shutdown"
23669 + *      argv [2] = context identifier
23670 + *
23671 + *      envp [*] = type-specific parameters
23672 + */
23673 +
23674 +long vs_state_change(struct vx_info *vxi, unsigned int cmd)
23675 +{
23676 +       char id_buf[8], cmd_buf[16];
23677 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
23678 +       char *envp[] = {"HOME=/", "TERM=linux",
23679 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
23680 +
23681 +       if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
23682 +               return 0;
23683 +
23684 +       snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
23685 +       snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
23686 +
23687 +       switch (cmd) {
23688 +       case VSC_STARTUP:
23689 +               argv[1] = "startup";
23690 +               break;
23691 +       case VSC_SHUTDOWN:
23692 +               argv[1] = "shutdown";
23693 +               break;
23694 +       default:
23695 +               return 0;
23696 +       }
23697 +
23698 +       return do_vshelper(vshelper_path, argv, envp, 1);
23699 +}
23700 +
23701 +
23702 +/*
23703 + *      argv [0] = vshelper_path;
23704 + *      argv [1] = action: "netup", "netdown"
23705 + *      argv [2] = context identifier
23706 + *
23707 + *      envp [*] = type-specific parameters
23708 + */
23709 +
23710 +long vs_net_change(struct nx_info *nxi, unsigned int cmd)
23711 +{
23712 +       char id_buf[8], cmd_buf[16];
23713 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
23714 +       char *envp[] = {"HOME=/", "TERM=linux",
23715 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
23716 +
23717 +       if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
23718 +               return 0;
23719 +
23720 +       snprintf(id_buf, sizeof(id_buf)-1, "%d", nxi->nx_id);
23721 +       snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
23722 +
23723 +       switch (cmd) {
23724 +       case VSC_NETUP:
23725 +               argv[1] = "netup";
23726 +               break;
23727 +       case VSC_NETDOWN:
23728 +               argv[1] = "netdown";
23729 +               break;
23730 +       default:
23731 +               return 0;
23732 +       }
23733 +
23734 +       return do_vshelper(vshelper_path, argv, envp, 1);
23735 +}
23736 +
23737 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/history.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/history.c
23738 --- linux-2.6.17.11/kernel/vserver/history.c    1970-01-01 01:00:00 +0100
23739 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/history.c       2006-07-09 17:07:14 +0200
23740 @@ -0,0 +1,184 @@
23741 +/*
23742 + *  kernel/vserver/history.c
23743 + *
23744 + *  Virtual Context History Backtrace
23745 + *
23746 + *  Copyright (C) 2004-2005  Herbert Pötzl
23747 + *
23748 + *  V0.01  basic structure
23749 + *  V0.02  hash/unhash and trace
23750 + *  V0.03  preemption fixes
23751 + *
23752 + */
23753 +
23754 +#include <linux/errno.h>
23755 +#include <linux/module.h>
23756 +#include <linux/types.h>
23757 +#include <linux/ctype.h>
23758 +
23759 +#include <asm/uaccess.h>
23760 +#include <asm/atomic.h>
23761 +#include <asm/unistd.h>
23762 +
23763 +#include <linux/vserver/debug.h>
23764 +#include <linux/vserver/history.h>
23765 +
23766 +
23767 +#ifdef CONFIG_VSERVER_HISTORY
23768 +#define VXH_SIZE       CONFIG_VSERVER_HISTORY_SIZE
23769 +#else
23770 +#define VXH_SIZE       64
23771 +#endif
23772 +
23773 +struct _vx_history {
23774 +       unsigned int counter;
23775 +
23776 +       struct _vx_hist_entry entry[VXH_SIZE+1];
23777 +};
23778 +
23779 +
23780 +DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
23781 +
23782 +unsigned volatile int vxh_active = 1;
23783 +
23784 +static atomic_t sequence = ATOMIC_INIT(0);
23785 +
23786 +
23787 +/*     vxh_advance()
23788 +
23789 +       * requires disabled preemption                          */
23790 +
23791 +struct _vx_hist_entry *vxh_advance(void *loc)
23792 +{
23793 +       unsigned int cpu = smp_processor_id();
23794 +       struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
23795 +       struct _vx_hist_entry *entry;
23796 +       unsigned int index;
23797 +
23798 +       index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
23799 +       entry = &hist->entry[index];
23800 +
23801 +       entry->seq = atomic_inc_return(&sequence);
23802 +       entry->loc = loc;
23803 +       return entry;
23804 +}
23805 +
23806 +
23807 +#define VXH_LOC_FMTS   "(#%04x,*%d):%p"
23808 +
23809 +#define VXH_LOC_ARGS(e)        (e)->seq, cpu, (e)->loc
23810 +
23811 +
23812 +#define VXH_VXI_FMTS   "%p[#%d,%d.%d]"
23813 +
23814 +#define VXH_VXI_ARGS(e)        (e)->vxi.ptr,                   \
23815 +                       (e)->vxi.ptr?(e)->vxi.xid:0,    \
23816 +                       (e)->vxi.ptr?(e)->vxi.usecnt:0, \
23817 +                       (e)->vxi.ptr?(e)->vxi.tasks:0
23818 +
23819 +void   vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
23820 +{
23821 +       switch (e->type) {
23822 +       case VXH_THROW_OOPS:
23823 +               printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
23824 +               break;
23825 +
23826 +       case VXH_GET_VX_INFO:
23827 +       case VXH_PUT_VX_INFO:
23828 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
23829 +                       VXH_LOC_ARGS(e),
23830 +                       (e->type==VXH_GET_VX_INFO)?"get":"put",
23831 +                       VXH_VXI_ARGS(e));
23832 +               break;
23833 +
23834 +       case VXH_INIT_VX_INFO:
23835 +       case VXH_SET_VX_INFO:
23836 +       case VXH_CLR_VX_INFO:
23837 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
23838 +                       VXH_LOC_ARGS(e),
23839 +                       (e->type==VXH_INIT_VX_INFO)?"init":
23840 +                       ((e->type==VXH_SET_VX_INFO)?"set":"clr"),
23841 +                       VXH_VXI_ARGS(e), e->sc.data);
23842 +               break;
23843 +
23844 +       case VXH_CLAIM_VX_INFO:
23845 +       case VXH_RELEASE_VX_INFO:
23846 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
23847 +                       VXH_LOC_ARGS(e),
23848 +                       (e->type==VXH_CLAIM_VX_INFO)?"claim":"release",
23849 +                       VXH_VXI_ARGS(e), e->sc.data);
23850 +               break;
23851 +
23852 +       case VXH_ALLOC_VX_INFO:
23853 +       case VXH_DEALLOC_VX_INFO:
23854 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
23855 +                       VXH_LOC_ARGS(e),
23856 +                       (e->type==VXH_ALLOC_VX_INFO)?"alloc":"dealloc",
23857 +                       VXH_VXI_ARGS(e));
23858 +               break;
23859 +
23860 +       case VXH_HASH_VX_INFO:
23861 +       case VXH_UNHASH_VX_INFO:
23862 +               printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
23863 +                       VXH_LOC_ARGS(e),
23864 +                       (e->type==VXH_HASH_VX_INFO)?"hash":"unhash",
23865 +                       VXH_VXI_ARGS(e));
23866 +               break;
23867 +
23868 +       case VXH_LOC_VX_INFO:
23869 +       case VXH_LOOKUP_VX_INFO:
23870 +       case VXH_CREATE_VX_INFO:
23871 +               printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
23872 +                       VXH_LOC_ARGS(e),
23873 +                       (e->type==VXH_CREATE_VX_INFO)?"create":
23874 +                       ((e->type==VXH_LOC_VX_INFO)?"loc":"lookup"),
23875 +                       e->ll.arg, VXH_VXI_ARGS(e));
23876 +               break;
23877 +       }
23878 +}
23879 +
23880 +static void __vxh_dump_history(void)
23881 +{
23882 +       unsigned int i,j;
23883 +
23884 +       printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
23885 +               atomic_read(&sequence), NR_CPUS);
23886 +
23887 +       for (i=0; i < VXH_SIZE; i++) {
23888 +               for (j=0; j < NR_CPUS; j++) {
23889 +                       struct _vx_history *hist =
23890 +                               &per_cpu(vx_history_buffer, j);
23891 +                       unsigned int index = (hist->counter-i) % VXH_SIZE;
23892 +                       struct _vx_hist_entry *entry = &hist->entry[index];
23893 +
23894 +                       vxh_dump_entry(entry, j);
23895 +               }
23896 +       }
23897 +}
23898 +
23899 +void   vxh_dump_history(void)
23900 +{
23901 +       vxh_active = 0;
23902 +#ifdef CONFIG_SMP
23903 +       local_irq_enable();
23904 +       smp_send_stop();
23905 +       local_irq_disable();
23906 +#endif
23907 +       __vxh_dump_history();
23908 +}
23909 +
23910 +
23911 +/* vserver syscall commands below here */
23912 +
23913 +
23914 +int    vc_dump_history(uint32_t id)
23915 +{
23916 +       vxh_active = 0;
23917 +       __vxh_dump_history();
23918 +       vxh_active = 1;
23919 +
23920 +       return 0;
23921 +}
23922 +
23923 +EXPORT_SYMBOL_GPL(vxh_advance);
23924 +
23925 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/init.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/init.c
23926 --- linux-2.6.17.11/kernel/vserver/init.c       1970-01-01 01:00:00 +0100
23927 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/init.c  2006-07-09 17:07:14 +0200
23928 @@ -0,0 +1,46 @@
23929 +/*
23930 + *  linux/kernel/init.c
23931 + *
23932 + *  Virtual Server Init
23933 + *
23934 + *  Copyright (C) 2004-2005  Herbert Pötzl
23935 + *
23936 + *  V0.01  basic structure
23937 + *
23938 + */
23939 +
23940 +#include <linux/errno.h>
23941 +#include <linux/init.h>
23942 +#include <linux/module.h>
23943 +
23944 +int    vserver_register_sysctl(void);
23945 +void   vserver_unregister_sysctl(void);
23946 +
23947 +
23948 +static int __init init_vserver(void)
23949 +{
23950 +       int ret = 0;
23951 +
23952 +#ifdef CONFIG_VSERVER_DEBUG
23953 +       vserver_register_sysctl();
23954 +#endif
23955 +       return ret;
23956 +}
23957 +
23958 +
23959 +static void __exit exit_vserver(void)
23960 +{
23961 +
23962 +#ifdef CONFIG_VSERVER_DEBUG
23963 +       vserver_unregister_sysctl();
23964 +#endif
23965 +       return;
23966 +}
23967 +
23968 +long vx_slab[GFP_ZONETYPES];
23969 +long vx_area;
23970 +
23971 +
23972 +module_init(init_vserver);
23973 +module_exit(exit_vserver);
23974 +
23975 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/inode.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/inode.c
23976 --- linux-2.6.17.11/kernel/vserver/inode.c      1970-01-01 01:00:00 +0100
23977 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/inode.c 2006-07-09 17:07:14 +0200
23978 @@ -0,0 +1,369 @@
23979 +/*
23980 + *  linux/kernel/vserver/inode.c
23981 + *
23982 + *  Virtual Server: File System Support
23983 + *
23984 + *  Copyright (C) 2004-2005  Herbert Pötzl
23985 + *
23986 + *  V0.01  separated from vcontext V0.05
23987 + *
23988 + */
23989 +
23990 +#include <linux/sched.h>
23991 +#include <linux/vs_context.h>
23992 +#include <linux/proc_fs.h>
23993 +#include <linux/devpts_fs.h>
23994 +#include <linux/namei.h>
23995 +#include <linux/mount.h>
23996 +#include <linux/parser.h>
23997 +#include <linux/compat.h>
23998 +#include <linux/vserver/inode.h>
23999 +#include <linux/vserver/inode_cmd.h>
24000 +#include <linux/vserver/tag.h>
24001 +
24002 +#include <asm/errno.h>
24003 +#include <asm/uaccess.h>
24004 +
24005 +
24006 +static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
24007 +{
24008 +       struct proc_dir_entry *entry;
24009 +
24010 +       if (!in || !in->i_sb)
24011 +               return -ESRCH;
24012 +
24013 +       *flags = IATTR_TAG
24014 +               | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
24015 +               | (IS_IUNLINK(in) ? IATTR_IUNLINK : 0)
24016 +               | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0);
24017 +       *mask = IATTR_IUNLINK | IATTR_IMMUTABLE;
24018 +
24019 +       if (S_ISDIR(in->i_mode))
24020 +               *mask |= IATTR_BARRIER;
24021 +
24022 +       if (IS_TAGGED(in)) {
24023 +               *tag = in->i_tag;
24024 +               *mask |= IATTR_TAG;
24025 +       }
24026 +
24027 +       switch (in->i_sb->s_magic) {
24028 +       case PROC_SUPER_MAGIC:
24029 +               entry = PROC_I(in)->pde;
24030 +
24031 +               /* check for specific inodes? */
24032 +               if (entry)
24033 +                       *mask |= IATTR_FLAGS;
24034 +               if (entry)
24035 +                       *flags |= (entry->vx_flags & IATTR_FLAGS);
24036 +               else
24037 +                       *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
24038 +               break;
24039 +
24040 +       case DEVPTS_SUPER_MAGIC:
24041 +               *tag = in->i_tag;
24042 +               *mask |= IATTR_TAG;
24043 +               break;
24044 +
24045 +       default:
24046 +               break;
24047 +       }
24048 +       return 0;
24049 +}
24050 +
24051 +int vc_get_iattr(uint32_t id, void __user *data)
24052 +{
24053 +       struct nameidata nd;
24054 +       struct vcmd_ctx_iattr_v1 vc_data = { .xid = -1 };
24055 +       int ret;
24056 +
24057 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24058 +               return -EFAULT;
24059 +
24060 +       ret = user_path_walk_link(vc_data.name, &nd);
24061 +       if (!ret) {
24062 +               ret = __vc_get_iattr(nd.dentry->d_inode,
24063 +                       &vc_data.xid, &vc_data.flags, &vc_data.mask);
24064 +               path_release(&nd);
24065 +       }
24066 +       if (ret)
24067 +               return ret;
24068 +
24069 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24070 +               ret = -EFAULT;
24071 +       return ret;
24072 +}
24073 +
24074 +#ifdef CONFIG_COMPAT
24075 +
24076 +int vc_get_iattr_x32(uint32_t id, void __user *data)
24077 +{
24078 +       struct nameidata nd;
24079 +       struct vcmd_ctx_iattr_v1_x32 vc_data = { .xid = -1 };
24080 +       int ret;
24081 +
24082 +       if (!vx_check(0, VX_ADMIN))
24083 +               return -ENOSYS;
24084 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24085 +               return -EFAULT;
24086 +
24087 +       ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
24088 +       if (!ret) {
24089 +               ret = __vc_get_iattr(nd.dentry->d_inode,
24090 +                       &vc_data.xid, &vc_data.flags, &vc_data.mask);
24091 +               path_release(&nd);
24092 +       }
24093 +       if (ret)
24094 +               return ret;
24095 +
24096 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24097 +               ret = -EFAULT;
24098 +       return ret;
24099 +}
24100 +
24101 +#endif /* CONFIG_COMPAT */
24102 +
24103 +
24104 +static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
24105 +{
24106 +       struct inode *in = de->d_inode;
24107 +       int error = 0, is_proc = 0, has_tag = 0;
24108 +       struct iattr attr = { 0 };
24109 +
24110 +       if (!in || !in->i_sb)
24111 +               return -ESRCH;
24112 +
24113 +       is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
24114 +       if ((*mask & IATTR_FLAGS) && !is_proc)
24115 +               return -EINVAL;
24116 +
24117 +       has_tag = IS_TAGGED(in) ||
24118 +               (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
24119 +       if ((*mask & IATTR_TAG) && !has_tag)
24120 +               return -EINVAL;
24121 +
24122 +       mutex_lock(&in->i_mutex);
24123 +       if (*mask & IATTR_TAG) {
24124 +               attr.ia_tag = *tag;
24125 +               attr.ia_valid |= ATTR_TAG;
24126 +       }
24127 +
24128 +       if (*mask & IATTR_FLAGS) {
24129 +               struct proc_dir_entry *entry = PROC_I(in)->pde;
24130 +               unsigned int iflags = PROC_I(in)->vx_flags;
24131 +
24132 +               iflags = (iflags & ~(*mask & IATTR_FLAGS))
24133 +                       | (*flags & IATTR_FLAGS);
24134 +               PROC_I(in)->vx_flags = iflags;
24135 +               if (entry)
24136 +                       entry->vx_flags = iflags;
24137 +       }
24138 +
24139 +       if (*mask & (IATTR_BARRIER | IATTR_IUNLINK | IATTR_IMMUTABLE)) {
24140 +               if (*mask & IATTR_IMMUTABLE) {
24141 +                       if (*flags & IATTR_IMMUTABLE)
24142 +                               in->i_flags |= S_IMMUTABLE;
24143 +                       else
24144 +                               in->i_flags &= ~S_IMMUTABLE;
24145 +               }
24146 +               if (*mask & IATTR_IUNLINK) {
24147 +                       if (*flags & IATTR_IUNLINK)
24148 +                               in->i_flags |= S_IUNLINK;
24149 +                       else
24150 +                               in->i_flags &= ~S_IUNLINK;
24151 +               }
24152 +               if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
24153 +                       if (*flags & IATTR_BARRIER)
24154 +                               in->i_flags |= S_BARRIER;
24155 +                       else
24156 +                               in->i_flags &= ~S_BARRIER;
24157 +               }
24158 +               if (in->i_op && in->i_op->sync_flags) {
24159 +                       error = in->i_op->sync_flags(in);
24160 +                       if (error)
24161 +                               goto out;
24162 +               }
24163 +       }
24164 +
24165 +       if (attr.ia_valid) {
24166 +               if (in->i_op && in->i_op->setattr)
24167 +                       error = in->i_op->setattr(de, &attr);
24168 +               else {
24169 +                       error = inode_change_ok(in, &attr);
24170 +                       if (!error)
24171 +                               error = inode_setattr(in, &attr);
24172 +               }
24173 +       }
24174 +
24175 +out:
24176 +       mutex_unlock(&in->i_mutex);
24177 +       return error;
24178 +}
24179 +
24180 +int vc_set_iattr(uint32_t id, void __user *data)
24181 +{
24182 +       struct nameidata nd;
24183 +       struct vcmd_ctx_iattr_v1 vc_data;
24184 +       int ret;
24185 +
24186 +       if (!capable(CAP_LINUX_IMMUTABLE))
24187 +               return -EPERM;
24188 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24189 +               return -EFAULT;
24190 +
24191 +       ret = user_path_walk_link(vc_data.name, &nd);
24192 +       if (!ret) {
24193 +               ret = __vc_set_iattr(nd.dentry,
24194 +                       &vc_data.xid, &vc_data.flags, &vc_data.mask);
24195 +               path_release(&nd);
24196 +       }
24197 +
24198 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24199 +               ret = -EFAULT;
24200 +       return ret;
24201 +}
24202 +
24203 +#ifdef CONFIG_COMPAT
24204 +
24205 +int vc_set_iattr_x32(uint32_t id, void __user *data)
24206 +{
24207 +       struct nameidata nd;
24208 +       struct vcmd_ctx_iattr_v1_x32 vc_data;
24209 +       int ret;
24210 +
24211 +       if (!capable(CAP_LINUX_IMMUTABLE))
24212 +               return -EPERM;
24213 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24214 +               return -EFAULT;
24215 +
24216 +       ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
24217 +       if (!ret) {
24218 +               ret = __vc_set_iattr(nd.dentry,
24219 +                       &vc_data.xid, &vc_data.flags, &vc_data.mask);
24220 +               path_release(&nd);
24221 +       }
24222 +
24223 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24224 +               ret = -EFAULT;
24225 +       return ret;
24226 +}
24227 +
24228 +#endif /* CONFIG_COMPAT */
24229 +
24230 +#ifdef CONFIG_VSERVER_LEGACY
24231 +
24232 +#define PROC_DYNAMIC_FIRST 0xF0000000UL
24233 +
24234 +int vx_proc_ioctl(struct inode * inode, struct file * filp,
24235 +       unsigned int cmd, unsigned long arg)
24236 +{
24237 +       struct proc_dir_entry *entry;
24238 +       int error = 0;
24239 +       int flags;
24240 +
24241 +       if (inode->i_ino < PROC_DYNAMIC_FIRST)
24242 +               return -ENOTTY;
24243 +
24244 +       entry = PROC_I(inode)->pde;
24245 +       if (!entry)
24246 +               return -ENOTTY;
24247 +
24248 +       switch(cmd) {
24249 +       case FIOC_GETXFLG: {
24250 +               /* fixme: if stealth, return -ENOTTY */
24251 +               error = -EPERM;
24252 +               flags = entry->vx_flags;
24253 +               if (capable(CAP_CONTEXT))
24254 +                       error = put_user(flags, (int __user *) arg);
24255 +               break;
24256 +       }
24257 +       case FIOC_SETXFLG: {
24258 +               /* fixme: if stealth, return -ENOTTY */
24259 +               error = -EPERM;
24260 +               if (!capable(CAP_CONTEXT))
24261 +                       break;
24262 +               error = -EROFS;
24263 +               if (IS_RDONLY(inode))
24264 +                       break;
24265 +               error = -EFAULT;
24266 +               if (get_user(flags, (int __user *) arg))
24267 +                       break;
24268 +               error = 0;
24269 +               entry->vx_flags = flags;
24270 +               break;
24271 +       }
24272 +       default:
24273 +               return -ENOTTY;
24274 +       }
24275 +       return error;
24276 +}
24277 +#endif /* CONFIG_VSERVER_LEGACY */
24278 +
24279 +#ifdef CONFIG_PROPAGATE
24280 +
24281 +int dx_parse_tag(char *string, tag_t *tag, int remove)
24282 +{
24283 +       static match_table_t tokens = {
24284 +               {1, "tagid=%u"},
24285 +               {0, NULL}
24286 +       };
24287 +       substring_t args[MAX_OPT_ARGS];
24288 +       int token, option = 0;
24289 +
24290 +       if (!string)
24291 +               return 0;
24292 +
24293 +       token = match_token(string, tokens, args);
24294 +       if (token && tag && !match_int(args, &option))
24295 +               *tag = option;
24296 +
24297 +       vxdprintk(VXD_CBIT(tag, 7),
24298 +               "dx_parse_tag(»%s«): %d:#%d",
24299 +               string, token, option);
24300 +
24301 +       if ((token == 1) && remove) {
24302 +               char *p = strstr(string, "tagid=");
24303 +               char *q = p;
24304 +
24305 +               if (p) {
24306 +                       while (*q != '\0' && *q != ',')
24307 +                               q++;
24308 +                       while (*q)
24309 +                               *p++ = *q++;
24310 +                       while (*p)
24311 +                               *p++ = '\0';
24312 +               }
24313 +       }
24314 +       return token;
24315 +}
24316 +
24317 +void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
24318 +{
24319 +       tag_t new_tag = 0;
24320 +       struct vfsmount *mnt;
24321 +       int propagate;
24322 +
24323 +       if (!nd)
24324 +               return;
24325 +       mnt = nd->mnt;
24326 +       if (!mnt)
24327 +               return;
24328 +
24329 +       propagate = (mnt->mnt_flags & MNT_TAGID);
24330 +       if (propagate)
24331 +               new_tag = mnt->mnt_tag;
24332 +
24333 +       vxdprintk(VXD_CBIT(tag, 7),
24334 +               "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
24335 +               inode, inode->i_ino, inode->i_tag,
24336 +               new_tag, (propagate)?1:0);
24337 +
24338 +       if (propagate)
24339 +               inode->i_tag = new_tag;
24340 +}
24341 +
24342 +#include <linux/module.h>
24343 +
24344 +EXPORT_SYMBOL_GPL(__dx_propagate_tag);
24345 +
24346 +#endif /* CONFIG_PROPAGATE */
24347 +
24348 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/legacy.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/legacy.c
24349 --- linux-2.6.17.11/kernel/vserver/legacy.c     1970-01-01 01:00:00 +0100
24350 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/legacy.c        2006-08-26 00:52:08 +0200
24351 @@ -0,0 +1,115 @@
24352 +/*
24353 + *  linux/kernel/vserver/legacy.c
24354 + *
24355 + *  Virtual Server: Legacy Funtions
24356 + *
24357 + *  Copyright (C) 2001-2003  Jacques Gelinas
24358 + *  Copyright (C) 2003-2005  Herbert Pötzl
24359 + *
24360 + *  V0.01  broken out from vcontext.c V0.05
24361 + *
24362 + */
24363 +
24364 +#include <linux/sched.h>
24365 +#include <linux/vs_context.h>
24366 +#include <linux/vs_network.h>
24367 +#include <linux/vserver/legacy.h>
24368 +#include <linux/vserver/namespace.h>
24369 +#include <linux/namespace.h>
24370 +
24371 +#include <asm/errno.h>
24372 +#include <asm/uaccess.h>
24373 +
24374 +
24375 +extern int vx_set_init(struct vx_info *, struct task_struct *);
24376 +
24377 +static int vx_set_initpid(struct vx_info *vxi, int pid)
24378 +{
24379 +       struct task_struct *init;
24380 +
24381 +       init = find_task_by_real_pid(pid);
24382 +       if (!init)
24383 +               return -ESRCH;
24384 +
24385 +       vxi->vx_flags &= ~VXF_STATE_INIT;
24386 +       return vx_set_init(vxi, init);
24387 +}
24388 +
24389 +int vc_new_s_context(uint32_t ctx, void __user *data)
24390 +{
24391 +       int ret = -ENOMEM;
24392 +       struct vcmd_new_s_context_v1 vc_data;
24393 +       struct vx_info *new_vxi;
24394 +
24395 +       if (copy_from_user(&vc_data, data, sizeof(vc_data)))
24396 +               return -EFAULT;
24397 +
24398 +       /* legacy hack, will be removed soon */
24399 +       if (ctx == -2) {
24400 +               /* assign flags and initpid */
24401 +               if (!current->vx_info)
24402 +                       return -EINVAL;
24403 +               ret = 0;
24404 +               if (vc_data.flags & VX_INFO_INIT)
24405 +                       ret = vx_set_initpid(current->vx_info, current->tgid);
24406 +               if (ret == 0) {
24407 +                       /* We keep the same vx_id, but lower the capabilities */
24408 +                       current->vx_info->vx_bcaps &= (~vc_data.remove_cap);
24409 +                       ret = vx_current_xid();
24410 +                       current->vx_info->vx_flags |= vc_data.flags;
24411 +               }
24412 +               return ret;
24413 +       }
24414 +
24415 +       if (!vx_check(0, VX_ADMIN) || !capable(CAP_SYS_ADMIN)
24416 +               /* might make sense in the future, or not ... */
24417 +               || vx_flags(VX_INFO_LOCK, 0))
24418 +               return -EPERM;
24419 +
24420 +       /* ugly hack for Spectator */
24421 +       if (ctx == 1) {
24422 +               current->xid = 1;
24423 +               return 0;
24424 +       }
24425 +
24426 +       if (((ctx > MAX_S_CONTEXT) && (ctx != VX_DYNAMIC_ID)) ||
24427 +               (ctx == 0))
24428 +               return -EINVAL;
24429 +
24430 +       if ((ctx == VX_DYNAMIC_ID) || (ctx < MIN_D_CONTEXT))
24431 +               new_vxi = lookup_or_create_vx_info(ctx);
24432 +       else
24433 +               new_vxi = lookup_vx_info(ctx);
24434 +
24435 +       if (!new_vxi)
24436 +               return -EINVAL;
24437 +
24438 +       ret = -EPERM;
24439 +       if (!vx_info_flags(new_vxi, VXF_STATE_SETUP, 0) &&
24440 +               vx_info_flags(new_vxi, VX_INFO_PRIVATE, 0))
24441 +               goto out_put;
24442 +
24443 +       new_vxi->vx_flags &= ~VXF_STATE_SETUP;
24444 +
24445 +       ret = vx_migrate_task(current, new_vxi);
24446 +       if (ret == 0) {
24447 +               current->vx_info->vx_bcaps &= (~vc_data.remove_cap);
24448 +               new_vxi->vx_flags |= vc_data.flags;
24449 +               if (vc_data.flags & VX_INFO_INIT)
24450 +                       vx_set_initpid(new_vxi, current->tgid);
24451 +               if (vc_data.flags & VX_INFO_NAMESPACE)
24452 +                       vx_set_namespace(new_vxi,
24453 +                               current->namespace, current->fs);
24454 +               if (vc_data.flags & VX_INFO_NPROC)
24455 +                       __rlim_set(&new_vxi->limit, RLIMIT_NPROC,
24456 +                               current->signal->rlim[RLIMIT_NPROC].rlim_max);
24457 +
24458 +               /* tweak some defaults for legacy */
24459 +               new_vxi->vx_flags |= (VXF_HIDE_NETIF|VXF_INFO_INIT);
24460 +               ret = new_vxi->vx_id;
24461 +       }
24462 +out_put:
24463 +       put_vx_info(new_vxi);
24464 +       return ret;
24465 +}
24466 +
24467 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/legacynet.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/legacynet.c
24468 --- linux-2.6.17.11/kernel/vserver/legacynet.c  1970-01-01 01:00:00 +0100
24469 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/legacynet.c     2006-08-17 01:24:16 +0200
24470 @@ -0,0 +1,84 @@
24471 +
24472 +/*
24473 + *  linux/kernel/vserver/legacynet.c
24474 + *
24475 + *  Virtual Server: Legacy Network Funtions
24476 + *
24477 + *  Copyright (C) 2001-2003  Jacques Gelinas
24478 + *  Copyright (C) 2003-2005  Herbert Pötzl
24479 + *
24480 + *  V0.01  broken out from legacy.c
24481 + *
24482 + */
24483 +
24484 +#include <linux/sched.h>
24485 +#include <linux/vs_context.h>
24486 +#include <linux/vs_network.h>
24487 +#include <linux/vserver/legacy.h>
24488 +#include <linux/namespace.h>
24489 +#include <linux/err.h>
24490 +
24491 +#include <asm/errno.h>
24492 +#include <asm/uaccess.h>
24493 +
24494 +
24495 +extern struct nx_info *create_nx_info(void);
24496 +
24497 +/*  set ipv4 root (syscall) */
24498 +
24499 +int vc_set_ipv4root(uint32_t nbip, void __user *data)
24500 +{
24501 +       int i, err = -EPERM;
24502 +       struct vcmd_set_ipv4root_v3 vc_data;
24503 +       struct nx_info *new_nxi, *nxi = current->nx_info;
24504 +
24505 +       if (nbip < 0 || nbip > NB_IPV4ROOT)
24506 +               return -EINVAL;
24507 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24508 +               return -EFAULT;
24509 +
24510 +       if (!nxi || nxi->ipv4[0] == 0 || capable(CAP_NET_ADMIN))
24511 +               /* We are allowed to change everything */
24512 +               err = 0;
24513 +       else if (nxi) {
24514 +               int found = 0;
24515 +
24516 +               /* We are allowed to select a subset of the currently
24517 +                  installed IP numbers. No new one are allowed
24518 +                  We can't change the broadcast address though */
24519 +               for (i=0; i<nbip; i++) {
24520 +                       int j;
24521 +                       __u32 nxip = vc_data.nx_mask_pair[i].ip;
24522 +                       for (j=0; j<nxi->nbipv4; j++) {
24523 +                               if (nxip == nxi->ipv4[j]) {
24524 +                                       found++;
24525 +                                       break;
24526 +                               }
24527 +                       }
24528 +               }
24529 +               if ((found == nbip) &&
24530 +                       (vc_data.broadcast == nxi->v4_bcast))
24531 +                       err = 0;
24532 +       }
24533 +       if (err)
24534 +               return err;
24535 +
24536 +       new_nxi = create_nx_info();
24537 +       if (IS_ERR(new_nxi))
24538 +               return -EINVAL;
24539 +
24540 +       new_nxi->nbipv4 = nbip;
24541 +       for (i=0; i<nbip; i++) {
24542 +               new_nxi->ipv4[i] = vc_data.nx_mask_pair[i].ip;
24543 +               new_nxi->mask[i] = vc_data.nx_mask_pair[i].mask;
24544 +       }
24545 +       new_nxi->v4_bcast = vc_data.broadcast;
24546 +       if (nxi)
24547 +               printk("!!! switching nx_info %p->%p\n", nxi, new_nxi);
24548 +
24549 +       nx_migrate_task(current, new_nxi);
24550 +       put_nx_info(new_nxi);
24551 +       return 0;
24552 +}
24553 +
24554 +
24555 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/limit.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/limit.c
24556 --- linux-2.6.17.11/kernel/vserver/limit.c      1970-01-01 01:00:00 +0100
24557 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/limit.c 2006-08-19 13:38:21 +0200
24558 @@ -0,0 +1,297 @@
24559 +/*
24560 + *  linux/kernel/vserver/limit.c
24561 + *
24562 + *  Virtual Server: Context Limits
24563 + *
24564 + *  Copyright (C) 2004-2006  Herbert Pötzl
24565 + *
24566 + *  V0.01  broken out from vcontext V0.05
24567 + *  V0.02  changed vcmds to vxi arg
24568 + *
24569 + */
24570 +
24571 +#include <linux/module.h>
24572 +#include <linux/vs_context.h>
24573 +#include <linux/vs_limit.h>
24574 +#include <linux/vserver/limit.h>
24575 +#include <linux/vserver/switch.h>
24576 +#include <linux/vserver/limit_cmd.h>
24577 +
24578 +#include <asm/errno.h>
24579 +#include <asm/uaccess.h>
24580 +
24581 +
24582 +const char *vlimit_name[NUM_LIMITS] = {
24583 +       [RLIMIT_CPU]            = "CPU",
24584 +       [RLIMIT_RSS]            = "RSS",
24585 +       [RLIMIT_NPROC]          = "NPROC",
24586 +       [RLIMIT_NOFILE]         = "NOFILE",
24587 +       [RLIMIT_MEMLOCK]        = "VML",
24588 +       [RLIMIT_AS]             = "VM",
24589 +       [RLIMIT_LOCKS]          = "LOCKS",
24590 +       [RLIMIT_SIGPENDING]     = "SIGP",
24591 +       [RLIMIT_MSGQUEUE]       = "MSGQ",
24592 +
24593 +       [VLIMIT_NSOCK]          = "NSOCK",
24594 +       [VLIMIT_OPENFD]         = "OPENFD",
24595 +       [VLIMIT_ANON]           = "ANON",
24596 +       [VLIMIT_SHMEM]          = "SHMEM",
24597 +       [VLIMIT_DENTRY]         = "DENTRY",
24598 +};
24599 +
24600 +EXPORT_SYMBOL_GPL(vlimit_name);
24601 +
24602 +
24603 +static int is_valid_rlimit(int id)
24604 +{
24605 +       int valid = 0;
24606 +
24607 +       switch (id) {
24608 +       case RLIMIT_RSS:
24609 +       case RLIMIT_NPROC:
24610 +       case RLIMIT_NOFILE:
24611 +       case RLIMIT_MEMLOCK:
24612 +       case RLIMIT_AS:
24613 +       case RLIMIT_LOCKS:
24614 +       case RLIMIT_MSGQUEUE:
24615 +
24616 +       case VLIMIT_NSOCK:
24617 +       case VLIMIT_OPENFD:
24618 +       case VLIMIT_ANON:
24619 +       case VLIMIT_SHMEM:
24620 +       case VLIMIT_DENTRY:
24621 +               valid = 1;
24622 +               break;
24623 +       }
24624 +       return valid;
24625 +}
24626 +
24627 +static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
24628 +{
24629 +       rlim_t limit = __rlim_soft(&vxi->limit, id);
24630 +       return VX_VLIM(limit);
24631 +}
24632 +
24633 +static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
24634 +{
24635 +       rlim_t limit = __rlim_hard(&vxi->limit, id);
24636 +       return VX_VLIM(limit);
24637 +}
24638 +
24639 +static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
24640 +       uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
24641 +{
24642 +       if (!is_valid_rlimit(id))
24643 +               return -EINVAL;
24644 +
24645 +       if (minimum)
24646 +               *minimum = CRLIM_UNSET;
24647 +       if (softlimit)
24648 +               *softlimit = vc_get_soft(vxi, id);
24649 +       if (maximum)
24650 +               *maximum = vc_get_hard(vxi, id);
24651 +       return 0;
24652 +}
24653 +
24654 +int vc_get_rlimit(struct vx_info *vxi, void __user *data)
24655 +{
24656 +       struct vcmd_ctx_rlimit_v0 vc_data;
24657 +       int ret;
24658 +
24659 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24660 +               return -EFAULT;
24661 +
24662 +       ret = do_get_rlimit(vxi, vc_data.id,
24663 +               &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
24664 +       if (ret)
24665 +               return ret;
24666 +
24667 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24668 +               return -EFAULT;
24669 +       return 0;
24670 +}
24671 +
24672 +static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
24673 +       uint64_t minimum, uint64_t softlimit, uint64_t maximum)
24674 +{
24675 +       if (!is_valid_rlimit(id))
24676 +               return -EINVAL;
24677 +
24678 +       if (maximum != CRLIM_KEEP)
24679 +               __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
24680 +       if (softlimit != CRLIM_KEEP)
24681 +               __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
24682 +
24683 +       /* clamp soft limit */
24684 +       if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
24685 +               __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
24686 +
24687 +       return 0;
24688 +}
24689 +
24690 +int vc_set_rlimit(struct vx_info *vxi, void __user *data)
24691 +{
24692 +       struct vcmd_ctx_rlimit_v0 vc_data;
24693 +
24694 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24695 +               return -EFAULT;
24696 +
24697 +       return do_set_rlimit(vxi, vc_data.id,
24698 +               vc_data.minimum, vc_data.softlimit, vc_data.maximum);
24699 +}
24700 +
24701 +#ifdef CONFIG_IA32_EMULATION
24702 +
24703 +int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
24704 +{
24705 +       struct vcmd_ctx_rlimit_v0_x32 vc_data;
24706 +
24707 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24708 +               return -EFAULT;
24709 +
24710 +       return do_set_rlimit(vxi, vc_data.id,
24711 +               vc_data.minimum, vc_data.softlimit, vc_data.maximum);
24712 +}
24713 +
24714 +int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
24715 +{
24716 +       struct vcmd_ctx_rlimit_v0_x32 vc_data;
24717 +       int ret;
24718 +
24719 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24720 +               return -EFAULT;
24721 +
24722 +       ret = do_get_rlimit(vxi, vc_data.id,
24723 +               &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
24724 +       if (ret)
24725 +               return ret;
24726 +
24727 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24728 +               return -EFAULT;
24729 +       return 0;
24730 +}
24731 +
24732 +#endif /* CONFIG_IA32_EMULATION */
24733 +
24734 +
24735 +int vc_get_rlimit_mask(uint32_t id, void __user *data)
24736 +{
24737 +       static struct vcmd_ctx_rlimit_mask_v0 mask = {
24738 +                       /* minimum */
24739 +               0
24740 +               ,       /* softlimit */
24741 +               (1 << RLIMIT_RSS) |
24742 +               (1 << VLIMIT_ANON) |
24743 +               0
24744 +               ,       /* maximum */
24745 +               (1 << RLIMIT_RSS) |
24746 +               (1 << RLIMIT_NPROC) |
24747 +               (1 << RLIMIT_NOFILE) |
24748 +               (1 << RLIMIT_MEMLOCK) |
24749 +               (1 << RLIMIT_LOCKS) |
24750 +               (1 << RLIMIT_AS) |
24751 +               (1 << VLIMIT_ANON) |
24752 +               (1 << VLIMIT_DENTRY) |
24753 +               0
24754 +               };
24755 +
24756 +       if (copy_to_user(data, &mask, sizeof(mask)))
24757 +               return -EFAULT;
24758 +       return 0;
24759 +}
24760 +
24761 +
24762 +static inline void vx_reset_minmax(struct _vx_limit *limit)
24763 +{
24764 +       rlim_t value;
24765 +       int lim;
24766 +
24767 +       for (lim=0; lim<NUM_LIMITS; lim++) {
24768 +               value = __rlim_get(limit, lim);
24769 +               __rlim_rmax(limit, lim) = value;
24770 +               __rlim_rmin(limit, lim) = value;
24771 +       }
24772 +}
24773 +
24774 +
24775 +int vc_reset_minmax(struct vx_info *vxi, void __user *data)
24776 +{
24777 +       vx_reset_minmax(&vxi->limit);
24778 +       return 0;
24779 +}
24780 +
24781 +
24782 +int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
24783 +{
24784 +       struct vcmd_rlimit_stat_v0 vc_data;
24785 +       struct _vx_limit *limit = &vxi->limit;
24786 +       int id;
24787 +
24788 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24789 +               return -EFAULT;
24790 +
24791 +       id = vc_data.id;
24792 +       if (!is_valid_rlimit(id))
24793 +               return -EINVAL;
24794 +
24795 +       vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
24796 +       vc_data.value = __rlim_get(limit, id);
24797 +       vc_data.minimum = __rlim_rmin(limit, id);
24798 +       vc_data.maximum = __rlim_rmax(limit, id);
24799 +
24800 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24801 +               return -EFAULT;
24802 +       return 0;
24803 +}
24804 +
24805 +
24806 +void vx_vsi_meminfo(struct sysinfo *val)
24807 +{
24808 +       struct vx_info *vxi = current->vx_info;
24809 +       unsigned long totalram, freeram;
24810 +       rlim_t v;
24811 +
24812 +       /* we blindly accept the max */
24813 +       v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
24814 +       totalram = (v != RLIM_INFINITY) ? v : val->totalram;
24815 +
24816 +       /* total minus used equals free */
24817 +       v = __rlim_get(&vxi->limit, RLIMIT_RSS);
24818 +       freeram = (v < totalram) ? totalram - v : 0;
24819 +
24820 +       val->totalram = totalram;
24821 +       val->freeram = freeram;
24822 +       val->bufferram = 0;
24823 +       val->totalhigh = 0;
24824 +       val->freehigh = 0;
24825 +       return;
24826 +}
24827 +
24828 +void vx_vsi_swapinfo(struct sysinfo *val)
24829 +{
24830 +       struct vx_info *vxi = current->vx_info;
24831 +       unsigned long totalswap, freeswap;
24832 +       rlim_t v, w;
24833 +
24834 +       v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
24835 +       if (v == RLIM_INFINITY) {
24836 +               val->freeswap = val->totalswap;
24837 +               return;
24838 +       }
24839 +
24840 +       /* we blindly accept the max */
24841 +       w = __rlim_hard(&vxi->limit, RLIMIT_RSS);
24842 +       totalswap = (w != RLIM_INFINITY) ? (w - v) : val->totalswap;
24843 +
24844 +       /* currently 'used' swap */
24845 +       w = __rlim_get(&vxi->limit, RLIMIT_RSS);
24846 +       w -= (w > v) ? v : w;
24847 +
24848 +       /* total minus used equals free */
24849 +       freeswap = (w < totalswap) ? totalswap - w : 0;
24850 +
24851 +       val->totalswap = totalswap;
24852 +       val->freeswap = freeswap;
24853 +       return;
24854 +}
24855 +
24856 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/limit_init.h linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/limit_init.h
24857 --- linux-2.6.17.11/kernel/vserver/limit_init.h 1970-01-01 01:00:00 +0100
24858 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/limit_init.h    2006-07-12 14:16:06 +0200
24859 @@ -0,0 +1,33 @@
24860 +
24861 +
24862 +static inline void vx_info_init_limit(struct _vx_limit *limit)
24863 +{
24864 +       int lim;
24865 +
24866 +       for (lim=0; lim<NUM_LIMITS; lim++) {
24867 +               __rlim_soft(limit, lim) = RLIM_INFINITY;
24868 +               __rlim_hard(limit, lim) = RLIM_INFINITY;
24869 +               __rlim_set(limit, lim, 0);
24870 +               atomic_set(&__rlim_lhit(limit, lim), 0);
24871 +               __rlim_rmin(limit, lim) = 0;
24872 +               __rlim_rmax(limit, lim) = 0;
24873 +       }
24874 +}
24875 +
24876 +static inline void vx_info_exit_limit(struct _vx_limit *limit)
24877 +{
24878 +#ifdef CONFIG_VSERVER_DEBUG
24879 +       rlim_t value;
24880 +       int lim;
24881 +
24882 +       for (lim=0; lim<NUM_LIMITS; lim++) {
24883 +               if ((1 << lim) & VLIM_NOCHECK)
24884 +                       continue;
24885 +               value = __rlim_get(limit, lim);
24886 +               vxwprintk(value,
24887 +                       "!!! limit: %p[%s,%d] = %ld on exit.",
24888 +                       limit, vlimit_name[lim], lim, (long)value);
24889 +       }
24890 +#endif
24891 +}
24892 +
24893 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/limit_proc.h linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/limit_proc.h
24894 --- linux-2.6.17.11/kernel/vserver/limit_proc.h 1970-01-01 01:00:00 +0100
24895 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/limit_proc.h    2006-07-09 17:07:14 +0200
24896 @@ -0,0 +1,71 @@
24897 +#ifndef _VX_LIMIT_PROC_H
24898 +#define _VX_LIMIT_PROC_H
24899 +
24900 +
24901 +static inline void vx_limit_fixup(struct _vx_limit *limit)
24902 +{
24903 +       rlim_t value;
24904 +       int lim;
24905 +
24906 +       for (lim=0; lim<NUM_LIMITS; lim++) {
24907 +               value = __rlim_get(limit, lim);
24908 +               if (value > __rlim_rmax(limit, lim))
24909 +                       __rlim_rmax(limit, lim) = value;
24910 +               if (value < __rlim_rmin(limit, lim))
24911 +                       __rlim_rmin(limit, lim) = value;
24912 +               if (__rlim_rmax(limit, lim) > __rlim_hard(limit, lim))
24913 +                       __rlim_rmax(limit, lim) = __rlim_hard(limit, lim);
24914 +       }
24915 +}
24916 +
24917 +
24918 +#define VX_LIMIT_FMT   ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
24919 +#define VX_LIMIT_TOP   \
24920 +       "Limit\t current\t     min/max\t\t    soft/hard\t\thits\n"
24921 +
24922 +#define VX_LIMIT_ARG(r)                                \
24923 +       ,(unsigned long)__rlim_get(limit, r)    \
24924 +       ,(unsigned long)__rlim_rmin(limit, r)   \
24925 +       ,(unsigned long)__rlim_rmax(limit, r)   \
24926 +       ,VX_VLIM(__rlim_soft(limit, r))         \
24927 +       ,VX_VLIM(__rlim_hard(limit, r))         \
24928 +       ,atomic_read(&__rlim_lhit(limit, r))
24929 +
24930 +static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
24931 +{
24932 +       vx_limit_fixup(limit);
24933 +       return sprintf(buffer, VX_LIMIT_TOP
24934 +               "PROC"  VX_LIMIT_FMT
24935 +               "VM"    VX_LIMIT_FMT
24936 +               "VML"   VX_LIMIT_FMT
24937 +               "RSS"   VX_LIMIT_FMT
24938 +               "ANON"  VX_LIMIT_FMT
24939 +               "FILES" VX_LIMIT_FMT
24940 +               "OFD"   VX_LIMIT_FMT
24941 +               "LOCKS" VX_LIMIT_FMT
24942 +               "SOCK"  VX_LIMIT_FMT
24943 +               "MSGQ"  VX_LIMIT_FMT
24944 +               "SHM"   VX_LIMIT_FMT
24945 +               "SEMA"  VX_LIMIT_FMT
24946 +               "SEMS"  VX_LIMIT_FMT
24947 +               "DENT"  VX_LIMIT_FMT
24948 +               VX_LIMIT_ARG(RLIMIT_NPROC)
24949 +               VX_LIMIT_ARG(RLIMIT_AS)
24950 +               VX_LIMIT_ARG(RLIMIT_MEMLOCK)
24951 +               VX_LIMIT_ARG(RLIMIT_RSS)
24952 +               VX_LIMIT_ARG(VLIMIT_ANON)
24953 +               VX_LIMIT_ARG(RLIMIT_NOFILE)
24954 +               VX_LIMIT_ARG(VLIMIT_OPENFD)
24955 +               VX_LIMIT_ARG(RLIMIT_LOCKS)
24956 +               VX_LIMIT_ARG(VLIMIT_NSOCK)
24957 +               VX_LIMIT_ARG(RLIMIT_MSGQUEUE)
24958 +               VX_LIMIT_ARG(VLIMIT_SHMEM)
24959 +               VX_LIMIT_ARG(VLIMIT_SEMARY)
24960 +               VX_LIMIT_ARG(VLIMIT_NSEMS)
24961 +               VX_LIMIT_ARG(VLIMIT_DENTRY)
24962 +               );
24963 +}
24964 +
24965 +#endif /* _VX_LIMIT_PROC_H */
24966 +
24967 +
24968 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/monitor.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/monitor.c
24969 --- linux-2.6.17.11/kernel/vserver/monitor.c    1970-01-01 01:00:00 +0100
24970 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/monitor.c       2006-07-09 17:07:14 +0200
24971 @@ -0,0 +1,64 @@
24972 +/*
24973 + *  kernel/vserver/monitor.c
24974 + *
24975 + *  Virtual Context Scheduler Monitor
24976 + *
24977 + *  Copyright (C) 2006 Herbert Pötzl
24978 + *
24979 + *  V0.01  basic design
24980 + *
24981 + */
24982 +
24983 +#include <linux/config.h>
24984 +#include <linux/errno.h>
24985 +#include <linux/module.h>
24986 +#include <linux/types.h>
24987 +#include <linux/ctype.h>
24988 +
24989 +#include <asm/uaccess.h>
24990 +#include <asm/atomic.h>
24991 +#include <asm/unistd.h>
24992 +
24993 +#include <linux/vserver/monitor.h>
24994 +
24995 +
24996 +#ifdef CONFIG_VSERVER_MONITOR
24997 +#define VXM_SIZE       CONFIG_VSERVER_MONITOR_SIZE
24998 +#else
24999 +#define VXM_SIZE       64
25000 +#endif
25001 +
25002 +struct _vx_monitor {
25003 +       unsigned int counter;
25004 +
25005 +       struct _vx_mon_entry entry[VXM_SIZE+1];
25006 +};
25007 +
25008 +
25009 +DEFINE_PER_CPU(struct _vx_monitor, vx_monitor_buffer);
25010 +
25011 +unsigned volatile int vxm_active = 1;
25012 +
25013 +static atomic_t sequence = ATOMIC_INIT(0);
25014 +
25015 +
25016 +/*     vxm_advance()
25017 +
25018 +       * requires disabled preemption                          */
25019 +
25020 +struct _vx_mon_entry *vxm_advance(int cpu)
25021 +{
25022 +       struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu);
25023 +       struct _vx_mon_entry *entry;
25024 +       unsigned int index;
25025 +
25026 +       index = vxm_active ? (mon->counter++ % VXM_SIZE) : VXM_SIZE;
25027 +       entry = &mon->entry[index];
25028 +
25029 +       entry->ev.seq = atomic_inc_return(&sequence);
25030 +       entry->ev.jif = jiffies;
25031 +       return entry;
25032 +}
25033 +
25034 +EXPORT_SYMBOL_GPL(vxm_advance);
25035 +
25036 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/namespace.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/namespace.c
25037 --- linux-2.6.17.11/kernel/vserver/namespace.c  1970-01-01 01:00:00 +0100
25038 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/namespace.c     2006-07-30 03:46:39 +0200
25039 @@ -0,0 +1,101 @@
25040 +/*
25041 + *  linux/kernel/vserver/namespace.c
25042 + *
25043 + *  Virtual Server: Context Namespace Support
25044 + *
25045 + *  Copyright (C) 2003-2006  Herbert Pötzl
25046 + *
25047 + *  V0.01  broken out from context.c 0.07
25048 + *  V0.02  added task locking for namespace
25049 + *  V0.03  broken out vx_enter_namespace
25050 + *
25051 + */
25052 +
25053 +#include <linux/utsname.h>
25054 +#include <linux/sched.h>
25055 +#include <linux/vs_context.h>
25056 +#include <linux/vserver/namespace.h>
25057 +#include <linux/vserver/namespace_cmd.h>
25058 +#include <linux/dcache.h>
25059 +#include <linux/mount.h>
25060 +#include <linux/fs.h>
25061 +
25062 +#include <asm/errno.h>
25063 +#include <asm/uaccess.h>
25064 +
25065 +
25066 +/* namespace functions */
25067 +
25068 +#include <linux/namespace.h>
25069 +
25070 +int vx_enter_namespace(struct vx_info *vxi)
25071 +{
25072 +       struct fs_struct *old_fs, *fs;
25073 +       struct namespace *old_ns;
25074 +
25075 +       if (vx_info_flags(vxi, VXF_INFO_LOCK, 0))
25076 +               return -EACCES;
25077 +       if (!vxi->vx_namespace)
25078 +               return -EINVAL;
25079 +
25080 +       fs = copy_fs_struct(vxi->vx_fs);
25081 +       if (!fs)
25082 +               return -ENOMEM;
25083 +
25084 +       task_lock(current);
25085 +       old_ns = current->namespace;
25086 +       old_fs = current->fs;
25087 +       get_namespace(vxi->vx_namespace);
25088 +       current->namespace = vxi->vx_namespace;
25089 +       current->fs = fs;
25090 +       task_unlock(current);
25091 +
25092 +       put_namespace(old_ns);
25093 +       put_fs_struct(old_fs);
25094 +       return 0;
25095 +}
25096 +
25097 +int vx_set_namespace(struct vx_info *vxi, struct namespace *ns, struct fs_struct *fs)
25098 +{
25099 +       struct fs_struct *fs_copy;
25100 +
25101 +       if (vxi->vx_namespace)
25102 +               return -EPERM;
25103 +       if (!ns || !fs)
25104 +               return -EINVAL;
25105 +
25106 +       fs_copy = copy_fs_struct(fs);
25107 +       if (!fs_copy)
25108 +               return -ENOMEM;
25109 +
25110 +       get_namespace(ns);
25111 +       vxi->vx_namespace = ns;
25112 +       vxi->vx_fs = fs_copy;
25113 +       return 0;
25114 +}
25115 +
25116 +int vc_enter_namespace(struct vx_info *vxi, void __user *data)
25117 +{
25118 +       return vx_enter_namespace(vxi);
25119 +}
25120 +
25121 +int vc_set_namespace(struct vx_info *vxi, void __user *data)
25122 +{
25123 +       struct fs_struct *fs;
25124 +       struct namespace *ns;
25125 +       int ret;
25126 +
25127 +       task_lock(current);
25128 +       fs = current->fs;
25129 +       atomic_inc(&fs->count);
25130 +       ns = current->namespace;
25131 +       get_namespace(current->namespace);
25132 +       task_unlock(current);
25133 +
25134 +       ret = vx_set_namespace(vxi, ns, fs);
25135 +
25136 +       put_namespace(ns);
25137 +       put_fs_struct(fs);
25138 +       return ret;
25139 +}
25140 +
25141 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/network.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/network.c
25142 --- linux-2.6.17.11/kernel/vserver/network.c    1970-01-01 01:00:00 +0100
25143 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/network.c       2006-08-25 05:47:25 +0200
25144 @@ -0,0 +1,752 @@
25145 +/*
25146 + *  linux/kernel/vserver/network.c
25147 + *
25148 + *  Virtual Server: Network Support
25149 + *
25150 + *  Copyright (C) 2003-2006  Herbert Pötzl
25151 + *
25152 + *  V0.01  broken out from vcontext V0.05
25153 + *  V0.02  cleaned up implementation
25154 + *  V0.03  added equiv nx commands
25155 + *  V0.04  switch to RCU based hash
25156 + *  V0.05  and back to locking again
25157 + *  V0.06  changed vcmds to nxi arg
25158 + *
25159 + */
25160 +
25161 +#include <linux/slab.h>
25162 +#include <linux/rcupdate.h>
25163 +#include <net/tcp.h>
25164 +
25165 +#include <asm/errno.h>
25166 +#include <linux/vserver/network_cmd.h>
25167 +
25168 +
25169 +/*     __alloc_nx_info()
25170 +
25171 +       * allocate an initialized nx_info struct
25172 +       * doesn't make it visible (hash)                        */
25173 +
25174 +static struct nx_info *__alloc_nx_info(nid_t nid)
25175 +{
25176 +       struct nx_info *new = NULL;
25177 +
25178 +       vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
25179 +
25180 +       /* would this benefit from a slab cache? */
25181 +       new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
25182 +       if (!new)
25183 +               return 0;
25184 +
25185 +       memset (new, 0, sizeof(struct nx_info));
25186 +       new->nx_id = nid;
25187 +       INIT_HLIST_NODE(&new->nx_hlist);
25188 +       atomic_set(&new->nx_usecnt, 0);
25189 +       atomic_set(&new->nx_tasks, 0);
25190 +       new->nx_state = 0;
25191 +
25192 +       new->nx_flags = NXF_INIT_SET;
25193 +
25194 +       /* rest of init goes here */
25195 +
25196 +       vxdprintk(VXD_CBIT(nid, 0),
25197 +               "alloc_nx_info(%d) = %p", nid, new);
25198 +       return new;
25199 +}
25200 +
25201 +/*     __dealloc_nx_info()
25202 +
25203 +       * final disposal of nx_info                             */
25204 +
25205 +static void __dealloc_nx_info(struct nx_info *nxi)
25206 +{
25207 +       vxdprintk(VXD_CBIT(nid, 0),
25208 +               "dealloc_nx_info(%p)", nxi);
25209 +
25210 +       nxi->nx_hlist.next = LIST_POISON1;
25211 +       nxi->nx_id = -1;
25212 +
25213 +       BUG_ON(atomic_read(&nxi->nx_usecnt));
25214 +       BUG_ON(atomic_read(&nxi->nx_tasks));
25215 +
25216 +       nxi->nx_state |= NXS_RELEASED;
25217 +       kfree(nxi);
25218 +}
25219 +
25220 +static void __shutdown_nx_info(struct nx_info *nxi)
25221 +{
25222 +       nxi->nx_state |= NXS_SHUTDOWN;
25223 +       vs_net_change(nxi, VSC_NETDOWN);
25224 +}
25225 +
25226 +/*     exported stuff                                          */
25227 +
25228 +void free_nx_info(struct nx_info *nxi)
25229 +{
25230 +       /* context shutdown is mandatory */
25231 +       BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
25232 +
25233 +       /* context must not be hashed */
25234 +       BUG_ON(nxi->nx_state & NXS_HASHED);
25235 +
25236 +       BUG_ON(atomic_read(&nxi->nx_usecnt));
25237 +       BUG_ON(atomic_read(&nxi->nx_tasks));
25238 +
25239 +       __dealloc_nx_info(nxi);
25240 +}
25241 +
25242 +
25243 +/*     hash table for nx_info hash */
25244 +
25245 +#define NX_HASH_SIZE   13
25246 +
25247 +struct hlist_head nx_info_hash[NX_HASH_SIZE];
25248 +
25249 +static spinlock_t nx_info_hash_lock = SPIN_LOCK_UNLOCKED;
25250 +
25251 +
25252 +static inline unsigned int __hashval(nid_t nid)
25253 +{
25254 +       return (nid % NX_HASH_SIZE);
25255 +}
25256 +
25257 +
25258 +
25259 +/*     __hash_nx_info()
25260 +
25261 +       * add the nxi to the global hash table
25262 +       * requires the hash_lock to be held                     */
25263 +
25264 +static inline void __hash_nx_info(struct nx_info *nxi)
25265 +{
25266 +       struct hlist_head *head;
25267 +
25268 +       vxd_assert_lock(&nx_info_hash_lock);
25269 +       vxdprintk(VXD_CBIT(nid, 4),
25270 +               "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
25271 +
25272 +       /* context must not be hashed */
25273 +       BUG_ON(nx_info_state(nxi, NXS_HASHED));
25274 +
25275 +       nxi->nx_state |= NXS_HASHED;
25276 +       head = &nx_info_hash[__hashval(nxi->nx_id)];
25277 +       hlist_add_head(&nxi->nx_hlist, head);
25278 +}
25279 +
25280 +/*     __unhash_nx_info()
25281 +
25282 +       * remove the nxi from the global hash table
25283 +       * requires the hash_lock to be held                     */
25284 +
25285 +static inline void __unhash_nx_info(struct nx_info *nxi)
25286 +{
25287 +       vxd_assert_lock(&nx_info_hash_lock);
25288 +       vxdprintk(VXD_CBIT(nid, 4),
25289 +               "__unhash_nx_info: %p[#%d]", nxi, nxi->nx_id);
25290 +
25291 +       /* context must be hashed */
25292 +       BUG_ON(!nx_info_state(nxi, NXS_HASHED));
25293 +
25294 +       nxi->nx_state &= ~NXS_HASHED;
25295 +       hlist_del(&nxi->nx_hlist);
25296 +}
25297 +
25298 +
25299 +/*     __lookup_nx_info()
25300 +
25301 +       * requires the hash_lock to be held
25302 +       * doesn't increment the nx_refcnt                       */
25303 +
25304 +static inline struct nx_info *__lookup_nx_info(nid_t nid)
25305 +{
25306 +       struct hlist_head *head = &nx_info_hash[__hashval(nid)];
25307 +       struct hlist_node *pos;
25308 +       struct nx_info *nxi;
25309 +
25310 +       vxd_assert_lock(&nx_info_hash_lock);
25311 +       hlist_for_each(pos, head) {
25312 +               nxi = hlist_entry(pos, struct nx_info, nx_hlist);
25313 +
25314 +               if (nxi->nx_id == nid)
25315 +                       goto found;
25316 +       }
25317 +       nxi = NULL;
25318 +found:
25319 +       vxdprintk(VXD_CBIT(nid, 0),
25320 +               "__lookup_nx_info(#%u): %p[#%u]",
25321 +               nid, nxi, nxi?nxi->nx_id:0);
25322 +       return nxi;
25323 +}
25324 +
25325 +
25326 +/*     __nx_dynamic_id()
25327 +
25328 +       * find unused dynamic nid
25329 +       * requires the hash_lock to be held                     */
25330 +
25331 +static inline nid_t __nx_dynamic_id(void)
25332 +{
25333 +       static nid_t seq = MAX_N_CONTEXT;
25334 +       nid_t barrier = seq;
25335 +
25336 +       vxd_assert_lock(&nx_info_hash_lock);
25337 +       do {
25338 +               if (++seq > MAX_N_CONTEXT)
25339 +                       seq = MIN_D_CONTEXT;
25340 +               if (!__lookup_nx_info(seq)) {
25341 +                       vxdprintk(VXD_CBIT(nid, 4),
25342 +                               "__nx_dynamic_id: [#%d]", seq);
25343 +                       return seq;
25344 +               }
25345 +       } while (barrier != seq);
25346 +       return 0;
25347 +}
25348 +
25349 +/*     __create_nx_info()
25350 +
25351 +       * create the requested context
25352 +       * get() and hash it                                     */
25353 +
25354 +static struct nx_info * __create_nx_info(int id)
25355 +{
25356 +       struct nx_info *new, *nxi = NULL;
25357 +
25358 +       vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
25359 +
25360 +       if (!(new = __alloc_nx_info(id)))
25361 +               return ERR_PTR(-ENOMEM);
25362 +
25363 +       /* required to make dynamic xids unique */
25364 +       spin_lock(&nx_info_hash_lock);
25365 +
25366 +       /* dynamic context requested */
25367 +       if (id == NX_DYNAMIC_ID) {
25368 +#ifdef CONFIG_VSERVER_DYNAMIC_IDS
25369 +               id = __nx_dynamic_id();
25370 +               if (!id) {
25371 +                       printk(KERN_ERR "no dynamic context available.\n");
25372 +                       nxi = ERR_PTR(-EAGAIN);
25373 +                       goto out_unlock;
25374 +               }
25375 +               new->nx_id = id;
25376 +#else
25377 +               printk(KERN_ERR "dynamic contexts disabled.\n");
25378 +               nxi = ERR_PTR(-EINVAL);
25379 +               goto out_unlock;
25380 +#endif
25381 +       }
25382 +       /* static context requested */
25383 +       else if ((nxi = __lookup_nx_info(id))) {
25384 +               vxdprintk(VXD_CBIT(nid, 0),
25385 +                       "create_nx_info(%d) = %p (already there)", id, nxi);
25386 +               if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
25387 +                       nxi = ERR_PTR(-EBUSY);
25388 +               else
25389 +                       nxi = ERR_PTR(-EEXIST);
25390 +               goto out_unlock;
25391 +       }
25392 +       /* dynamic nid creation blocker */
25393 +       else if (id >= MIN_D_CONTEXT) {
25394 +               vxdprintk(VXD_CBIT(nid, 0),
25395 +                       "create_nx_info(%d) (dynamic rejected)", id);
25396 +               nxi = ERR_PTR(-EINVAL);
25397 +               goto out_unlock;
25398 +       }
25399 +
25400 +       /* new context */
25401 +       vxdprintk(VXD_CBIT(nid, 0),
25402 +               "create_nx_info(%d) = %p (new)", id, new);
25403 +       __hash_nx_info(get_nx_info(new));
25404 +       nxi = new, new = NULL;
25405 +
25406 +out_unlock:
25407 +       spin_unlock(&nx_info_hash_lock);
25408 +       if (new)
25409 +               __dealloc_nx_info(new);
25410 +       return nxi;
25411 +}
25412 +
25413 +
25414 +
25415 +/*     exported stuff                                          */
25416 +
25417 +
25418 +void unhash_nx_info(struct nx_info *nxi)
25419 +{
25420 +       __shutdown_nx_info(nxi);
25421 +       spin_lock(&nx_info_hash_lock);
25422 +       __unhash_nx_info(nxi);
25423 +       spin_unlock(&nx_info_hash_lock);
25424 +}
25425 +
25426 +#ifdef  CONFIG_VSERVER_LEGACYNET
25427 +
25428 +struct nx_info *create_nx_info(void)
25429 +{
25430 +       return __create_nx_info(NX_DYNAMIC_ID);
25431 +}
25432 +
25433 +#endif
25434 +
25435 +/*     lookup_nx_info()
25436 +
25437 +       * search for a nx_info and get() it
25438 +       * negative id means current                             */
25439 +
25440 +struct nx_info *lookup_nx_info(int id)
25441 +{
25442 +       struct nx_info *nxi = NULL;
25443 +
25444 +       if (id < 0) {
25445 +               nxi = get_nx_info(current->nx_info);
25446 +       } else if (id > 1) {
25447 +               spin_lock(&nx_info_hash_lock);
25448 +               nxi = get_nx_info(__lookup_nx_info(id));
25449 +               spin_unlock(&nx_info_hash_lock);
25450 +       }
25451 +       return nxi;
25452 +}
25453 +
25454 +/*     nid_is_hashed()
25455 +
25456 +       * verify that nid is still hashed                       */
25457 +
25458 +int nid_is_hashed(nid_t nid)
25459 +{
25460 +       int hashed;
25461 +
25462 +       spin_lock(&nx_info_hash_lock);
25463 +       hashed = (__lookup_nx_info(nid) != NULL);
25464 +       spin_unlock(&nx_info_hash_lock);
25465 +       return hashed;
25466 +}
25467 +
25468 +
25469 +#ifdef CONFIG_PROC_FS
25470 +
25471 +/*     get_nid_list()
25472 +
25473 +       * get a subset of hashed nids for proc
25474 +       * assumes size is at least one                          */
25475 +
25476 +int get_nid_list(int index, unsigned int *nids, int size)
25477 +{
25478 +       int hindex, nr_nids = 0;
25479 +
25480 +       /* only show current and children */
25481 +       if (!nx_check(0, VX_ADMIN|VX_WATCH)) {
25482 +               if (index > 0)
25483 +                       return 0;
25484 +               nids[nr_nids] = nx_current_nid();
25485 +               return 1;
25486 +       }
25487 +
25488 +       for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
25489 +               struct hlist_head *head = &nx_info_hash[hindex];
25490 +               struct hlist_node *pos;
25491 +
25492 +               spin_lock(&nx_info_hash_lock);
25493 +               hlist_for_each(pos, head) {
25494 +                       struct nx_info *nxi;
25495 +
25496 +                       if (--index > 0)
25497 +                               continue;
25498 +
25499 +                       nxi = hlist_entry(pos, struct nx_info, nx_hlist);
25500 +                       nids[nr_nids] = nxi->nx_id;
25501 +                       if (++nr_nids >= size) {
25502 +                               spin_unlock(&nx_info_hash_lock);
25503 +                               goto out;
25504 +                       }
25505 +               }
25506 +               /* keep the lock time short */
25507 +               spin_unlock(&nx_info_hash_lock);
25508 +       }
25509 +out:
25510 +       return nr_nids;
25511 +}
25512 +#endif
25513 +
25514 +
25515 +/*
25516 + *     migrate task to new network
25517 + *     gets nxi, puts old_nxi on change
25518 + */
25519 +
25520 +int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
25521 +{
25522 +       struct nx_info *old_nxi;
25523 +       int ret = 0;
25524 +
25525 +       if (!p || !nxi)
25526 +               BUG();
25527 +
25528 +       vxdprintk(VXD_CBIT(nid, 5),
25529 +               "nx_migrate_task(%p,%p[#%d.%d.%d])",
25530 +               p, nxi, nxi->nx_id,
25531 +               atomic_read(&nxi->nx_usecnt),
25532 +               atomic_read(&nxi->nx_tasks));
25533 +
25534 +       if (nx_info_flags(nxi, NXF_INFO_LOCK, 0))
25535 +               return -EACCES;
25536 +
25537 +       /* maybe disallow this completely? */
25538 +       old_nxi = task_get_nx_info(p);
25539 +       if (old_nxi == nxi)
25540 +               goto out;
25541 +
25542 +       task_lock(p);
25543 +       if (old_nxi)
25544 +               clr_nx_info(&p->nx_info);
25545 +       claim_nx_info(nxi, p);
25546 +       set_nx_info(&p->nx_info, nxi);
25547 +       p->nid = nxi->nx_id;
25548 +       task_unlock(p);
25549 +
25550 +       vxdprintk(VXD_CBIT(nid, 5),
25551 +               "moved task %p into nxi:%p[#%d]",
25552 +               p, nxi, nxi->nx_id);
25553 +
25554 +       if (old_nxi)
25555 +               release_nx_info(old_nxi, p);
25556 +out:
25557 +       put_nx_info(old_nxi);
25558 +       return ret;
25559 +}
25560 +
25561 +
25562 +#ifdef CONFIG_INET
25563 +
25564 +#include <linux/netdevice.h>
25565 +#include <linux/inetdevice.h>
25566 +
25567 +int ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
25568 +{
25569 +       if (!nxi)
25570 +               return 1;
25571 +       if (!ifa)
25572 +               return 0;
25573 +       return addr_in_nx_info(nxi, ifa->ifa_local);
25574 +}
25575 +
25576 +int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
25577 +{
25578 +       struct in_device *in_dev;
25579 +       struct in_ifaddr **ifap;
25580 +       struct in_ifaddr *ifa;
25581 +       int ret = 0;
25582 +
25583 +       if (!nxi)
25584 +               return 1;
25585 +
25586 +       in_dev = in_dev_get(dev);
25587 +       if (!in_dev)
25588 +               goto out;
25589 +
25590 +       for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
25591 +               ifap = &ifa->ifa_next) {
25592 +               if (addr_in_nx_info(nxi, ifa->ifa_local)) {
25593 +                       ret = 1;
25594 +                       break;
25595 +               }
25596 +       }
25597 +       in_dev_put(in_dev);
25598 +out:
25599 +       return ret;
25600 +}
25601 +
25602 +/*
25603 + *     check if address is covered by socket
25604 + *
25605 + *     sk:     the socket to check against
25606 + *     addr:   the address in question (must be != 0)
25607 + */
25608 +static inline int __addr_in_socket(struct sock *sk, uint32_t addr)
25609 +{
25610 +       struct nx_info *nxi = sk->sk_nx_info;
25611 +       uint32_t saddr = inet_rcv_saddr(sk);
25612 +
25613 +       vxdprintk(VXD_CBIT(net, 5),
25614 +               "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx",
25615 +               sk, VXD_QUAD(addr), nxi, VXD_QUAD(saddr), sk->sk_socket,
25616 +               (sk->sk_socket?sk->sk_socket->flags:0));
25617 +
25618 +       if (saddr) {
25619 +               /* direct address match */
25620 +               return (saddr == addr);
25621 +       } else if (nxi) {
25622 +               /* match against nx_info */
25623 +               return addr_in_nx_info(nxi, addr);
25624 +       } else {
25625 +               /* unrestricted any socket */
25626 +               return 1;
25627 +       }
25628 +}
25629 +
25630 +
25631 +int nx_addr_conflict(struct nx_info *nxi, uint32_t addr, struct sock *sk)
25632 +{
25633 +       vxdprintk(VXD_CBIT(net, 2),
25634 +               "nx_addr_conflict(%p,%p) %d.%d,%d.%d",
25635 +               nxi, sk, VXD_QUAD(addr));
25636 +
25637 +       if (addr) {
25638 +               /* check real address */
25639 +               return __addr_in_socket(sk, addr);
25640 +       } else if (nxi) {
25641 +               /* check against nx_info */
25642 +               int i, n = nxi->nbipv4;
25643 +
25644 +               for (i=0; i<n; i++)
25645 +                       if (__addr_in_socket(sk, nxi->ipv4[i]))
25646 +                               return 1;
25647 +               return 0;
25648 +       } else {
25649 +               /* check against any */
25650 +               return 1;
25651 +       }
25652 +}
25653 +
25654 +#endif /* CONFIG_INET */
25655 +
25656 +void nx_set_persistent(struct nx_info *nxi)
25657 +{
25658 +       get_nx_info(nxi);
25659 +       claim_nx_info(nxi, current);
25660 +}
25661 +
25662 +void nx_clear_persistent(struct nx_info *nxi)
25663 +{
25664 +       vxdprintk(VXD_CBIT(nid, 6),
25665 +               "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
25666 +
25667 +       release_nx_info(nxi, current);
25668 +       put_nx_info(nxi);
25669 +}
25670 +
25671 +void nx_update_persistent(struct nx_info *nxi)
25672 +{
25673 +       if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
25674 +               nx_set_persistent(nxi);
25675 +       else
25676 +               nx_clear_persistent(nxi);
25677 +}
25678 +
25679 +/* vserver syscall commands below here */
25680 +
25681 +/* taks nid and nx_info functions */
25682 +
25683 +#include <asm/uaccess.h>
25684 +
25685 +
25686 +int vc_task_nid(uint32_t id, void __user *data)
25687 +{
25688 +       nid_t nid;
25689 +
25690 +       if (id) {
25691 +               struct task_struct *tsk;
25692 +
25693 +               if (!vx_check(0, VX_ADMIN|VX_WATCH))
25694 +                       return -EPERM;
25695 +
25696 +               read_lock(&tasklist_lock);
25697 +               tsk = find_task_by_real_pid(id);
25698 +               nid = (tsk) ? tsk->nid : -ESRCH;
25699 +               read_unlock(&tasklist_lock);
25700 +       }
25701 +       else
25702 +               nid = nx_current_nid();
25703 +       return nid;
25704 +}
25705 +
25706 +
25707 +int vc_nx_info(struct nx_info *nxi, void __user *data)
25708 +{
25709 +       struct vcmd_nx_info_v0 vc_data;
25710 +
25711 +       vc_data.nid = nxi->nx_id;
25712 +
25713 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25714 +               return -EFAULT;
25715 +       return 0;
25716 +}
25717 +
25718 +
25719 +/* network functions */
25720 +
25721 +int vc_net_create(uint32_t nid, void __user *data)
25722 +{
25723 +       struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
25724 +       struct nx_info *new_nxi;
25725 +       int ret;
25726 +
25727 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
25728 +               return -EFAULT;
25729 +
25730 +       if ((nid > MAX_S_CONTEXT) && (nid != VX_DYNAMIC_ID))
25731 +               return -EINVAL;
25732 +       if (nid < 2)
25733 +               return -EINVAL;
25734 +
25735 +       new_nxi = __create_nx_info(nid);
25736 +       if (IS_ERR(new_nxi))
25737 +               return PTR_ERR(new_nxi);
25738 +
25739 +       /* initial flags */
25740 +       new_nxi->nx_flags = vc_data.flagword;
25741 +
25742 +       /* get a reference for persistent contexts */
25743 +       if ((vc_data.flagword & NXF_PERSISTENT))
25744 +               nx_set_persistent(new_nxi);
25745 +
25746 +       ret = -ENOEXEC;
25747 +       if (vs_net_change(new_nxi, VSC_NETUP))
25748 +               goto out_unhash;
25749 +       ret = nx_migrate_task(current, new_nxi);
25750 +       if (!ret) {
25751 +               /* return context id on success */
25752 +               ret = new_nxi->nx_id;
25753 +               goto out;
25754 +       }
25755 +out_unhash:
25756 +       /* prepare for context disposal */
25757 +       new_nxi->nx_state |= NXS_SHUTDOWN;
25758 +       if ((vc_data.flagword & NXF_PERSISTENT))
25759 +               nx_clear_persistent(new_nxi);
25760 +       __unhash_nx_info(new_nxi);
25761 +out:
25762 +       put_nx_info(new_nxi);
25763 +       return ret;
25764 +}
25765 +
25766 +
25767 +int vc_net_migrate(struct nx_info *nxi, void __user *data)
25768 +{
25769 +       return nx_migrate_task(current, nxi);
25770 +}
25771 +
25772 +int vc_net_add(struct nx_info *nxi, void __user *data)
25773 +{
25774 +       struct vcmd_net_addr_v0 vc_data;
25775 +       int index, pos, ret = 0;
25776 +
25777 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
25778 +               return -EFAULT;
25779 +
25780 +       switch (vc_data.type) {
25781 +       case NXA_TYPE_IPV4:
25782 +               if ((vc_data.count < 1) || (vc_data.count > 4))
25783 +                       return -EINVAL;
25784 +               break;
25785 +
25786 +       default:
25787 +               break;
25788 +       }
25789 +
25790 +       switch (vc_data.type) {
25791 +       case NXA_TYPE_IPV4:
25792 +               index = 0;
25793 +               while ((index < vc_data.count) &&
25794 +                       ((pos = nxi->nbipv4) < NB_IPV4ROOT)) {
25795 +                       nxi->ipv4[pos] = vc_data.ip[index];
25796 +                       nxi->mask[pos] = vc_data.mask[index];
25797 +                       index++;
25798 +                       nxi->nbipv4++;
25799 +               }
25800 +               ret = index;
25801 +               break;
25802 +
25803 +       case NXA_TYPE_IPV4|NXA_MOD_BCAST:
25804 +               nxi->v4_bcast = vc_data.ip[0];
25805 +               ret = 1;
25806 +               break;
25807 +
25808 +       default:
25809 +               ret = -EINVAL;
25810 +               break;
25811 +       }
25812 +       return ret;
25813 +}
25814 +
25815 +int vc_net_remove(struct nx_info * nxi, void __user *data)
25816 +{
25817 +       struct vcmd_net_addr_v0 vc_data;
25818 +
25819 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
25820 +               return -EFAULT;
25821 +
25822 +       switch (vc_data.type) {
25823 +       case NXA_TYPE_ANY:
25824 +               nxi->nbipv4 = 0;
25825 +               break;
25826 +
25827 +       default:
25828 +               return -EINVAL;
25829 +       }
25830 +       return 0;
25831 +}
25832 +
25833 +int vc_get_nflags(struct nx_info *nxi, void __user *data)
25834 +{
25835 +       struct vcmd_net_flags_v0 vc_data;
25836 +
25837 +       vc_data.flagword = nxi->nx_flags;
25838 +
25839 +       /* special STATE flag handling */
25840 +       vc_data.mask = vx_mask_flags(~0UL, nxi->nx_flags, NXF_ONE_TIME);
25841 +
25842 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25843 +               return -EFAULT;
25844 +       return 0;
25845 +}
25846 +
25847 +int vc_set_nflags(struct nx_info *nxi, void __user *data)
25848 +{
25849 +       struct vcmd_net_flags_v0 vc_data;
25850 +       uint64_t mask, trigger;
25851 +
25852 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25853 +               return -EFAULT;
25854 +
25855 +       /* special STATE flag handling */
25856 +       mask = vx_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
25857 +       trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
25858 +
25859 +       nxi->nx_flags = vx_mask_flags(nxi->nx_flags,
25860 +               vc_data.flagword, mask);
25861 +       if (trigger & NXF_PERSISTENT)
25862 +               nx_update_persistent(nxi);
25863 +
25864 +       return 0;
25865 +}
25866 +
25867 +int vc_get_ncaps(struct nx_info *nxi, void __user *data)
25868 +{
25869 +       struct vcmd_net_caps_v0 vc_data;
25870 +
25871 +       vc_data.ncaps = nxi->nx_ncaps;
25872 +       vc_data.cmask = ~0UL;
25873 +
25874 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25875 +               return -EFAULT;
25876 +       return 0;
25877 +}
25878 +
25879 +int vc_set_ncaps(struct nx_info *nxi, void __user *data)
25880 +{
25881 +       struct vcmd_net_caps_v0 vc_data;
25882 +
25883 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25884 +               return -EFAULT;
25885 +
25886 +       nxi->nx_ncaps = vx_mask_flags(nxi->nx_ncaps,
25887 +               vc_data.ncaps, vc_data.cmask);
25888 +       return 0;
25889 +}
25890 +
25891 +
25892 +#include <linux/module.h>
25893 +
25894 +EXPORT_SYMBOL_GPL(free_nx_info);
25895 +EXPORT_SYMBOL_GPL(unhash_nx_info);
25896 +
25897 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/proc.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/proc.c
25898 --- linux-2.6.17.11/kernel/vserver/proc.c       1970-01-01 01:00:00 +0100
25899 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/proc.c  2006-08-19 19:56:39 +0200
25900 @@ -0,0 +1,919 @@
25901 +/*
25902 + *  linux/kernel/vserver/proc.c
25903 + *
25904 + *  Virtual Context Support
25905 + *
25906 + *  Copyright (C) 2003-2005  Herbert Pötzl
25907 + *
25908 + *  V0.01  basic structure
25909 + *  V0.02  adaptation vs1.3.0
25910 + *  V0.03  proc permissions
25911 + *  V0.04  locking/generic
25912 + *  V0.05  next generation procfs
25913 + *  V0.06  inode validation
25914 + *  V0.07  generic rewrite vid
25915 + *
25916 + */
25917 +
25918 +#include <linux/errno.h>
25919 +#include <linux/proc_fs.h>
25920 +#include <linux/sched.h>
25921 +#include <linux/vs_context.h>
25922 +#include <linux/vs_network.h>
25923 +#include <linux/vs_cvirt.h>
25924 +
25925 +#include <linux/vserver/switch.h>
25926 +#include <linux/vserver/global.h>
25927 +
25928 +#include <asm/uaccess.h>
25929 +#include <asm/unistd.h>
25930 +
25931 +#include "cvirt_proc.h"
25932 +#include "cacct_proc.h"
25933 +#include "limit_proc.h"
25934 +#include "sched_proc.h"
25935 +#include "vci_config.h"
25936 +
25937 +static struct proc_dir_entry *proc_virtual;
25938 +
25939 +static struct proc_dir_entry *proc_vnet;
25940 +
25941 +
25942 +enum vid_directory_inos {
25943 +       PROC_XID_INO = 32,
25944 +       PROC_XID_INFO,
25945 +       PROC_XID_STATUS,
25946 +       PROC_XID_LIMIT,
25947 +       PROC_XID_SCHED,
25948 +       PROC_XID_CVIRT,
25949 +       PROC_XID_CACCT,
25950 +
25951 +       PROC_NID_INO = 64,
25952 +       PROC_NID_INFO,
25953 +       PROC_NID_STATUS,
25954 +};
25955 +
25956 +#define PROC_VID_MASK  0x60
25957 +
25958 +
25959 +/* first the actual feeds */
25960 +
25961 +
25962 +static int proc_virtual_info(int vid, char *buffer)
25963 +{
25964 +       return sprintf(buffer,
25965 +               "VCIVersion:\t%04x:%04x\n"
25966 +               "VCISyscall:\t%d\n"
25967 +               "VCIKernel:\t%08x\n"
25968 +               ,VCI_VERSION >> 16
25969 +               ,VCI_VERSION & 0xFFFF
25970 +               ,__NR_vserver
25971 +               ,vci_kernel_config()
25972 +               );
25973 +}
25974 +
25975 +static int proc_virtual_status(int vid, char *buffer)
25976 +{
25977 +       return sprintf(buffer,
25978 +               "#CTotal:\t%d\n"
25979 +               "#CActive:\t%d\n"
25980 +               ,atomic_read(&vx_global_ctotal)
25981 +               ,atomic_read(&vx_global_cactive)
25982 +               );
25983 +}
25984 +
25985 +
25986 +int proc_xid_info (int vid, char *buffer)
25987 +{
25988 +       struct vx_info *vxi;
25989 +       int length;
25990 +
25991 +       vxi = lookup_vx_info(vid);
25992 +       if (!vxi)
25993 +               return 0;
25994 +       length = sprintf(buffer,
25995 +               "ID:\t%d\n"
25996 +               "Info:\t%p\n"
25997 +               "Init:\t%d\n"
25998 +               ,vxi->vx_id
25999 +               ,vxi
26000 +               ,vxi->vx_initpid
26001 +               );
26002 +       put_vx_info(vxi);
26003 +       return length;
26004 +}
26005 +
26006 +int proc_xid_status (int vid, char *buffer)
26007 +{
26008 +       struct vx_info *vxi;
26009 +       int length;
26010 +
26011 +       vxi = lookup_vx_info(vid);
26012 +       if (!vxi)
26013 +               return 0;
26014 +       length = sprintf(buffer,
26015 +               "UseCnt:\t%d\n"
26016 +               "Tasks:\t%d\n"
26017 +               "Flags:\t%016llx\n"
26018 +               "BCaps:\t%016llx\n"
26019 +               "CCaps:\t%016llx\n"
26020 +//             "Ticks:\t%d\n"
26021 +               ,atomic_read(&vxi->vx_usecnt)
26022 +               ,atomic_read(&vxi->vx_tasks)
26023 +               ,(unsigned long long)vxi->vx_flags
26024 +               ,(unsigned long long)vxi->vx_bcaps
26025 +               ,(unsigned long long)vxi->vx_ccaps
26026 +//             ,atomic_read(&vxi->limit.ticks)
26027 +               );
26028 +       put_vx_info(vxi);
26029 +       return length;
26030 +}
26031 +
26032 +int proc_xid_limit (int vid, char *buffer)
26033 +{
26034 +       struct vx_info *vxi;
26035 +       int length;
26036 +
26037 +       vxi = lookup_vx_info(vid);
26038 +       if (!vxi)
26039 +               return 0;
26040 +       length = vx_info_proc_limit(&vxi->limit, buffer);
26041 +       put_vx_info(vxi);
26042 +       return length;
26043 +}
26044 +
26045 +int proc_xid_sched (int vid, char *buffer)
26046 +{
26047 +       struct vx_info *vxi;
26048 +       int cpu, length;
26049 +
26050 +       vxi = lookup_vx_info(vid);
26051 +       if (!vxi)
26052 +               return 0;
26053 +       length = vx_info_proc_sched(&vxi->sched, buffer);
26054 +       for_each_online_cpu(cpu) {
26055 +               length += vx_info_proc_sched_pc(
26056 +                       &vx_per_cpu(vxi, sched_pc, cpu),
26057 +                       buffer + length, cpu);
26058 +       }
26059 +       put_vx_info(vxi);
26060 +       return length;
26061 +}
26062 +
26063 +int proc_xid_cvirt (int vid, char *buffer)
26064 +{
26065 +       struct vx_info *vxi;
26066 +       int cpu, length;
26067 +
26068 +       vxi = lookup_vx_info(vid);
26069 +       if (!vxi)
26070 +               return 0;
26071 +       vx_update_load(vxi);
26072 +       length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
26073 +       for_each_online_cpu(cpu) {
26074 +               length += vx_info_proc_cvirt_pc(
26075 +                       &vx_per_cpu(vxi, cvirt_pc, cpu),
26076 +                       buffer + length, cpu);
26077 +       }
26078 +       put_vx_info(vxi);
26079 +       return length;
26080 +}
26081 +
26082 +int proc_xid_cacct (int vid, char *buffer)
26083 +{
26084 +       struct vx_info *vxi;
26085 +       int length;
26086 +
26087 +       vxi = lookup_vx_info(vid);
26088 +       if (!vxi)
26089 +               return 0;
26090 +       length = vx_info_proc_cacct(&vxi->cacct, buffer);
26091 +       put_vx_info(vxi);
26092 +       return length;
26093 +}
26094 +
26095 +
26096 +static int proc_vnet_info(int vid, char *buffer)
26097 +{
26098 +       return sprintf(buffer,
26099 +               "VCIVersion:\t%04x:%04x\n"
26100 +               "VCISyscall:\t%d\n"
26101 +               ,VCI_VERSION >> 16
26102 +               ,VCI_VERSION & 0xFFFF
26103 +               ,__NR_vserver
26104 +               );
26105 +}
26106 +
26107 +
26108 +int proc_nid_info (int vid, char *buffer)
26109 +{
26110 +       struct nx_info *nxi;
26111 +       int length, i;
26112 +
26113 +       nxi = lookup_nx_info(vid);
26114 +       if (!nxi)
26115 +               return 0;
26116 +       length = sprintf(buffer,
26117 +               "ID:\t%d\n"
26118 +               "Info:\t%p\n"
26119 +               ,nxi->nx_id
26120 +               ,nxi
26121 +               );
26122 +       for (i=0; i<nxi->nbipv4; i++) {
26123 +               length += sprintf(buffer + length,
26124 +                       "%d:\t" NIPQUAD_FMT "/" NIPQUAD_FMT "\n", i,
26125 +                       NIPQUAD(nxi->ipv4[i]), NIPQUAD(nxi->mask[i]));
26126 +       }
26127 +       put_nx_info(nxi);
26128 +       return length;
26129 +}
26130 +
26131 +int proc_nid_status (int vid, char *buffer)
26132 +{
26133 +       struct nx_info *nxi;
26134 +       int length;
26135 +
26136 +       nxi = lookup_nx_info(vid);
26137 +       if (!nxi)
26138 +               return 0;
26139 +       length = sprintf(buffer,
26140 +               "UseCnt:\t%d\n"
26141 +               "Tasks:\t%d\n"
26142 +               ,atomic_read(&nxi->nx_usecnt)
26143 +               ,atomic_read(&nxi->nx_tasks)
26144 +               );
26145 +       put_nx_info(nxi);
26146 +       return length;
26147 +}
26148 +
26149 +/* here the inode helpers */
26150 +
26151 +
26152 +#define fake_ino(id,nr) (((nr) & 0xFFFF) | \
26153 +                       (((id) & 0xFFFF) << 16))
26154 +
26155 +#define inode_vid(i)   (((i)->i_ino >> 16) & 0xFFFF)
26156 +#define inode_type(i)  ((i)->i_ino & 0xFFFF)
26157 +
26158 +#define MAX_MULBY10    ((~0U-9)/10)
26159 +
26160 +
26161 +static struct inode *proc_vid_make_inode(struct super_block * sb,
26162 +       int vid, int ino)
26163 +{
26164 +       struct inode *inode = new_inode(sb);
26165 +
26166 +       if (!inode)
26167 +               goto out;
26168 +
26169 +       inode->i_mtime = inode->i_atime =
26170 +               inode->i_ctime = CURRENT_TIME;
26171 +       inode->i_ino = fake_ino(vid, ino);
26172 +
26173 +       inode->i_uid = 0;
26174 +       inode->i_gid = 0;
26175 +out:
26176 +       return inode;
26177 +}
26178 +
26179 +static int proc_vid_revalidate(struct dentry * dentry, struct nameidata *nd)
26180 +{
26181 +       struct inode * inode = dentry->d_inode;
26182 +       int vid, hashed=0;
26183 +
26184 +       vid = inode_vid(inode);
26185 +       switch (inode_type(inode) & PROC_VID_MASK) {
26186 +               case PROC_XID_INO:
26187 +                       hashed = xid_is_hashed(vid);
26188 +                       break;
26189 +               case PROC_NID_INO:
26190 +                       hashed = nid_is_hashed(vid);
26191 +                       break;
26192 +       }
26193 +       if (hashed)
26194 +               return 1;
26195 +       d_drop(dentry);
26196 +       return 0;
26197 +}
26198 +
26199 +
26200 +#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
26201 +
26202 +static ssize_t proc_vid_info_read(struct file * file, char __user * buf,
26203 +                         size_t count, loff_t *ppos)
26204 +{
26205 +       struct inode * inode = file->f_dentry->d_inode;
26206 +       unsigned long page;
26207 +       ssize_t length;
26208 +       int vid;
26209 +
26210 +       if (count > PROC_BLOCK_SIZE)
26211 +               count = PROC_BLOCK_SIZE;
26212 +       if (!(page = __get_free_page(GFP_KERNEL)))
26213 +               return -ENOMEM;
26214 +
26215 +       vid = inode_vid(inode);
26216 +       length = PROC_I(inode)->op.proc_vid_read(vid, (char*)page);
26217 +
26218 +       if (length >= 0)
26219 +               length = simple_read_from_buffer(buf, count, ppos,
26220 +                       (char *)page, length);
26221 +       free_page(page);
26222 +       return length;
26223 +}
26224 +
26225 +
26226 +
26227 +
26228 +
26229 +/* here comes the lower level (vid) */
26230 +
26231 +static struct file_operations proc_vid_info_file_operations = {
26232 +       .read =         proc_vid_info_read,
26233 +};
26234 +
26235 +static struct dentry_operations proc_vid_dentry_operations = {
26236 +       .d_revalidate = proc_vid_revalidate,
26237 +};
26238 +
26239 +
26240 +struct vid_entry {
26241 +       int type;
26242 +       int len;
26243 +       char *name;
26244 +       mode_t mode;
26245 +};
26246 +
26247 +#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)}
26248 +
26249 +static struct vid_entry vx_base_stuff[] = {
26250 +       E(PROC_XID_INFO,        "info",         S_IFREG|S_IRUGO),
26251 +       E(PROC_XID_STATUS,      "status",       S_IFREG|S_IRUGO),
26252 +       E(PROC_XID_LIMIT,       "limit",        S_IFREG|S_IRUGO),
26253 +       E(PROC_XID_SCHED,       "sched",        S_IFREG|S_IRUGO),
26254 +       E(PROC_XID_CVIRT,       "cvirt",        S_IFREG|S_IRUGO),
26255 +       E(PROC_XID_CACCT,       "cacct",        S_IFREG|S_IRUGO),
26256 +       {0,0,NULL,0}
26257 +};
26258 +
26259 +static struct vid_entry vn_base_stuff[] = {
26260 +       E(PROC_NID_INFO,        "info",         S_IFREG|S_IRUGO),
26261 +       E(PROC_NID_STATUS,      "status",       S_IFREG|S_IRUGO),
26262 +       {0,0,NULL,0}
26263 +};
26264 +
26265 +
26266 +
26267 +static struct dentry *proc_vid_lookup(struct inode *dir,
26268 +       struct dentry *dentry, struct nameidata *nd)
26269 +{
26270 +       struct inode *inode;
26271 +       struct vid_entry *p;
26272 +       int error;
26273 +
26274 +       error = -ENOENT;
26275 +       inode = NULL;
26276 +
26277 +       switch (inode_type(dir)) {
26278 +               case PROC_XID_INO:
26279 +                       p = vx_base_stuff;
26280 +                       break;
26281 +               case PROC_NID_INO:
26282 +                       p = vn_base_stuff;
26283 +                       break;
26284 +               default:
26285 +                       goto out;
26286 +       }
26287 +
26288 +       for (; p->name; p++) {
26289 +               if (p->len != dentry->d_name.len)
26290 +                       continue;
26291 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
26292 +                       break;
26293 +       }
26294 +       if (!p->name)
26295 +               goto out;
26296 +
26297 +       error = -EINVAL;
26298 +       inode = proc_vid_make_inode(dir->i_sb, inode_vid(dir), p->type);
26299 +       if (!inode)
26300 +               goto out;
26301 +
26302 +       switch(p->type) {
26303 +       case PROC_XID_INFO:
26304 +               PROC_I(inode)->op.proc_vid_read = proc_xid_info;
26305 +               break;
26306 +       case PROC_XID_STATUS:
26307 +               PROC_I(inode)->op.proc_vid_read = proc_xid_status;
26308 +               break;
26309 +       case PROC_XID_LIMIT:
26310 +               PROC_I(inode)->op.proc_vid_read = proc_xid_limit;
26311 +               break;
26312 +       case PROC_XID_SCHED:
26313 +               PROC_I(inode)->op.proc_vid_read = proc_xid_sched;
26314 +               break;
26315 +       case PROC_XID_CVIRT:
26316 +               PROC_I(inode)->op.proc_vid_read = proc_xid_cvirt;
26317 +               break;
26318 +       case PROC_XID_CACCT:
26319 +               PROC_I(inode)->op.proc_vid_read = proc_xid_cacct;
26320 +               break;
26321 +
26322 +       case PROC_NID_INFO:
26323 +               PROC_I(inode)->op.proc_vid_read = proc_nid_info;
26324 +               break;
26325 +       case PROC_NID_STATUS:
26326 +               PROC_I(inode)->op.proc_vid_read = proc_nid_status;
26327 +               break;
26328 +
26329 +       default:
26330 +               printk("procfs: impossible type (%d)",p->type);
26331 +               iput(inode);
26332 +               return ERR_PTR(-EINVAL);
26333 +       }
26334 +       inode->i_mode = p->mode;
26335 +       inode->i_fop = &proc_vid_info_file_operations;
26336 +       inode->i_nlink = 1;
26337 +       inode->i_flags|=S_IMMUTABLE;
26338 +
26339 +       dentry->d_op = &proc_vid_dentry_operations;
26340 +       d_add(dentry, inode);
26341 +       error = 0;
26342 +out:
26343 +       return ERR_PTR(error);
26344 +}
26345 +
26346 +
26347 +static int proc_vid_readdir(struct file * filp,
26348 +       void * dirent, filldir_t filldir)
26349 +{
26350 +       int i, size;
26351 +       struct inode *inode = filp->f_dentry->d_inode;
26352 +       struct vid_entry *p;
26353 +
26354 +       i = filp->f_pos;
26355 +       switch (i) {
26356 +       case 0:
26357 +               if (filldir(dirent, ".", 1, i,
26358 +                       inode->i_ino, DT_DIR) < 0)
26359 +                       return 0;
26360 +               i++;
26361 +               filp->f_pos++;
26362 +               /* fall through */
26363 +       case 1:
26364 +               if (filldir(dirent, "..", 2, i,
26365 +                       PROC_ROOT_INO, DT_DIR) < 0)
26366 +                       return 0;
26367 +               i++;
26368 +               filp->f_pos++;
26369 +               /* fall through */
26370 +       default:
26371 +               i -= 2;
26372 +               switch (inode_type(inode)) {
26373 +               case PROC_XID_INO:
26374 +                       size = sizeof(vx_base_stuff);
26375 +                       p = vx_base_stuff + i;
26376 +                       break;
26377 +               case PROC_NID_INO:
26378 +                       size = sizeof(vn_base_stuff);
26379 +                       p = vn_base_stuff + i;
26380 +                       break;
26381 +               default:
26382 +                       return 1;
26383 +               }
26384 +               if (i >= size/sizeof(struct vid_entry))
26385 +                       return 1;
26386 +               while (p->name) {
26387 +                       if (filldir(dirent, p->name, p->len,
26388 +                               filp->f_pos, fake_ino(inode_vid(inode),
26389 +                               p->type), p->mode >> 12) < 0)
26390 +                               return 0;
26391 +                       filp->f_pos++;
26392 +                       p++;
26393 +               }
26394 +       }
26395 +       return 1;
26396 +}
26397 +
26398 +
26399 +
26400 +
26401 +/* now the upper level (virtual) */
26402 +
26403 +static struct file_operations proc_vid_file_operations = {
26404 +       .read =         generic_read_dir,
26405 +       .readdir =      proc_vid_readdir,
26406 +};
26407 +
26408 +static struct inode_operations proc_vid_inode_operations = {
26409 +       .lookup =       proc_vid_lookup,
26410 +};
26411 +
26412 +
26413 +
26414 +static __inline__ int atovid(const char *str, int len)
26415 +{
26416 +       int vid, c;
26417 +
26418 +       vid = 0;
26419 +       while (len-- > 0) {
26420 +               c = *str - '0';
26421 +               str++;
26422 +               if (c > 9)
26423 +                       return -1;
26424 +               if (vid >= MAX_MULBY10)
26425 +                       return -1;
26426 +               vid *= 10;
26427 +               vid += c;
26428 +               if (!vid)
26429 +                       return -1;
26430 +       }
26431 +       return vid;
26432 +}
26433 +
26434 +static __inline__ unsigned long atoaddr(const char *str, int len)
26435 +{
26436 +       unsigned long addr, c;
26437 +
26438 +       addr = 0;
26439 +       while (len-- > 0) {
26440 +               c = *str - '0';
26441 +               if (c > 9)
26442 +                       c -= 'A'-'0'+10;
26443 +               if (c > 15)
26444 +                       c -= 'a'-'A';
26445 +               if (c > 15)
26446 +                       return -1;
26447 +               str++;
26448 +               if (addr >= ((1 << 28) - 1))
26449 +                       return -1;
26450 +               addr = (addr << 4) | c;
26451 +               if (!addr)
26452 +                       return -1;
26453 +       }
26454 +       return addr;
26455 +}
26456 +
26457 +
26458 +struct dentry *proc_virtual_lookup(struct inode *dir,
26459 +       struct dentry * dentry, struct nameidata *nd)
26460 +{
26461 +       int xid, len, ret;
26462 +       struct vx_info *vxi;
26463 +       const char *name;
26464 +       struct inode *inode;
26465 +
26466 +       name = dentry->d_name.name;
26467 +       len = dentry->d_name.len;
26468 +       ret = -ENOMEM;
26469 +
26470 +#if 0
26471 +       if (len == 7 && !memcmp(name, "current", 7)) {
26472 +               inode = new_inode(dir->i_sb);
26473 +               if (!inode)
26474 +                       goto out;
26475 +               inode->i_mtime = inode->i_atime =
26476 +                       inode->i_ctime = CURRENT_TIME;
26477 +               inode->i_ino = fake_ino(1, PROC_XID_INO);
26478 +               inode->i_mode = S_IFLNK|S_IRWXUGO;
26479 +               inode->i_uid = inode->i_gid = 0;
26480 +               d_add(dentry, inode);
26481 +               return NULL;
26482 +       }
26483 +#endif
26484 +       if (len == 4 && !memcmp(name, "info", 4)) {
26485 +               inode = proc_vid_make_inode(dir->i_sb, 0, PROC_XID_INFO);
26486 +               if (!inode)
26487 +                       goto out;
26488 +               inode->i_fop = &proc_vid_info_file_operations;
26489 +               PROC_I(inode)->op.proc_vid_read = proc_virtual_info;
26490 +               inode->i_mode = S_IFREG|S_IRUGO;
26491 +               d_add(dentry, inode);
26492 +               return NULL;
26493 +       }
26494 +       if (len == 6 && !memcmp(name, "status", 6)) {
26495 +               inode = proc_vid_make_inode(dir->i_sb, 0, PROC_XID_STATUS);
26496 +               if (!inode)
26497 +                       goto out;
26498 +               inode->i_fop = &proc_vid_info_file_operations;
26499 +               PROC_I(inode)->op.proc_vid_read = proc_virtual_status;
26500 +               inode->i_mode = S_IFREG|S_IRUGO;
26501 +               d_add(dentry, inode);
26502 +               return NULL;
26503 +       }
26504 +
26505 +       ret = -ENOENT;
26506 +       xid = atovid(name, len);
26507 +       if (xid < 0)
26508 +               goto out;
26509 +       vxi = lookup_vx_info(xid);
26510 +       if (!vxi)
26511 +               goto out;
26512 +
26513 +       inode = NULL;
26514 +       if (vx_check(xid, VX_ADMIN|VX_WATCH|VX_IDENT))
26515 +               inode = proc_vid_make_inode(dir->i_sb,
26516 +                       vxi->vx_id, PROC_XID_INO);
26517 +       if (!inode)
26518 +               goto out_release;
26519 +
26520 +       inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
26521 +       inode->i_op = &proc_vid_inode_operations;
26522 +       inode->i_fop = &proc_vid_file_operations;
26523 +       inode->i_nlink = 2;
26524 +       inode->i_flags|=S_IMMUTABLE;
26525 +
26526 +       dentry->d_op = &proc_vid_dentry_operations;
26527 +       d_add(dentry, inode);
26528 +       ret = 0;
26529 +
26530 +out_release:
26531 +       put_vx_info(vxi);
26532 +out:
26533 +       return ERR_PTR(ret);
26534 +}
26535 +
26536 +
26537 +struct dentry *proc_vnet_lookup(struct inode *dir,
26538 +       struct dentry * dentry, struct nameidata *nd)
26539 +{
26540 +       int nid, len, ret;
26541 +       struct nx_info *nxi;
26542 +       const char *name;
26543 +       struct inode *inode;
26544 +
26545 +       name = dentry->d_name.name;
26546 +       len = dentry->d_name.len;
26547 +       ret = -ENOMEM;
26548 +#if 0
26549 +       if (len == 7 && !memcmp(name, "current", 7)) {
26550 +               inode = new_inode(dir->i_sb);
26551 +               if (!inode)
26552 +                       goto out;
26553 +               inode->i_mtime = inode->i_atime =
26554 +                       inode->i_ctime = CURRENT_TIME;
26555 +               inode->i_ino = fake_ino(1, PROC_NID_INO);
26556 +               inode->i_mode = S_IFLNK|S_IRWXUGO;
26557 +               inode->i_uid = inode->i_gid = 0;
26558 +               d_add(dentry, inode);
26559 +               return NULL;
26560 +       }
26561 +#endif
26562 +       if (len == 4 && !memcmp(name, "info", 4)) {
26563 +               inode = proc_vid_make_inode(dir->i_sb, 0, PROC_NID_INFO);
26564 +               if (!inode)
26565 +                       goto out;
26566 +               inode->i_fop = &proc_vid_info_file_operations;
26567 +               PROC_I(inode)->op.proc_vid_read = proc_vnet_info;
26568 +               inode->i_mode = S_IFREG|S_IRUGO;
26569 +               d_add(dentry, inode);
26570 +               return NULL;
26571 +       }
26572 +
26573 +       ret = -ENOENT;
26574 +       nid = atovid(name, len);
26575 +       if (nid < 0)
26576 +               goto out;
26577 +       nxi = lookup_nx_info(nid);
26578 +       if (!nxi)
26579 +               goto out;
26580 +
26581 +       inode = NULL;
26582 +       if (1)
26583 +               inode = proc_vid_make_inode(dir->i_sb,
26584 +                       nxi->nx_id, PROC_NID_INO);
26585 +       if (!inode)
26586 +               goto out_release;
26587 +
26588 +       inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
26589 +       inode->i_op = &proc_vid_inode_operations;
26590 +       inode->i_fop = &proc_vid_file_operations;
26591 +       inode->i_nlink = 2;
26592 +       inode->i_flags|=S_IMMUTABLE;
26593 +
26594 +       dentry->d_op = &proc_vid_dentry_operations;
26595 +       d_add(dentry, inode);
26596 +       ret = 0;
26597 +
26598 +out_release:
26599 +       put_nx_info(nxi);
26600 +out:
26601 +       return ERR_PTR(ret);
26602 +}
26603 +
26604 +
26605 +
26606 +
26607 +#define PROC_NUMBUF 10
26608 +#define PROC_MAXVIDS 32
26609 +
26610 +int proc_virtual_readdir(struct file * filp,
26611 +       void * dirent, filldir_t filldir)
26612 +{
26613 +       unsigned int xid_array[PROC_MAXVIDS];
26614 +       char buf[PROC_NUMBUF];
26615 +       unsigned int nr = filp->f_pos-3;
26616 +       unsigned int nr_xids, i;
26617 +       int visible = vx_check(0, VX_ADMIN|VX_WATCH);
26618 +       ino_t ino;
26619 +
26620 +       switch ((long)filp->f_pos) {
26621 +       case 0:
26622 +               ino = fake_ino(0, PROC_XID_INO);
26623 +               if (filldir(dirent, ".", 1,
26624 +                       filp->f_pos, ino, DT_DIR) < 0)
26625 +                       return 0;
26626 +               filp->f_pos++;
26627 +               /* fall through */
26628 +       case 1:
26629 +               ino = filp->f_dentry->d_parent->d_inode->i_ino;
26630 +               if (filldir(dirent, "..", 2,
26631 +                       filp->f_pos, ino, DT_DIR) < 0)
26632 +                       return 0;
26633 +               filp->f_pos++;
26634 +               /* fall through */
26635 +       case 2:
26636 +               if (visible) {
26637 +                       ino = fake_ino(0, PROC_XID_INFO);
26638 +                       if (filldir(dirent, "info", 4,
26639 +                               filp->f_pos, ino, DT_REG) < 0)
26640 +                               return 0;
26641 +               }
26642 +               filp->f_pos++;
26643 +               /* fall through */
26644 +       case 3:
26645 +               ino = fake_ino(0, PROC_XID_STATUS);
26646 +               if (filldir(dirent, "status", 6,
26647 +                       filp->f_pos, ino, DT_REG) < 0)
26648 +                       return 0;
26649 +               filp->f_pos++;
26650 +               /* fall through */
26651 +       }
26652 +
26653 +       nr_xids = get_xid_list(nr, xid_array, PROC_MAXVIDS);
26654 +       for (i = 0; i < nr_xids; i++) {
26655 +               int xid = xid_array[i];
26656 +               ino_t ino = fake_ino(xid, PROC_XID_INO);
26657 +               unsigned int j = PROC_NUMBUF;
26658 +
26659 +               do buf[--j] = '0' + (xid % 10); while (xid/=10);
26660 +
26661 +               if (filldir(dirent, buf+j, PROC_NUMBUF-j,
26662 +                       filp->f_pos, ino, DT_DIR) < 0)
26663 +                       break;
26664 +               filp->f_pos++;
26665 +       }
26666 +       return 0;
26667 +}
26668 +
26669 +
26670 +static struct file_operations proc_virtual_dir_operations = {
26671 +       .read =         generic_read_dir,
26672 +       .readdir =      proc_virtual_readdir,
26673 +};
26674 +
26675 +static struct inode_operations proc_virtual_dir_inode_operations = {
26676 +       .lookup =       proc_virtual_lookup,
26677 +};
26678 +
26679 +
26680 +int proc_vnet_readdir(struct file * filp,
26681 +       void * dirent, filldir_t filldir)
26682 +{
26683 +       unsigned int nid_array[PROC_MAXVIDS];
26684 +       char buf[PROC_NUMBUF];
26685 +       unsigned int nr = filp->f_pos-2;
26686 +       unsigned int nr_nids, i;
26687 +//     int visible = vx_check(0, VX_ADMIN|VX_WATCH);
26688 +       ino_t ino;
26689 +
26690 +       switch ((long)filp->f_pos) {
26691 +       case 0:
26692 +               ino = fake_ino(0, PROC_NID_INO);
26693 +               if (filldir(dirent, ".", 1,
26694 +                       filp->f_pos, ino, DT_DIR) < 0)
26695 +                       return 0;
26696 +               filp->f_pos++;
26697 +               /* fall through */
26698 +       case 1:
26699 +               ino = filp->f_dentry->d_parent->d_inode->i_ino;
26700 +               if (filldir(dirent, "..", 2,
26701 +                       filp->f_pos, ino, DT_DIR) < 0)
26702 +                       return 0;
26703 +               filp->f_pos++;
26704 +               /* fall through */
26705 +       case 2:
26706 +               ino = fake_ino(0, PROC_NID_INFO);
26707 +               if (filldir(dirent, "info", 4,
26708 +                       filp->f_pos, ino, DT_REG) < 0)
26709 +                       return 0;
26710 +               filp->f_pos++;
26711 +               /* fall through */
26712 +       }
26713 +
26714 +       nr_nids = get_nid_list(nr, nid_array, PROC_MAXVIDS);
26715 +       for (i = 0; i < nr_nids; i++) {
26716 +               int nid = nid_array[i];
26717 +               ino_t ino = fake_ino(nid, PROC_NID_INO);
26718 +               unsigned long j = PROC_NUMBUF;
26719 +
26720 +               do buf[--j] = '0' + (nid % 10); while (nid/=10);
26721 +
26722 +               if (filldir(dirent, buf+j, PROC_NUMBUF-j,
26723 +                       filp->f_pos, ino, DT_DIR) < 0)
26724 +                       break;
26725 +               filp->f_pos++;
26726 +       }
26727 +       return 0;
26728 +}
26729 +
26730 +
26731 +static struct file_operations proc_vnet_dir_operations = {
26732 +       .read =         generic_read_dir,
26733 +       .readdir =      proc_vnet_readdir,
26734 +};
26735 +
26736 +static struct inode_operations proc_vnet_dir_inode_operations = {
26737 +       .lookup =       proc_vnet_lookup,
26738 +};
26739 +
26740 +
26741 +
26742 +void proc_vx_init(void)
26743 +{
26744 +       struct proc_dir_entry *ent;
26745 +
26746 +       ent = proc_mkdir("virtual", 0);
26747 +       if (ent) {
26748 +               ent->proc_fops = &proc_virtual_dir_operations;
26749 +               ent->proc_iops = &proc_virtual_dir_inode_operations;
26750 +       }
26751 +       proc_virtual = ent;
26752 +
26753 +       ent = proc_mkdir("virtnet", 0);
26754 +       if (ent) {
26755 +               ent->proc_fops = &proc_vnet_dir_operations;
26756 +               ent->proc_iops = &proc_vnet_dir_inode_operations;
26757 +       }
26758 +       proc_vnet = ent;
26759 +}
26760 +
26761 +
26762 +
26763 +
26764 +/* per pid info */
26765 +
26766 +
26767 +int proc_pid_vx_info(struct task_struct *p, char *buffer)
26768 +{
26769 +       struct vx_info *vxi;
26770 +       char * orig = buffer;
26771 +
26772 +       buffer += sprintf (buffer,"XID:\t%d\n", vx_task_xid(p));
26773 +
26774 +       vxi = task_get_vx_info(p);
26775 +       if (!vxi)
26776 +               goto out;
26777 +
26778 +       buffer += sprintf (buffer,"BCaps:\t%016llx\n"
26779 +               ,(unsigned long long)vxi->vx_bcaps);
26780 +       buffer += sprintf (buffer,"CCaps:\t%016llx\n"
26781 +               ,(unsigned long long)vxi->vx_ccaps);
26782 +       buffer += sprintf (buffer,"CFlags:\t%016llx\n"
26783 +               ,(unsigned long long)vxi->vx_flags);
26784 +       buffer += sprintf (buffer,"CIPid:\t%d\n"
26785 +               ,vxi->vx_initpid);
26786 +
26787 +       put_vx_info(vxi);
26788 +out:
26789 +       return buffer - orig;
26790 +}
26791 +
26792 +
26793 +int proc_pid_nx_info(struct task_struct *p, char *buffer)
26794 +{
26795 +       struct nx_info *nxi;
26796 +       char * orig = buffer;
26797 +       int i;
26798 +
26799 +       buffer += sprintf (buffer,"NID:\t%d\n", nx_task_nid(p));
26800 +
26801 +       nxi = task_get_nx_info(p);
26802 +       if (!nxi)
26803 +               goto out;
26804 +
26805 +       for (i=0; i<nxi->nbipv4; i++){
26806 +               buffer += sprintf (buffer,
26807 +                       "V4Root[%d]:\t%d.%d.%d.%d/%d.%d.%d.%d\n", i
26808 +                       ,NIPQUAD(nxi->ipv4[i])
26809 +                       ,NIPQUAD(nxi->mask[i]));
26810 +       }
26811 +       buffer += sprintf (buffer,
26812 +               "V4Root[bcast]:\t%d.%d.%d.%d\n"
26813 +               ,NIPQUAD(nxi->v4_bcast));
26814 +
26815 +       put_nx_info(nxi);
26816 +out:
26817 +       return buffer - orig;
26818 +}
26819 +
26820 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/sched.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/sched.c
26821 --- linux-2.6.17.11/kernel/vserver/sched.c      1970-01-01 01:00:00 +0100
26822 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/sched.c 2006-08-13 06:13:52 +0200
26823 @@ -0,0 +1,318 @@
26824 +/*
26825 + *  linux/kernel/vserver/sched.c
26826 + *
26827 + *  Virtual Server: Scheduler Support
26828 + *
26829 + *  Copyright (C) 2004-2006  Herbert Pötzl
26830 + *
26831 + *  V0.01  adapted Sam Vilains version to 2.6.3
26832 + *  V0.02  removed legacy interface
26833 + *  V0.03  changed vcmds to vxi arg
26834 + *
26835 + */
26836 +
26837 +#include <linux/sched.h>
26838 +#include <linux/vs_context.h>
26839 +#include <linux/vs_sched.h>
26840 +#include <linux/vserver/sched_cmd.h>
26841 +
26842 +#include <asm/errno.h>
26843 +#include <asm/uaccess.h>
26844 +
26845 +#define vxd_check_range(val, min, max) do {            \
26846 +       vxlprintk((val<min) || (val>max),               \
26847 +               "check_range(%ld,%ld,%ld)",             \
26848 +               (long)val, (long)min, (long)max,        \
26849 +               __FILE__, __LINE__);                    \
26850 +       } while (0)
26851 +
26852 +
26853 +void vx_update_sched_param(struct _vx_sched *sched,
26854 +       struct _vx_sched_pc *sched_pc)
26855 +{
26856 +       unsigned int set_mask = sched->update_mask;
26857 +
26858 +       if (set_mask & VXSM_FILL_RATE)
26859 +               sched_pc->fill_rate[0] = sched->fill_rate[0];
26860 +       if (set_mask & VXSM_INTERVAL)
26861 +               sched_pc->interval[0] = sched->interval[0];
26862 +       if (set_mask & VXSM_FILL_RATE2)
26863 +               sched_pc->fill_rate[1] = sched->fill_rate[1];
26864 +       if (set_mask & VXSM_INTERVAL2)
26865 +               sched_pc->interval[1] = sched->interval[1];
26866 +       if (set_mask & VXSM_TOKENS)
26867 +               sched_pc->tokens = sched->tokens;
26868 +       if (set_mask & VXSM_TOKENS_MIN)
26869 +               sched_pc->tokens_min = sched->tokens_min;
26870 +       if (set_mask & VXSM_TOKENS_MAX)
26871 +               sched_pc->tokens_max = sched->tokens_max;
26872 +
26873 +       if (set_mask & VXSM_IDLE_TIME)
26874 +               sched_pc->flags |= VXSF_IDLE_TIME;
26875 +       else
26876 +               sched_pc->flags &= ~VXSF_IDLE_TIME;
26877 +
26878 +       /* reset time */
26879 +       sched_pc->norm_time = jiffies;
26880 +}
26881 +
26882 +
26883 +/*
26884 + * recalculate the context's scheduling tokens
26885 + *
26886 + * ret > 0 : number of tokens available
26887 + * ret < 0 : on hold, check delta_min[]
26888 + *          -1 only jiffies
26889 + *          -2 also idle time
26890 + *
26891 + */
26892 +int vx_tokens_recalc(struct _vx_sched_pc *sched_pc,
26893 +       unsigned long *norm_time, unsigned long *idle_time, int delta_min[2])
26894 +{
26895 +       long delta;
26896 +       long tokens = 0;
26897 +       int flags = sched_pc->flags;
26898 +
26899 +       /* how much time did pass? */
26900 +       delta = *norm_time - sched_pc->norm_time;
26901 +       vxd_check_range(delta, 0, INT_MAX);
26902 +
26903 +       if (delta >= sched_pc->interval[0]) {
26904 +               long tokens, integral;
26905 +
26906 +               /* calc integral token part */
26907 +               tokens = delta / sched_pc->interval[0];
26908 +               integral = tokens * sched_pc->interval[0];
26909 +               tokens *= sched_pc->fill_rate[0];
26910 +#ifdef CONFIG_VSERVER_HARDCPU
26911 +               delta_min[0] = delta - integral;
26912 +               vxd_check_range(delta_min[0], 0, sched_pc->interval[0]);
26913 +#endif
26914 +               /* advance time */
26915 +               sched_pc->norm_time += delta;
26916 +
26917 +               /* add tokens */
26918 +               sched_pc->tokens += tokens;
26919 +               sched_pc->token_time += tokens;
26920 +       }
26921 +       else
26922 +               delta_min[0] = delta;
26923 +
26924 +#ifdef CONFIG_VSERVER_IDLETIME
26925 +       if (!(flags & VXSF_IDLE_TIME))
26926 +               goto skip_idle;
26927 +
26928 +       /* how much was the idle skip? */
26929 +       delta = *idle_time - sched_pc->idle_time;
26930 +       vxd_check_range(delta, 0, INT_MAX);
26931 +
26932 +       if (delta >= sched_pc->interval[1]) {
26933 +               long tokens, integral;
26934 +
26935 +               /* calc fair share token part */
26936 +               tokens = delta / sched_pc->interval[1];
26937 +               integral = tokens * sched_pc->interval[1];
26938 +               tokens *= sched_pc->fill_rate[1];
26939 +               delta_min[1] = delta - integral;
26940 +               vxd_check_range(delta_min[1], 0, sched_pc->interval[1]);
26941 +
26942 +               /* advance idle time */
26943 +               sched_pc->idle_time += integral;
26944 +
26945 +               /* add tokens */
26946 +               sched_pc->tokens += tokens;
26947 +               sched_pc->token_time += tokens;
26948 +       }
26949 +       else
26950 +               delta_min[1] = delta;
26951 +skip_idle:
26952 +#endif
26953 +
26954 +       /* clip at maximum */
26955 +       if (sched_pc->tokens > sched_pc->tokens_max)
26956 +               sched_pc->tokens = sched_pc->tokens_max;
26957 +       tokens = sched_pc->tokens;
26958 +
26959 +       if ((flags & VXSF_ONHOLD)) {
26960 +               /* can we unhold? */
26961 +               if (tokens >= sched_pc->tokens_min) {
26962 +                       flags &= ~VXSF_ONHOLD;
26963 +                       sched_pc->hold_ticks +=
26964 +                               *norm_time - sched_pc->onhold;
26965 +               }
26966 +               else
26967 +                       goto on_hold;
26968 +       } else {
26969 +               /* put on hold? */
26970 +               if (tokens <= 0) {
26971 +                       flags |= VXSF_ONHOLD;
26972 +                       sched_pc->onhold = *norm_time;
26973 +                       goto on_hold;
26974 +               }
26975 +       }
26976 +       sched_pc->flags = flags;
26977 +       return tokens;
26978 +
26979 +on_hold:
26980 +       tokens = sched_pc->tokens_min - tokens;
26981 +       sched_pc->flags = flags;
26982 +       BUG_ON(tokens < 0);
26983 +
26984 +#ifdef CONFIG_VSERVER_HARDCPU
26985 +       /* next interval? */
26986 +       if (!sched_pc->fill_rate[0])
26987 +               delta_min[0] = HZ;
26988 +       else if (tokens > sched_pc->fill_rate[0])
26989 +               delta_min[0] += sched_pc->interval[0] *
26990 +                       tokens / sched_pc->fill_rate[0];
26991 +       else
26992 +               delta_min[0] = sched_pc->interval[0] - delta_min[0];
26993 +       vxd_check_range(delta_min[0], 0, INT_MAX);
26994 +
26995 +#ifdef CONFIG_VSERVER_IDLETIME
26996 +       if (!(flags & VXSF_IDLE_TIME))
26997 +               return -1;
26998 +
26999 +       /* next interval? */
27000 +       if (!sched_pc->fill_rate[1])
27001 +               delta_min[1] = HZ;
27002 +       else if (tokens > sched_pc->fill_rate[1])
27003 +               delta_min[1] += sched_pc->interval[1] *
27004 +                       tokens / sched_pc->fill_rate[1];
27005 +       else
27006 +               delta_min[1] = sched_pc->interval[1] - delta_min[1];
27007 +       vxd_check_range(delta_min[1], 0, INT_MAX);
27008 +
27009 +       return -2;
27010 +#else
27011 +       return -1;
27012 +#endif /* CONFIG_VSERVER_IDLETIME */
27013 +#else
27014 +       return 0;
27015 +#endif /* CONFIG_VSERVER_HARDCPU */
27016 +}
27017 +
27018 +
27019 +static int do_set_sched(struct vx_info *vxi, struct vcmd_set_sched_v4 *data)
27020 +{
27021 +       unsigned int set_mask = data->set_mask;
27022 +       unsigned int update_mask;
27023 +
27024 +       /* Sanity check data values */
27025 +       if (data->fill_rate < 0)
27026 +               data->fill_rate = 1;
27027 +       if (data->interval <= 0)
27028 +               data->interval = HZ;
27029 +       if (data->tokens_max <= 0)
27030 +               data->tokens_max = HZ;
27031 +       if (data->tokens_min < 0)
27032 +               data->tokens_min = data->fill_rate*3;
27033 +       if (data->tokens_min >= data->tokens_max)
27034 +               data->tokens_min = data->tokens_max;
27035 +
27036 +       if (data->prio_bias > MAX_PRIO_BIAS)
27037 +               data->prio_bias = MAX_PRIO_BIAS;
27038 +       if (data->prio_bias < MIN_PRIO_BIAS)
27039 +               data->prio_bias = MIN_PRIO_BIAS;
27040 +
27041 +       spin_lock(&vxi->sched.tokens_lock);
27042 +
27043 +       if (set_mask & VXSM_FILL_RATE)
27044 +               vxi->sched.fill_rate[0] = data->fill_rate;
27045 +       if (set_mask & VXSM_INTERVAL)
27046 +               vxi->sched.interval[0] = data->interval;
27047 +       if (set_mask & VXSM_FILL_RATE2)
27048 +               vxi->sched.fill_rate[1] = data->fill_rate;
27049 +       if (set_mask & VXSM_INTERVAL2)
27050 +               vxi->sched.interval[1] = data->interval;
27051 +       if (set_mask & VXSM_TOKENS)
27052 +               vxi->sched.tokens = data->tokens;
27053 +       if (set_mask & VXSM_TOKENS_MIN)
27054 +               vxi->sched.tokens_min = data->tokens_min;
27055 +       if (set_mask & VXSM_TOKENS_MAX)
27056 +               vxi->sched.tokens_max = data->tokens_max;
27057 +       if (set_mask & VXSM_PRIO_BIAS)
27058 +               vxi->sched.prio_bias = data->prio_bias;
27059 +
27060 +       update_mask = vxi->sched.update_mask & VXSM_SET_MASK;
27061 +       update_mask |= (set_mask & (VXSM_SET_MASK|VXSM_IDLE_TIME));
27062 +       vxi->sched.update_mask = update_mask;
27063 +#ifdef CONFIG_SMP
27064 +       rmb();
27065 +       if (set_mask & VXSM_CPU_ID)
27066 +               vxi->sched.update = cpumask_of_cpu(data->cpu_id);
27067 +       else
27068 +               vxi->sched.update = CPU_MASK_ALL;
27069 +       /* forced reload? */
27070 +       if (set_mask & VXSM_FORCE) {
27071 +               int cpu;
27072 +
27073 +               for_each_cpu(cpu)
27074 +                       vx_update_sched_param(&vxi->sched,
27075 +                               &vx_per_cpu(vxi, sched_pc, cpu));
27076 +       }
27077 +#else
27078 +       /* on UP we update immediately */
27079 +       vx_update_sched_param(&vxi->sched,
27080 +               &vx_per_cpu(vxi, sched_pc, 0));
27081 +#endif
27082 +
27083 +       spin_unlock(&vxi->sched.tokens_lock);
27084 +       return 0;
27085 +}
27086 +
27087 +
27088 +#ifdef CONFIG_VSERVER_LEGACY
27089 +
27090 +#define COPY_MASK_V2(name, mask)                       \
27091 +       if (vc_data.name != SCHED_KEEP) {               \
27092 +               vc_data_v4.name = vc_data.name;         \
27093 +               vc_data_v4.set_mask |= mask;            \
27094 +       }
27095 +
27096 +int vc_set_sched_v2(struct vx_info *vxi, void __user *data)
27097 +{
27098 +       struct vcmd_set_sched_v2 vc_data;
27099 +       struct vcmd_set_sched_v4 vc_data_v4 = { .set_mask = 0 };
27100 +
27101 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
27102 +               return -EFAULT;
27103 +
27104 +       COPY_MASK_V2(fill_rate,  VXSM_FILL_RATE);
27105 +       COPY_MASK_V2(interval,   VXSM_INTERVAL);
27106 +       COPY_MASK_V2(tokens,     VXSM_TOKENS);
27107 +       COPY_MASK_V2(tokens_min, VXSM_TOKENS_MIN);
27108 +       COPY_MASK_V2(tokens_max, VXSM_TOKENS_MAX);
27109 +       vc_data_v4.bucket_id = 0;
27110 +
27111 +       do_set_sched(vxi, &vc_data_v4);
27112 +       return 0;
27113 +}
27114 +#endif
27115 +
27116 +int vc_set_sched_v3(struct vx_info *vxi, void __user *data)
27117 +{
27118 +       struct vcmd_set_sched_v3 vc_data;
27119 +       struct vcmd_set_sched_v4 vc_data_v4;
27120 +
27121 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
27122 +               return -EFAULT;
27123 +
27124 +       /* structures are binary compatible */
27125 +       memcpy(&vc_data_v4, &vc_data, sizeof(vc_data));
27126 +       vc_data_v4.set_mask &= VXSM_V3_MASK;
27127 +       vc_data_v4.bucket_id = 0;
27128 +
27129 +       return do_set_sched(vxi, &vc_data_v4);
27130 +}
27131 +
27132 +int vc_set_sched(struct vx_info *vxi, void __user *data)
27133 +{
27134 +       struct vcmd_set_sched_v4 vc_data;
27135 +
27136 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
27137 +               return -EFAULT;
27138 +
27139 +       return do_set_sched(vxi, &vc_data);
27140 +}
27141 +
27142 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/sched_init.h linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/sched_init.h
27143 --- linux-2.6.17.11/kernel/vserver/sched_init.h 1970-01-01 01:00:00 +0100
27144 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/sched_init.h    2006-07-09 17:07:14 +0200
27145 @@ -0,0 +1,47 @@
27146 +
27147 +static inline void vx_info_init_sched(struct _vx_sched *sched)
27148 +{
27149 +       /* scheduling; hard code starting values as constants */
27150 +       sched->fill_rate[0]     = 1;
27151 +       sched->interval[0]      = 4;
27152 +       sched->fill_rate[1]     = 1;
27153 +       sched->interval[1]      = 8;
27154 +       sched->tokens           = HZ >> 2;
27155 +       sched->tokens_min       = HZ >> 4;
27156 +       sched->tokens_max       = HZ >> 1;
27157 +       sched->tokens_lock      = SPIN_LOCK_UNLOCKED;
27158 +       sched->prio_bias        = 0;
27159 +       sched->vavavoom         = 0;
27160 +}
27161 +
27162 +static inline
27163 +void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
27164 +{
27165 +       sched_pc->fill_rate[0]  = 1;
27166 +       sched_pc->interval[0]   = 4;
27167 +       sched_pc->fill_rate[1]  = 1;
27168 +       sched_pc->interval[1]   = 8;
27169 +       sched_pc->tokens        = HZ >> 2;
27170 +       sched_pc->tokens_min    = HZ >> 4;
27171 +       sched_pc->tokens_max    = HZ >> 1;
27172 +       sched_pc->token_time    = 0;
27173 +       sched_pc->idle_time     = 0;
27174 +       sched_pc->norm_time     = jiffies;
27175 +
27176 +       sched_pc->user_ticks = 0;
27177 +       sched_pc->sys_ticks = 0;
27178 +       sched_pc->hold_ticks = 0;
27179 +}
27180 +
27181 +
27182 +static inline void vx_info_exit_sched(struct _vx_sched *sched)
27183 +{
27184 +       return;
27185 +}
27186 +
27187 +static inline
27188 +void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
27189 +{
27190 +       return;
27191 +}
27192 +
27193 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/sched_proc.h linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/sched_proc.h
27194 --- linux-2.6.17.11/kernel/vserver/sched_proc.h 1970-01-01 01:00:00 +0100
27195 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/sched_proc.h    2006-07-09 17:07:14 +0200
27196 @@ -0,0 +1,59 @@
27197 +#ifndef _VX_SCHED_PROC_H
27198 +#define _VX_SCHED_PROC_H
27199 +
27200 +
27201 +static inline
27202 +int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
27203 +{
27204 +       int length = 0;
27205 +
27206 +       length += sprintf(buffer,
27207 +               "FillRate:\t%8d,%d\n"
27208 +               "Interval:\t%8d,%d\n"
27209 +               "TokensMin:\t%8d\n"
27210 +               "TokensMax:\t%8d\n"
27211 +               "PrioBias:\t%8d\n"
27212 +               "VaVaVoom:\t%8d\n"
27213 +               ,sched->fill_rate[0]
27214 +               ,sched->fill_rate[1]
27215 +               ,sched->interval[0]
27216 +               ,sched->interval[1]
27217 +               ,sched->tokens_min
27218 +               ,sched->tokens_max
27219 +               ,sched->prio_bias
27220 +               ,sched->vavavoom
27221 +               );
27222 +       return length;
27223 +}
27224 +
27225 +static inline
27226 +int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
27227 +       char *buffer, int cpu)
27228 +{
27229 +       int length = 0;
27230 +
27231 +       length += sprintf(buffer + length,
27232 +               "cpu %d: %lld %lld %lld %ld %ld"
27233 +               ,cpu
27234 +               ,(unsigned long long)sched_pc->user_ticks
27235 +               ,(unsigned long long)sched_pc->sys_ticks
27236 +               ,(unsigned long long)sched_pc->hold_ticks
27237 +               ,sched_pc->token_time
27238 +               ,sched_pc->idle_time
27239 +               );
27240 +       length += sprintf(buffer + length,
27241 +               " %c%c %d %d %d %d/%d %d/%d\n"
27242 +               ,(sched_pc->flags & VXSF_ONHOLD) ? 'H' : 'R'
27243 +               ,(sched_pc->flags & VXSF_IDLE_TIME) ? 'I' : '-'
27244 +               ,sched_pc->tokens
27245 +               ,sched_pc->tokens_min
27246 +               ,sched_pc->tokens_max
27247 +               ,sched_pc->fill_rate[0]
27248 +               ,sched_pc->interval[0]
27249 +               ,sched_pc->fill_rate[1]
27250 +               ,sched_pc->interval[1]
27251 +               );
27252 +       return length;
27253 +}
27254 +
27255 +#endif /* _VX_SCHED_PROC_H */
27256 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/signal.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/signal.c
27257 --- linux-2.6.17.11/kernel/vserver/signal.c     1970-01-01 01:00:00 +0100
27258 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/signal.c        2006-08-07 02:41:47 +0200
27259 @@ -0,0 +1,137 @@
27260 +/*
27261 + *  linux/kernel/vserver/signal.c
27262 + *
27263 + *  Virtual Server: Signal Support
27264 + *
27265 + *  Copyright (C) 2003-2006  Herbert Pötzl
27266 + *
27267 + *  V0.01  broken out from vcontext V0.05
27268 + *  V0.02  changed vcmds to vxi arg
27269 + *
27270 + */
27271 +
27272 +#include <linux/sched.h>
27273 +
27274 +#include <asm/errno.h>
27275 +#include <asm/uaccess.h>
27276 +
27277 +#include <linux/vs_context.h>
27278 +#include <linux/vserver/signal_cmd.h>
27279 +
27280 +
27281 +int vx_info_kill(struct vx_info *vxi, int pid, int sig)
27282 +{
27283 +       int retval, count=0;
27284 +       struct task_struct *p;
27285 +       unsigned long priv = 0;
27286 +
27287 +       retval = -ESRCH;
27288 +       vxdprintk(VXD_CBIT(misc, 4),
27289 +               "vx_info_kill(%p[#%d],%d,%d)*",
27290 +               vxi, vxi->vx_id, pid, sig);
27291 +       read_lock(&tasklist_lock);
27292 +       switch (pid) {
27293 +       case  0:
27294 +               priv = 1;
27295 +       case -1:
27296 +               for_each_process(p) {
27297 +                       int err = 0;
27298 +
27299 +                       if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
27300 +                               (pid && vxi->vx_initpid == p->pid))
27301 +                               continue;
27302 +
27303 +                       err = group_send_sig_info(sig, (void*)priv, p);
27304 +                       ++count;
27305 +                       if (err != -EPERM)
27306 +                               retval = err;
27307 +               }
27308 +               break;
27309 +
27310 +       case 1:
27311 +               if (vxi->vx_initpid) {
27312 +                       pid = vxi->vx_initpid;
27313 +                       printk("··· tasks left: %d\n", atomic_read(&vxi->vx_tasks));
27314 +                       /* for now, only SIGINT to private init ... */
27315 +                       if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
27316 +                               /* ... as long as there are tasks left */
27317 +                               (atomic_read(&vxi->vx_tasks) > 1))
27318 +                               sig = SIGINT;
27319 +                       priv = 1;
27320 +               }
27321 +               /* fallthrough */
27322 +       default:
27323 +               p = find_task_by_real_pid(pid);
27324 +               if (p) {
27325 +                       if (vx_task_xid(p) == vxi->vx_id)
27326 +                               retval = group_send_sig_info(sig,
27327 +                                       (void*)priv, p);
27328 +               }
27329 +               break;
27330 +       }
27331 +       read_unlock(&tasklist_lock);
27332 +       vxdprintk(VXD_CBIT(misc, 4),
27333 +               "vx_info_kill(%p[#%d],%d,%d) = %d",
27334 +               vxi, vxi->vx_id, pid, sig, retval);
27335 +       return retval;
27336 +}
27337 +
27338 +int vc_ctx_kill(struct vx_info *vxi, void __user *data)
27339 +{
27340 +       struct vcmd_ctx_kill_v0 vc_data;
27341 +
27342 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
27343 +               return -EFAULT;
27344 +
27345 +       /* special check to allow guest shutdown */
27346 +       if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
27347 +               /* forbid killall pid=0 when init is present */
27348 +               (((vc_data.pid < 1) && vxi->vx_initpid) ||
27349 +               (vc_data.pid > 1)))
27350 +               return -EACCES;
27351 +
27352 +       return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
27353 +}
27354 +
27355 +
27356 +static int __wait_exit(struct vx_info *vxi)
27357 +{
27358 +       DECLARE_WAITQUEUE(wait, current);
27359 +       int ret = 0;
27360 +
27361 +       add_wait_queue(&vxi->vx_wait, &wait);
27362 +       set_current_state(TASK_INTERRUPTIBLE);
27363 +
27364 +wait:
27365 +       if (vx_info_state(vxi,
27366 +               VXS_SHUTDOWN|VXS_HASHED|VXS_HELPER) == VXS_SHUTDOWN)
27367 +               goto out;
27368 +       if (signal_pending(current)) {
27369 +               ret = -ERESTARTSYS;
27370 +               goto out;
27371 +       }
27372 +       schedule();
27373 +       goto wait;
27374 +
27375 +out:
27376 +       set_current_state(TASK_RUNNING);
27377 +       remove_wait_queue(&vxi->vx_wait, &wait);
27378 +       return ret;
27379 +}
27380 +
27381 +
27382 +
27383 +int vc_wait_exit(struct vx_info *vxi, void __user *data)
27384 +{
27385 +       struct vcmd_wait_exit_v0 vc_data;
27386 +       int ret;
27387 +
27388 +       ret = __wait_exit(vxi);
27389 +       vc_data.reboot_cmd = vxi->reboot_cmd;
27390 +       vc_data.exit_code = vxi->exit_code;
27391 +
27392 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
27393 +               ret = -EFAULT;
27394 +       return ret;
27395 +}
27396 +
27397 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/switch.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/switch.c
27398 --- linux-2.6.17.11/kernel/vserver/switch.c     1970-01-01 01:00:00 +0100
27399 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/switch.c        2006-08-26 00:52:08 +0200
27400 @@ -0,0 +1,480 @@
27401 +/*
27402 + *  linux/kernel/vserver/switch.c
27403 + *
27404 + *  Virtual Server: Syscall Switch
27405 + *
27406 + *  Copyright (C) 2003-2006  Herbert Pötzl
27407 + *
27408 + *  V0.01  syscall switch
27409 + *  V0.02  added signal to context
27410 + *  V0.03  added rlimit functions
27411 + *  V0.04  added iattr, task/xid functions
27412 + *  V0.05  added debug/history stuff
27413 + *  V0.06  added compat32 layer
27414 + *  V0.07  vcmd args and perms
27415 + *
27416 + */
27417 +
27418 +#include <linux/linkage.h>
27419 +#include <linux/sched.h>
27420 +#include <linux/compat.h>
27421 +#include <asm/errno.h>
27422 +
27423 +#include <linux/vs_context.h>
27424 +#include <linux/vs_network.h>
27425 +#include <linux/vserver/switch.h>
27426 +#include <linux/vserver/debug.h>
27427 +
27428 +static inline
27429 +int vc_get_version(uint32_t id)
27430 +{
27431 +#ifdef CONFIG_VSERVER_LEGACY_VERSION
27432 +       if (id == 63)
27433 +               return VCI_LEGACY_VERSION;
27434 +#endif
27435 +       return VCI_VERSION;
27436 +}
27437 +
27438 +#include "vci_config.h"
27439 +
27440 +static inline
27441 +int vc_get_vci(uint32_t id)
27442 +{
27443 +       return vci_kernel_config();
27444 +}
27445 +
27446 +#include <linux/vserver/context_cmd.h>
27447 +#include <linux/vserver/cvirt_cmd.h>
27448 +#include <linux/vserver/cacct_cmd.h>
27449 +#include <linux/vserver/limit_cmd.h>
27450 +#include <linux/vserver/network_cmd.h>
27451 +#include <linux/vserver/sched_cmd.h>
27452 +#include <linux/vserver/debug_cmd.h>
27453 +#include <linux/vserver/inode_cmd.h>
27454 +#include <linux/vserver/dlimit_cmd.h>
27455 +#include <linux/vserver/signal_cmd.h>
27456 +#include <linux/vserver/namespace_cmd.h>
27457 +
27458 +#include <linux/vserver/legacy.h>
27459 +#include <linux/vserver/inode.h>
27460 +#include <linux/vserver/dlimit.h>
27461 +
27462 +
27463 +#ifdef CONFIG_COMPAT
27464 +#define __COMPAT(name, id, data, compat)       \
27465 +       (compat) ? name ## _x32 (id, data) : name (id, data)
27466 +#else
27467 +#define __COMPAT(name, id, data, compat)       \
27468 +       name (id, data)
27469 +#endif
27470 +
27471 +
27472 +static inline
27473 +long do_vcmd(uint32_t cmd, uint32_t id,
27474 +       struct vx_info *vxi, struct nx_info *nxi,
27475 +       void __user *data, int compat)
27476 +{
27477 +       switch (cmd) {
27478 +
27479 +       case VCMD_get_version:
27480 +               return vc_get_version(id);
27481 +       case VCMD_get_vci:
27482 +               return vc_get_vci(id);
27483 +
27484 +       case VCMD_task_xid:
27485 +               return vc_task_xid(id, data);
27486 +       case VCMD_vx_info:
27487 +               return vc_vx_info(vxi, data);
27488 +
27489 +       case VCMD_task_nid:
27490 +               return vc_task_nid(id, data);
27491 +       case VCMD_nx_info:
27492 +               return vc_nx_info(nxi, data);
27493 +
27494 +       case VCMD_set_namespace_v0:
27495 +       /* this is version 1 */
27496 +       case VCMD_set_namespace:
27497 +               return vc_set_namespace(vxi, data);
27498 +
27499 +#ifdef CONFIG_IA32_EMULATION
27500 +       case VCMD_get_rlimit:
27501 +               return __COMPAT(vc_get_rlimit, vxi, data, compat);
27502 +       case VCMD_set_rlimit:
27503 +               return __COMPAT(vc_set_rlimit, vxi, data, compat);
27504 +#else
27505 +       case VCMD_get_rlimit:
27506 +               return vc_get_rlimit(vxi, data);
27507 +       case VCMD_set_rlimit:
27508 +               return vc_set_rlimit(vxi, data);
27509 +#endif
27510 +       case VCMD_get_rlimit_mask:
27511 +               return vc_get_rlimit_mask(id, data);
27512 +       case VCMD_reset_minmax:
27513 +               return vc_reset_minmax(vxi, data);
27514 +
27515 +       case VCMD_get_vhi_name:
27516 +               return vc_get_vhi_name(vxi, data);
27517 +       case VCMD_set_vhi_name:
27518 +               return vc_set_vhi_name(vxi, data);
27519 +
27520 +       case VCMD_sock_stat:
27521 +               return vc_sock_stat(vxi, data);
27522 +       case VCMD_rlimit_stat:
27523 +               return vc_rlimit_stat(vxi, data);
27524 +
27525 +       case VCMD_set_cflags:
27526 +               return vc_set_cflags(vxi, data);
27527 +       case VCMD_get_cflags:
27528 +               return vc_get_cflags(vxi, data);
27529 +
27530 +       case VCMD_set_ccaps_v0:
27531 +               return vc_set_ccaps_v0(vxi, data);
27532 +       /* this is version 1 */
27533 +       case VCMD_set_ccaps:
27534 +               return vc_set_ccaps(vxi, data);
27535 +       case VCMD_get_ccaps_v0:
27536 +               return vc_get_ccaps_v0(vxi, data);
27537 +       /* this is version 1 */
27538 +       case VCMD_get_ccaps:
27539 +               return vc_get_ccaps(vxi, data);
27540 +       case VCMD_set_bcaps:
27541 +               return vc_set_bcaps(vxi, data);
27542 +       case VCMD_get_bcaps:
27543 +               return vc_get_bcaps(vxi, data);
27544 +
27545 +       case VCMD_set_nflags:
27546 +               return vc_set_nflags(nxi, data);
27547 +       case VCMD_get_nflags:
27548 +               return vc_get_nflags(nxi, data);
27549 +
27550 +       case VCMD_set_ncaps:
27551 +               return vc_set_ncaps(nxi, data);
27552 +       case VCMD_get_ncaps:
27553 +               return vc_get_ncaps(nxi, data);
27554 +
27555 +#ifdef CONFIG_VSERVER_LEGACY
27556 +       case VCMD_set_sched_v2:
27557 +               return vc_set_sched_v2(vxi, data);
27558 +#endif
27559 +       case VCMD_set_sched_v3:
27560 +               return vc_set_sched_v3(vxi, data);
27561 +       /* this is version 4 */
27562 +       case VCMD_set_sched:
27563 +               return vc_set_sched(vxi, data);
27564 +
27565 +       case VCMD_add_dlimit:
27566 +               return __COMPAT(vc_add_dlimit, id, data, compat);
27567 +       case VCMD_rem_dlimit:
27568 +               return __COMPAT(vc_rem_dlimit, id, data, compat);
27569 +       case VCMD_set_dlimit:
27570 +               return __COMPAT(vc_set_dlimit, id, data, compat);
27571 +       case VCMD_get_dlimit:
27572 +               return __COMPAT(vc_get_dlimit, id, data, compat);
27573 +
27574 +       case VCMD_ctx_kill:
27575 +               return vc_ctx_kill(vxi, data);
27576 +
27577 +       case VCMD_wait_exit:
27578 +               return vc_wait_exit(vxi, data);
27579 +
27580 +#ifdef CONFIG_VSERVER_LEGACY
27581 +       case VCMD_create_context:
27582 +               return vc_ctx_create(id, NULL);
27583 +#endif
27584 +
27585 +       case VCMD_get_iattr:
27586 +               return __COMPAT(vc_get_iattr, id, data, compat);
27587 +       case VCMD_set_iattr:
27588 +               return __COMPAT(vc_set_iattr, id, data, compat);
27589 +
27590 +       case VCMD_enter_namespace:
27591 +               return vc_enter_namespace(vxi, data);
27592 +
27593 +       case VCMD_ctx_create_v0:
27594 +               return vc_ctx_create(id, NULL);
27595 +       case VCMD_ctx_create:
27596 +               return vc_ctx_create(id, data);
27597 +       case VCMD_ctx_migrate_v0:
27598 +               return vc_ctx_migrate(vxi, NULL);
27599 +       case VCMD_ctx_migrate:
27600 +               return vc_ctx_migrate(vxi, data);
27601 +
27602 +       case VCMD_net_create_v0:
27603 +               return vc_net_create(id, NULL);
27604 +       case VCMD_net_create:
27605 +               return vc_net_create(id, data);
27606 +       case VCMD_net_migrate:
27607 +               return vc_net_migrate(nxi, data);
27608 +       case VCMD_net_add:
27609 +               return vc_net_add(nxi, data);
27610 +       case VCMD_net_remove:
27611 +               return vc_net_remove(nxi, data);
27612 +
27613 +#ifdef CONFIG_VSERVER_HISTORY
27614 +       case VCMD_dump_history:
27615 +               return vc_dump_history(id);
27616 +#endif
27617 +#ifdef CONFIG_VSERVER_LEGACY
27618 +       case VCMD_new_s_context:
27619 +               return vc_new_s_context(id, data);
27620 +#endif
27621 +#ifdef CONFIG_VSERVER_LEGACYNET
27622 +       case VCMD_set_ipv4root:
27623 +               return vc_set_ipv4root(id, data);
27624 +#endif
27625 +       default:
27626 +               vxwprintk(1, "unimplemented VCMD_%02d_%d[%d]",
27627 +                       VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
27628 +       }
27629 +       return -ENOSYS;
27630 +}
27631 +
27632 +
27633 +#define        __VCMD(vcmd, _perm, _args, _flags)              \
27634 +       case VCMD_ ## vcmd: perm = _perm;               \
27635 +               args = _args; flags = _flags; break
27636 +
27637 +
27638 +#define VCA_NONE       0x00
27639 +#define VCA_VXI                0x01
27640 +#define VCA_NXI                0x02
27641 +
27642 +#define VCF_NONE       0x00
27643 +#define VCF_INFO       0x01
27644 +#define VCF_ADMIN      0x02
27645 +#define VCF_ARES       0x06    /* includes admin */
27646 +#define VCF_SETUP      0x08
27647 +
27648 +
27649 +static inline
27650 +long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
27651 +{
27652 +       long ret;
27653 +       int permit = -1, state = 0;
27654 +       int perm = -1, args = 0, flags = 0;
27655 +       struct vx_info *vxi = NULL;
27656 +       struct nx_info *nxi = NULL;
27657 +
27658 +       switch (cmd) {
27659 +       /* unpriviledged commands */
27660 +       __VCMD(get_version,      0, VCA_NONE,   0);
27661 +       __VCMD(get_vci,          0, VCA_NONE,   0);
27662 +       __VCMD(get_rlimit_mask,  0, VCA_NONE,   0);
27663 +
27664 +       /* info commands */
27665 +       __VCMD(task_xid,         2, VCA_NONE,   0);
27666 +       __VCMD(reset_minmax,     2, VCA_VXI,    0);
27667 +       __VCMD(vx_info,          3, VCA_VXI,    VCF_INFO);
27668 +       __VCMD(get_bcaps,        3, VCA_VXI,    VCF_INFO);
27669 +       __VCMD(get_ccaps_v0,     3, VCA_VXI,    VCF_INFO);
27670 +       __VCMD(get_ccaps,        3, VCA_VXI,    VCF_INFO);
27671 +       __VCMD(get_cflags,       3, VCA_VXI,    VCF_INFO);
27672 +       __VCMD(get_vhi_name,     3, VCA_VXI,    VCF_INFO);
27673 +       __VCMD(get_rlimit,       3, VCA_VXI,    VCF_INFO);
27674 +
27675 +       __VCMD(sock_stat,        3, VCA_VXI,    VCF_INFO);
27676 +       __VCMD(rlimit_stat,      3, VCA_VXI,    VCF_INFO);
27677 +
27678 +       __VCMD(task_nid,         2, VCA_NONE,   0);
27679 +       __VCMD(nx_info,          3, VCA_NXI,    VCF_INFO);
27680 +       __VCMD(get_ncaps,        3, VCA_NXI,    VCF_INFO);
27681 +       __VCMD(get_nflags,       3, VCA_NXI,    VCF_INFO);
27682 +
27683 +       __VCMD(get_iattr,        2, VCA_NONE,   0);
27684 +       __VCMD(get_dlimit,       3, VCA_NONE,   VCF_INFO);
27685 +
27686 +       /* lower admin commands */
27687 +       __VCMD(wait_exit,        4, VCA_VXI,    VCF_INFO);
27688 +       __VCMD(ctx_create_v0,    5, VCA_NONE,   0);
27689 +       __VCMD(ctx_create,       5, VCA_NONE,   0);
27690 +       __VCMD(ctx_migrate_v0,   5, VCA_VXI,    VCF_ADMIN);
27691 +       __VCMD(ctx_migrate,      5, VCA_VXI,    VCF_ADMIN);
27692 +       __VCMD(enter_namespace,  5, VCA_VXI,    VCF_ADMIN);
27693 +
27694 +       __VCMD(net_create_v0,    5, VCA_NONE,   0);
27695 +       __VCMD(net_create,       5, VCA_NONE,   0);
27696 +       __VCMD(net_migrate,      5, VCA_NXI,    VCF_ADMIN);
27697 +
27698 +       /* higher admin commands */
27699 +       __VCMD(ctx_kill,         6, VCA_VXI,    VCF_ARES);
27700 +       __VCMD(set_namespace_v0, 7, VCA_VXI,    VCF_ARES|VCF_SETUP);
27701 +       __VCMD(set_namespace,    7, VCA_VXI,    VCF_ARES|VCF_SETUP);
27702 +
27703 +       __VCMD(set_ccaps_v0,     7, VCA_VXI,    VCF_ARES|VCF_SETUP);
27704 +       __VCMD(set_ccaps,        7, VCA_VXI,    VCF_ARES|VCF_SETUP);
27705 +       __VCMD(set_bcaps,        7, VCA_VXI,    VCF_ARES|VCF_SETUP);
27706 +       __VCMD(set_cflags,       7, VCA_VXI,    VCF_ARES|VCF_SETUP);
27707 +
27708 +       __VCMD(set_vhi_name,     7, VCA_VXI,    VCF_ARES|VCF_SETUP);
27709 +       __VCMD(set_rlimit,       7, VCA_VXI,    VCF_ARES|VCF_SETUP);
27710 +       __VCMD(set_sched,        7, VCA_VXI,    VCF_ARES|VCF_SETUP);
27711 +       __VCMD(set_sched_v2,     7, VCA_VXI,    VCF_ARES|VCF_SETUP);
27712 +       __VCMD(set_sched_v3,     7, VCA_VXI,    VCF_ARES|VCF_SETUP);
27713 +
27714 +       __VCMD(set_ncaps,        7, VCA_NXI,    VCF_ARES|VCF_SETUP);
27715 +       __VCMD(set_nflags,       7, VCA_NXI,    VCF_ARES|VCF_SETUP);
27716 +       __VCMD(net_add,          8, VCA_NXI,    VCF_ARES|VCF_SETUP);
27717 +       __VCMD(net_remove,       8, VCA_NXI,    VCF_ARES|VCF_SETUP);
27718 +
27719 +       __VCMD(set_iattr,        7, VCA_NONE,   0);
27720 +       __VCMD(set_dlimit,       7, VCA_NONE,   VCF_ARES);
27721 +       __VCMD(add_dlimit,       8, VCA_NONE,   VCF_ARES);
27722 +       __VCMD(rem_dlimit,       8, VCA_NONE,   VCF_ARES);
27723 +
27724 +       /* debug level admin commands */
27725 +#ifdef CONFIG_VSERVER_HISTORY
27726 +       __VCMD(dump_history,     9, VCA_NONE,   0);
27727 +#endif
27728 +
27729 +       /* legacy commands */
27730 +#ifdef CONFIG_VSERVER_LEGACY
27731 +       __VCMD(create_context,   5, VCA_NONE,   0);
27732 +       __VCMD(new_s_context,    5, VCA_NONE,   0);
27733 +#endif
27734 +#ifdef CONFIG_VSERVER_LEGACYNET
27735 +       __VCMD(set_ipv4root,     5, VCA_NONE,   0);
27736 +#endif
27737 +       default:
27738 +               perm = -1;
27739 +       }
27740 +
27741 +       vxdprintk(VXD_CBIT(switch, 0),
27742 +               "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
27743 +               VC_CATEGORY(cmd), VC_COMMAND(cmd),
27744 +               VC_VERSION(cmd), id, data, compat,
27745 +               perm, args, flags);
27746 +
27747 +       ret = -ENOSYS;
27748 +       if (perm < 0)
27749 +               goto out;
27750 +
27751 +       state = 1;
27752 +#ifdef CONFIG_VSERVER_LEGACY
27753 +       if (!capable(CAP_CONTEXT) &&
27754 +               /* dirty hack for capremove */
27755 +               !(cmd==VCMD_new_s_context && id==-2))
27756 +               goto out;
27757 +#else
27758 +       if (!capable(CAP_CONTEXT))
27759 +               goto out;
27760 +#endif
27761 +
27762 +       state = 2;
27763 +       /* moved here from the individual commands */
27764 +       ret = -EPERM;
27765 +       if ((perm > 1) && !capable(CAP_SYS_ADMIN))
27766 +               goto out;
27767 +
27768 +       state = 3;
27769 +       /* vcmd involves resource management  */
27770 +       ret = -EPERM;
27771 +       if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
27772 +               goto out;
27773 +
27774 +       state = 4;
27775 +       /* various legacy exceptions */
27776 +       switch (cmd) {
27777 +#ifdef CONFIG_VSERVER_LEGACY
27778 +       case VCMD_set_cflags:
27779 +       case VCMD_set_ccaps_v0:
27780 +               ret = 0;
27781 +               if (vx_check(0, VX_WATCH))
27782 +                       goto out;
27783 +               break;
27784 +
27785 +       case VCMD_ctx_create_v0:
27786 +#endif
27787 +       /* will go away when admin is a cap */
27788 +       case VCMD_ctx_migrate_v0:
27789 +       case VCMD_ctx_migrate:
27790 +               if (id == 1) {
27791 +                       current->xid = 1;
27792 +                       ret = 1;
27793 +                       goto out;
27794 +               }
27795 +               break;
27796 +
27797 +       /* legacy special casing */
27798 +       case VCMD_set_namespace_v0:
27799 +               id = -1;
27800 +               break;
27801 +       }
27802 +
27803 +       /* vcmds are fine by default */
27804 +       permit = 1;
27805 +
27806 +       /* admin type vcmds require admin ... */
27807 +       if (flags & VCF_ADMIN)
27808 +               permit = vx_check(0, VX_ADMIN) ? 1 : 0;
27809 +
27810 +       /* ... but setup type vcmds override that */
27811 +       if (!permit && (flags & VCF_SETUP))
27812 +               permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
27813 +
27814 +       state = 5;
27815 +       ret = -EPERM;
27816 +       if (!permit)
27817 +               goto out;
27818 +
27819 +       state = 6;
27820 +       ret = -ESRCH;
27821 +       if (args & VCA_VXI) {
27822 +               vxi = lookup_vx_info(id);
27823 +               if (!vxi)
27824 +                       goto out;
27825 +
27826 +               if ((flags & VCF_ADMIN) &&
27827 +                       /* special case kill for shutdown */
27828 +                       (cmd != VCMD_ctx_kill) &&
27829 +                       /* can context be administrated? */
27830 +                       !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
27831 +                       ret = -EACCES;
27832 +                       goto out_vxi;
27833 +               }
27834 +       }
27835 +       state = 7;
27836 +       if (args & VCA_NXI) {
27837 +               nxi = lookup_nx_info(id);
27838 +               if (!nxi)
27839 +                       goto out_vxi;
27840 +
27841 +               if ((flags & VCF_ADMIN) &&
27842 +                       /* can context be administrated? */
27843 +                       !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
27844 +                       ret = -EACCES;
27845 +                       goto out_nxi;
27846 +               }
27847 +       }
27848 +
27849 +       state = 8;
27850 +       ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
27851 +
27852 +out_nxi:
27853 +       if (args & VCA_NXI)
27854 +               put_nx_info(nxi);
27855 +out_vxi:
27856 +       if (args & VCA_VXI)
27857 +               put_vx_info(vxi);
27858 +out:
27859 +       vxdprintk(VXD_CBIT(switch, 1),
27860 +               "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
27861 +               VC_CATEGORY(cmd), VC_COMMAND(cmd),
27862 +               VC_VERSION(cmd), ret, ret, state, permit);
27863 +       return ret;
27864 +}
27865 +
27866 +extern asmlinkage long
27867 +sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
27868 +{
27869 +       return do_vserver(cmd, id, data, 0);
27870 +}
27871 +
27872 +#ifdef CONFIG_COMPAT
27873 +
27874 +extern asmlinkage long
27875 +sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
27876 +{
27877 +       return do_vserver(cmd, id, data, 1);
27878 +}
27879 +
27880 +#endif /* CONFIG_COMPAT */
27881 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/sysctl.c linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/sysctl.c
27882 --- linux-2.6.17.11/kernel/vserver/sysctl.c     1970-01-01 01:00:00 +0100
27883 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/sysctl.c        2006-07-09 17:07:14 +0200
27884 @@ -0,0 +1,241 @@
27885 +/*
27886 + *  kernel/vserver/sysctl.c
27887 + *
27888 + *  Virtual Context Support
27889 + *
27890 + *  Copyright (C) 2004-2005  Herbert Pötzl
27891 + *
27892 + *  V0.01  basic structure
27893 + *
27894 + */
27895 +
27896 +#include <linux/errno.h>
27897 +#include <linux/module.h>
27898 +#include <linux/types.h>
27899 +#include <linux/ctype.h>
27900 +#include <linux/sysctl.h>
27901 +#include <linux/parser.h>
27902 +#include <linux/fs.h>
27903 +
27904 +#include <asm/uaccess.h>
27905 +#include <asm/unistd.h>
27906 +
27907 +
27908 +#define CTL_VSERVER    4242    /* unused? */
27909 +
27910 +enum {
27911 +       CTL_DEBUG_ERROR         = 0,
27912 +       CTL_DEBUG_SWITCH        = 1,
27913 +       CTL_DEBUG_XID,
27914 +       CTL_DEBUG_NID,
27915 +       CTL_DEBUG_TAG,
27916 +       CTL_DEBUG_NET,
27917 +       CTL_DEBUG_LIMIT,
27918 +       CTL_DEBUG_CRES,
27919 +       CTL_DEBUG_DLIM,
27920 +       CTL_DEBUG_QUOTA,
27921 +       CTL_DEBUG_CVIRT,
27922 +       CTL_DEBUG_MISC,
27923 +};
27924 +
27925 +
27926 +unsigned int vx_debug_switch   = 0;
27927 +unsigned int vx_debug_xid      = 0;
27928 +unsigned int vx_debug_nid      = 0;
27929 +unsigned int vx_debug_tag      = 0;
27930 +unsigned int vx_debug_net      = 0;
27931 +unsigned int vx_debug_limit    = 0;
27932 +unsigned int vx_debug_cres     = 0;
27933 +unsigned int vx_debug_dlim     = 0;
27934 +unsigned int vx_debug_quota    = 0;
27935 +unsigned int vx_debug_cvirt    = 0;
27936 +unsigned int vx_debug_misc     = 0;
27937 +
27938 +
27939 +static struct ctl_table_header *vserver_table_header;
27940 +static ctl_table vserver_table[];
27941 +
27942 +
27943 +void vserver_register_sysctl(void)
27944 +{
27945 +       if (!vserver_table_header) {
27946 +               vserver_table_header = register_sysctl_table(vserver_table, 1);
27947 +       }
27948 +
27949 +}
27950 +
27951 +void vserver_unregister_sysctl(void)
27952 +{
27953 +       if (vserver_table_header) {
27954 +               unregister_sysctl_table(vserver_table_header);
27955 +               vserver_table_header = NULL;
27956 +       }
27957 +}
27958 +
27959 +
27960 +static int proc_dodebug(ctl_table *table, int write,
27961 +       struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
27962 +{
27963 +       char            tmpbuf[20], *p, c;
27964 +       unsigned int    value;
27965 +       size_t          left, len;
27966 +
27967 +       if ((*ppos && !write) || !*lenp) {
27968 +               *lenp = 0;
27969 +               return 0;
27970 +       }
27971 +
27972 +       left = *lenp;
27973 +
27974 +       if (write) {
27975 +               if (!access_ok(VERIFY_READ, buffer, left))
27976 +                       return -EFAULT;
27977 +               p = (char *) buffer;
27978 +               while (left && __get_user(c, p) >= 0 && isspace(c))
27979 +                       left--, p++;
27980 +               if (!left)
27981 +                       goto done;
27982 +
27983 +               if (left > sizeof(tmpbuf) - 1)
27984 +                       return -EINVAL;
27985 +               if (copy_from_user(tmpbuf, p, left))
27986 +                       return -EFAULT;
27987 +               tmpbuf[left] = '\0';
27988 +
27989 +               for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
27990 +                       value = 10 * value + (*p - '0');
27991 +               if (*p && !isspace(*p))
27992 +                       return -EINVAL;
27993 +               while (left && isspace(*p))
27994 +                       left--, p++;
27995 +               *(unsigned int *) table->data = value;
27996 +       } else {
27997 +               if (!access_ok(VERIFY_WRITE, buffer, left))
27998 +                       return -EFAULT;
27999 +               len = sprintf(tmpbuf, "%d", *(unsigned int *) table->data);
28000 +               if (len > left)
28001 +                       len = left;
28002 +               if (__copy_to_user(buffer, tmpbuf, len))
28003 +                       return -EFAULT;
28004 +               if ((left -= len) > 0) {
28005 +                       if (put_user('\n', (char *)buffer + len))
28006 +                               return -EFAULT;
28007 +                       left--;
28008 +               }
28009 +       }
28010 +
28011 +done:
28012 +       *lenp -= left;
28013 +       *ppos += *lenp;
28014 +       return 0;
28015 +}
28016 +
28017 +
28018 +#define        CTL_ENTRY(ctl, name)                            \
28019 +       {                                               \
28020 +               .ctl_name       = ctl,                  \
28021 +               .procname       = #name,                \
28022 +               .data           = &vx_##name,           \
28023 +               .maxlen         = sizeof(int),          \
28024 +               .mode           = 0644,                 \
28025 +               .proc_handler   = &proc_dodebug         \
28026 +       }
28027 +
28028 +static ctl_table debug_table[] = {
28029 +       CTL_ENTRY (CTL_DEBUG_SWITCH,    debug_switch),
28030 +       CTL_ENTRY (CTL_DEBUG_XID,       debug_xid),
28031 +       CTL_ENTRY (CTL_DEBUG_NID,       debug_nid),
28032 +       CTL_ENTRY (CTL_DEBUG_TAG,       debug_tag),
28033 +       CTL_ENTRY (CTL_DEBUG_NET,       debug_net),
28034 +       CTL_ENTRY (CTL_DEBUG_LIMIT,     debug_limit),
28035 +       CTL_ENTRY (CTL_DEBUG_CRES,      debug_cres),
28036 +       CTL_ENTRY (CTL_DEBUG_DLIM,      debug_dlim),
28037 +       CTL_ENTRY (CTL_DEBUG_QUOTA,     debug_quota),
28038 +       CTL_ENTRY (CTL_DEBUG_CVIRT,     debug_cvirt),
28039 +       CTL_ENTRY (CTL_DEBUG_MISC,      debug_misc),
28040 +       { .ctl_name = 0 }
28041 +};
28042 +
28043 +static ctl_table vserver_table[] = {
28044 +       {
28045 +               .ctl_name       = CTL_VSERVER,
28046 +               .procname       = "vserver",
28047 +               .mode           = 0555,
28048 +               .child          = debug_table
28049 +       },
28050 +       { .ctl_name = 0 }
28051 +};
28052 +
28053 +
28054 +static match_table_t tokens = {
28055 +       { CTL_DEBUG_SWITCH,     "switch=%x"     },
28056 +       { CTL_DEBUG_XID,        "xid=%x"        },
28057 +       { CTL_DEBUG_NID,        "nid=%x"        },
28058 +       { CTL_DEBUG_TAG,        "tag=%x"        },
28059 +       { CTL_DEBUG_NET,        "net=%x"        },
28060 +       { CTL_DEBUG_LIMIT,      "limit=%x"      },
28061 +       { CTL_DEBUG_CRES,       "cres=%x"       },
28062 +       { CTL_DEBUG_DLIM,       "dlim=%x"       },
28063 +       { CTL_DEBUG_QUOTA,      "quota=%x"      },
28064 +       { CTL_DEBUG_CVIRT,      "cvirt=%x"      },
28065 +       { CTL_DEBUG_MISC,       "misc=%x"       },
28066 +       { CTL_DEBUG_ERROR,      NULL            }
28067 +};
28068 +
28069 +#define        HANDLE_CASE(id, name, val)                              \
28070 +       case CTL_DEBUG_ ## id:                                  \
28071 +               vx_debug_ ## name = val;                        \
28072 +               printk("vs_debug_" #name "=0x%x\n", val);       \
28073 +               break
28074 +
28075 +
28076 +static int __init vs_debug_setup(char *str)
28077 +{
28078 +       char *p;
28079 +       int token;
28080 +
28081 +       printk("vs_debug_setup(%s)\n", str);
28082 +       while ((p = strsep(&str, ",")) != NULL) {
28083 +               substring_t args[MAX_OPT_ARGS];
28084 +               unsigned int value;
28085 +
28086 +               if (!*p)
28087 +                       continue;
28088 +
28089 +               token = match_token(p, tokens, args);
28090 +               value = (token>0)?simple_strtoul(args[0].from, NULL, 0):0;
28091 +
28092 +               switch (token) {
28093 +               HANDLE_CASE(SWITCH, switch, value);
28094 +               HANDLE_CASE(XID,    xid,    value);
28095 +               HANDLE_CASE(NID,    nid,    value);
28096 +               HANDLE_CASE(NET,    net,    value);
28097 +               HANDLE_CASE(LIMIT,  limit,  value);
28098 +               HANDLE_CASE(CRES,   cres,   value);
28099 +               HANDLE_CASE(DLIM,   dlim,   value);
28100 +               HANDLE_CASE(QUOTA,  quota,  value);
28101 +               HANDLE_CASE(CVIRT,  cvirt,  value);
28102 +               HANDLE_CASE(MISC,   misc,   value);
28103 +               default:
28104 +                       return -EINVAL;
28105 +                       break;
28106 +               }
28107 +       }
28108 +       return 1;
28109 +}
28110 +
28111 +__setup("vsdebug=", vs_debug_setup);
28112 +
28113 +
28114 +
28115 +EXPORT_SYMBOL_GPL(vx_debug_switch);
28116 +EXPORT_SYMBOL_GPL(vx_debug_xid);
28117 +EXPORT_SYMBOL_GPL(vx_debug_nid);
28118 +EXPORT_SYMBOL_GPL(vx_debug_net);
28119 +EXPORT_SYMBOL_GPL(vx_debug_limit);
28120 +EXPORT_SYMBOL_GPL(vx_debug_cres);
28121 +EXPORT_SYMBOL_GPL(vx_debug_dlim);
28122 +EXPORT_SYMBOL_GPL(vx_debug_quota);
28123 +EXPORT_SYMBOL_GPL(vx_debug_cvirt);
28124 +EXPORT_SYMBOL_GPL(vx_debug_misc);
28125 +
28126 diff -NurpP --minimal linux-2.6.17.11/kernel/vserver/vci_config.h linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/vci_config.h
28127 --- linux-2.6.17.11/kernel/vserver/vci_config.h 1970-01-01 01:00:00 +0100
28128 +++ linux-2.6.17.11-vs2.1.1-rc31/kernel/vserver/vci_config.h    2006-07-09 17:07:14 +0200
28129 @@ -0,0 +1,78 @@
28130 +
28131 +enum {
28132 +       VCI_KCBIT_LEGACY = 1,
28133 +       VCI_KCBIT_LEGACYNET,
28134 +       VCI_KCBIT_NGNET,
28135 +
28136 +       VCI_KCBIT_PROC_SECURE,
28137 +       VCI_KCBIT_HARDCPU,
28138 +       VCI_KCBIT_IDLELIMIT,
28139 +       VCI_KCBIT_IDLETIME,
28140 +
28141 +       VCI_KCBIT_COWBL,
28142 +
28143 +       VCI_KCBIT_LEGACY_VERSION = 15,
28144 +       VCI_KCBIT_DEBUG = 16,
28145 +       VCI_KCBIT_HISTORY = 20,
28146 +       VCI_KCBIT_TAGGED = 24,
28147 +};
28148 +
28149 +
28150 +static inline uint32_t vci_kernel_config(void)
28151 +{
28152 +       return
28153 +       /* various legacy options */
28154 +#ifdef CONFIG_VSERVER_LEGACY
28155 +       (1 << VCI_KCBIT_LEGACY) |
28156 +#endif
28157 +#ifdef CONFIG_VSERVER_LEGACYNET
28158 +       (1 << VCI_KCBIT_LEGACYNET) |
28159 +#endif
28160 +#ifdef CONFIG_VSERVER_LEGACY_VERSION
28161 +       (1 << VCI_KCBIT_LEGACY_VERSION) |
28162 +#endif
28163 +
28164 +       /* configured features */
28165 +#ifdef CONFIG_VSERVER_PROC_SECURE
28166 +       (1 << VCI_KCBIT_PROC_SECURE) |
28167 +#endif
28168 +#ifdef CONFIG_VSERVER_HARDCPU
28169 +       (1 << VCI_KCBIT_HARDCPU) |
28170 +#endif
28171 +#ifdef CONFIG_VSERVER_IDLELIMIT
28172 +       (1 << VCI_KCBIT_IDLELIMIT) |
28173 +#endif
28174 +#ifdef CONFIG_VSERVER_IDLETIME
28175 +       (1 << VCI_KCBIT_IDLETIME) |
28176 +#endif
28177 +#ifdef CONFIG_VSERVER_COWBL
28178 +       (1 << VCI_KCBIT_COWBL) |
28179 +#endif
28180 +
28181 +       /* debug options */
28182 +#ifdef CONFIG_VSERVER_DEBUG
28183 +       (1 << VCI_KCBIT_DEBUG) |
28184 +#endif
28185 +#ifdef CONFIG_VSERVER_HISTORY
28186 +       (1 << VCI_KCBIT_HISTORY) |
28187 +#endif
28188 +
28189 +       /* inode context tagging */
28190 +#if    defined(CONFIG_TAGGING_NONE)
28191 +       (0 << VCI_KCBIT_TAGGED) |
28192 +#elif  defined(CONFIG_TAGGING_UID16)
28193 +       (1 << VCI_KCBIT_TAGGED) |
28194 +#elif  defined(CONFIG_TAGGING_GID16)
28195 +       (2 << VCI_KCBIT_TAGGED) |
28196 +#elif  defined(CONFIG_TAGGING_ID24)
28197 +       (3 << VCI_KCBIT_TAGGED) |
28198 +#elif  defined(CONFIG_TAGGING_INTERN)
28199 +       (4 << VCI_KCBIT_TAGGED) |
28200 +#elif  defined(CONFIG_TAGGING_RUNTIME)
28201 +       (5 << VCI_KCBIT_TAGGED) |
28202 +#else
28203 +       (7 << VCI_KCBIT_TAGGED) |
28204 +#endif
28205 +       0;
28206 +}
28207 +
28208 diff -NurpP --minimal linux-2.6.17.11/mm/filemap.c linux-2.6.17.11-vs2.1.1-rc31/mm/filemap.c
28209 --- linux-2.6.17.11/mm/filemap.c        2006-08-25 00:25:37 +0200
28210 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/filemap.c   2006-07-26 21:36:47 +0200
28211 @@ -1174,6 +1174,31 @@ int file_send_actor(read_descriptor_t * 
28212         return written;
28213  }
28214  
28215 +/* FIXME: It would be as simple as this, if we had a (void __user*) to write.
28216 + * We already have a kernel buffer, so it should be even simpler, right? ;)
28217 + *
28218 + * Yes, sorta.  After duplicating the complete path of generic_file_write(),
28219 + * at least some special cases could be removed, so the copy is simpler than
28220 + * the original.  But it remains a copy, so overall complexity increases.
28221 + */
28222 +static ssize_t
28223 +generic_kernel_file_write(struct file *, const char *, size_t, loff_t *);
28224 +
28225 +ssize_t generic_file_sendpage(struct file *file, struct page *page,
28226 +               int offset, size_t size, loff_t *ppos, int more)
28227 +{
28228 +       ssize_t ret;
28229 +       char *kaddr;
28230 +
28231 +       kaddr = kmap(page);
28232 +       ret = generic_kernel_file_write(file, kaddr + offset, size, ppos);
28233 +       kunmap(page);
28234 +
28235 +       return ret;
28236 +}
28237 +
28238 +EXPORT_SYMBOL(generic_file_sendpage);
28239 +
28240  ssize_t generic_file_sendfile(struct file *in_file, loff_t *ppos,
28241                          size_t count, read_actor_t actor, void *target)
28242  {
28243 @@ -1824,6 +1849,19 @@ int remove_suid(struct dentry *dentry)
28244  }
28245  EXPORT_SYMBOL(remove_suid);
28246  
28247 +static inline size_t
28248 +filemap_copy_from_kernel(struct page *page, unsigned long offset,
28249 +                        const char *buf, unsigned bytes)
28250 +{
28251 +       char *kaddr;
28252 +
28253 +       kaddr = kmap(page);
28254 +       memcpy(kaddr + offset, buf, bytes);
28255 +       kunmap(page);
28256 +
28257 +       return bytes;
28258 +}
28259 +
28260  size_t
28261  __filemap_copy_from_user_iovec(char *vaddr, 
28262                         const struct iovec *iov, size_t base, size_t bytes)
28263 @@ -2208,6 +2246,175 @@ out:
28264  }
28265  EXPORT_SYMBOL(generic_file_aio_write_nolock);
28266  
28267 +static inline void
28268 +filemap_set_next_kvec(const struct kvec **iovp, size_t *basep, size_t bytes)
28269 +{
28270 +       const struct kvec *iov = *iovp;
28271 +       size_t base = *basep;
28272 +
28273 +       while (bytes) {
28274 +               int copy = min(bytes, iov->iov_len - base);
28275 +
28276 +               bytes -= copy;
28277 +               base += copy;
28278 +               if (iov->iov_len == base) {
28279 +                       iov++;
28280 +                       base = 0;
28281 +               }
28282 +       }
28283 +       *iovp = iov;
28284 +       *basep = base;
28285 +}
28286 +
28287 +/*
28288 + * TODO:
28289 + * This largely tries to copy generic_file_aio_write_nolock(), although it
28290 + * doesn't have to be nearly as generic.  A real cleanup should either
28291 + * merge this into generic_file_aio_write_nolock() as well or keep it special
28292 + * and remove as much code as possible.
28293 + */
28294 +static ssize_t
28295 +generic_kernel_file_aio_write_nolock(struct kiocb *iocb, const struct kvec*iov,
28296 +                                    unsigned long nr_segs, loff_t *ppos)
28297 +{
28298 +       struct file *file = iocb->ki_filp;
28299 +       struct address_space * mapping = file->f_mapping;
28300 +       struct address_space_operations *a_ops = mapping->a_ops;
28301 +       size_t ocount;          /* original count */
28302 +       size_t count;           /* after file limit checks */
28303 +       struct inode    *inode = mapping->host;
28304 +       long            status = 0;
28305 +       loff_t          pos;
28306 +       struct page     *page;
28307 +       struct page     *cached_page = NULL;
28308 +       const int       isblk = S_ISBLK(inode->i_mode);
28309 +       ssize_t         written;
28310 +       ssize_t         err;
28311 +       size_t          bytes;
28312 +       struct pagevec  lru_pvec;
28313 +       const struct kvec *cur_iov = iov; /* current kvec */
28314 +       size_t          iov_base = 0;      /* offset in the current kvec */
28315 +       unsigned long   seg;
28316 +       char            *buf;
28317 +
28318 +       ocount = 0;
28319 +       for (seg = 0; seg < nr_segs; seg++) {
28320 +               const struct kvec *iv = &iov[seg];
28321 +
28322 +               /*
28323 +                * If any segment has a negative length, or the cumulative
28324 +                * length ever wraps negative then return -EINVAL.
28325 +                */
28326 +               ocount += iv->iov_len;
28327 +               if (unlikely((ssize_t)(ocount|iv->iov_len) < 0))
28328 +                       return -EINVAL;
28329 +       }
28330 +
28331 +       count = ocount;
28332 +       pos = *ppos;
28333 +       pagevec_init(&lru_pvec, 0);
28334 +
28335 +       /* We can write back this queue in page reclaim */
28336 +       current->backing_dev_info = mapping->backing_dev_info;
28337 +       written = 0;
28338 +
28339 +       err = generic_write_checks(file, &pos, &count, isblk);
28340 +       if (err)
28341 +               goto out;
28342 +
28343 +
28344 +       if (count == 0)
28345 +               goto out;
28346 +
28347 +       remove_suid(file->f_dentry);
28348 +       file_update_time(file);
28349 +
28350 +       /* There is no sane reason to use O_DIRECT */
28351 +       BUG_ON(file->f_flags & O_DIRECT);
28352 +
28353 +       buf = iov->iov_base;
28354 +       do {
28355 +               unsigned long index;
28356 +               unsigned long offset;
28357 +               size_t copied;
28358 +
28359 +               offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
28360 +               index = pos >> PAGE_CACHE_SHIFT;
28361 +               bytes = PAGE_CACHE_SIZE - offset;
28362 +               if (bytes > count)
28363 +                       bytes = count;
28364 +
28365 +               page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
28366 +               if (!page) {
28367 +                       status = -ENOMEM;
28368 +                       break;
28369 +               }
28370 +
28371 +               status = a_ops->prepare_write(file, page, offset, offset+bytes);
28372 +               if (unlikely(status)) {
28373 +                       loff_t isize = i_size_read(inode);
28374 +                       /*
28375 +                        * prepare_write() may have instantiated a few blocks
28376 +                        * outside i_size.  Trim these off again.
28377 +                        */
28378 +                       unlock_page(page);
28379 +                       page_cache_release(page);
28380 +                       if (pos + bytes > isize)
28381 +                               vmtruncate(inode, isize);
28382 +                       break;
28383 +               }
28384 +
28385 +               BUG_ON(nr_segs != 1);
28386 +               copied = filemap_copy_from_kernel(page, offset, buf, bytes);
28387 +
28388 +               flush_dcache_page(page);
28389 +               status = a_ops->commit_write(file, page, offset, offset+bytes);
28390 +               if (likely(copied > 0)) {
28391 +                       if (!status)
28392 +                               status = copied;
28393 +
28394 +                       if (status >= 0) {
28395 +                               written += status;
28396 +                               count -= status;
28397 +                               pos += status;
28398 +                               buf += status;
28399 +                               if (unlikely(nr_segs > 1))
28400 +                                       filemap_set_next_kvec(&cur_iov,
28401 +                                                       &iov_base, status);
28402 +                       }
28403 +               }
28404 +               if (unlikely(copied != bytes))
28405 +                       if (status >= 0)
28406 +                               status = -EFAULT;
28407 +               unlock_page(page);
28408 +               mark_page_accessed(page);
28409 +               page_cache_release(page);
28410 +               if (status < 0)
28411 +                       break;
28412 +               balance_dirty_pages_ratelimited(mapping);
28413 +               cond_resched();
28414 +       } while (count);
28415 +       *ppos = pos;
28416 +
28417 +       if (cached_page)
28418 +               page_cache_release(cached_page);
28419 +
28420 +       /*
28421 +        * For now, when the user asks for O_SYNC, we'll actually give O_DSYNC
28422 +        */
28423 +       if (status >= 0) {
28424 +               if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
28425 +                       status = generic_osync_inode(inode, mapping,
28426 +                                       OSYNC_METADATA|OSYNC_DATA);
28427 +       }
28428 +
28429 +       err = written ? written : status;
28430 +out:
28431 +       pagevec_lru_add(&lru_pvec);
28432 +       current->backing_dev_info = 0;
28433 +       return err;
28434 +}
28435 +
28436  ssize_t
28437  generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
28438                                 unsigned long nr_segs, loff_t *ppos)
28439 @@ -2257,6 +2464,21 @@ generic_file_write_nolock(struct file *f
28440                 ret = wait_on_sync_kiocb(&kiocb);
28441         return ret;
28442  }
28443 +
28444 +static ssize_t
28445 +generic_kernel_file_write_nolock(struct file *file, const struct kvec *iov,
28446 +                                unsigned long nr_segs, loff_t *ppos)
28447 +{
28448 +       struct kiocb kiocb;
28449 +       ssize_t ret;
28450 +
28451 +       init_sync_kiocb(&kiocb, file);
28452 +       ret = generic_kernel_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
28453 +       if (ret == -EIOCBQUEUED)
28454 +               ret = wait_on_sync_kiocb(&kiocb);
28455 +       return ret;
28456 +}
28457 +
28458  EXPORT_SYMBOL(generic_file_write_nolock);
28459  
28460  ssize_t generic_file_aio_write(struct kiocb *iocb, const char __user *buf,
28461 @@ -2311,6 +2533,21 @@ ssize_t generic_file_write(struct file *
28462  }
28463  EXPORT_SYMBOL(generic_file_write);
28464  
28465 +static ssize_t generic_kernel_file_write(struct file *file, const char *buf,
28466 +                                        size_t count, loff_t *ppos)
28467 +{
28468 +       struct inode    *inode = file->f_mapping->host;
28469 +       ssize_t         err;
28470 +       struct kvec local_iov = { .iov_base = (char *) buf,
28471 +                                 .iov_len = count };
28472 +
28473 +       mutex_lock(&inode->i_mutex);
28474 +       err = generic_kernel_file_write_nolock(file, &local_iov, 1, ppos);
28475 +       mutex_unlock(&inode->i_mutex);
28476 +
28477 +       return err;
28478 +}
28479 +
28480  ssize_t generic_file_readv(struct file *filp, const struct iovec *iov,
28481                         unsigned long nr_segs, loff_t *ppos)
28482  {
28483 diff -NurpP --minimal linux-2.6.17.11/mm/filemap_xip.c linux-2.6.17.11-vs2.1.1-rc31/mm/filemap_xip.c
28484 --- linux-2.6.17.11/mm/filemap_xip.c    2006-04-09 13:49:58 +0200
28485 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/filemap_xip.c       2006-07-09 17:07:14 +0200
28486 @@ -13,6 +13,7 @@
28487  #include <linux/module.h>
28488  #include <linux/uio.h>
28489  #include <linux/rmap.h>
28490 +#include <linux/vs_memory.h>
28491  #include <asm/tlbflush.h>
28492  #include "filemap.h"
28493  
28494 diff -NurpP --minimal linux-2.6.17.11/mm/fremap.c linux-2.6.17.11-vs2.1.1-rc31/mm/fremap.c
28495 --- linux-2.6.17.11/mm/fremap.c 2006-01-03 17:30:13 +0100
28496 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/fremap.c    2006-08-17 01:24:16 +0200
28497 @@ -15,6 +15,7 @@
28498  #include <linux/rmap.h>
28499  #include <linux/module.h>
28500  #include <linux/syscalls.h>
28501 +#include <linux/vs_memory.h>
28502  
28503  #include <asm/mmu_context.h>
28504  #include <asm/cacheflush.h>
28505 @@ -74,6 +75,8 @@ int install_page(struct mm_struct *mm, s
28506         err = -ENOMEM;
28507         if (page_mapcount(page) > INT_MAX/2)
28508                 goto unlock;
28509 +       if (!vx_rsspages_avail(mm, 1))
28510 +               goto unlock;
28511  
28512         if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte))
28513                 inc_mm_counter(mm, file_rss);
28514 diff -NurpP --minimal linux-2.6.17.11/mm/hugetlb.c linux-2.6.17.11-vs2.1.1-rc31/mm/hugetlb.c
28515 --- linux-2.6.17.11/mm/hugetlb.c        2006-06-18 04:55:36 +0200
28516 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/hugetlb.c   2006-07-09 17:07:14 +0200
28517 @@ -19,6 +19,7 @@
28518  #include <asm/pgtable.h>
28519  
28520  #include <linux/hugetlb.h>
28521 +#include <linux/vs_memory.h>
28522  #include "internal.h"
28523  
28524  const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
28525 diff -NurpP --minimal linux-2.6.17.11/mm/memory.c linux-2.6.17.11-vs2.1.1-rc31/mm/memory.c
28526 --- linux-2.6.17.11/mm/memory.c 2006-06-18 04:55:36 +0200
28527 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/memory.c    2006-07-09 17:07:14 +0200
28528 @@ -1901,6 +1901,10 @@ again:
28529                 grab_swap_token();
28530         }
28531  
28532 +       if (!vx_rsspages_avail(mm, 1)) {
28533 +               ret = VM_FAULT_OOM;
28534 +               goto out;
28535 +       }
28536         mark_page_accessed(page);
28537         lock_page(page);
28538         if (!PageSwapCache(page)) {
28539 @@ -1978,6 +1982,8 @@ static int do_anonymous_page(struct mm_s
28540                 /* Allocate our own private page. */
28541                 pte_unmap(page_table);
28542  
28543 +               if (!vx_rsspages_avail(mm, 1))
28544 +                       goto oom;
28545                 if (unlikely(anon_vma_prepare(vma)))
28546                         goto oom;
28547                 page = alloc_zeroed_user_highpage(vma, address);
28548 @@ -2056,6 +2062,9 @@ static int do_no_page(struct mm_struct *
28549                 smp_rmb(); /* serializes i_size against truncate_count */
28550         }
28551  retry:
28552 +       /* FIXME: is that check useful here? */
28553 +       if (!vx_rsspages_avail(mm, 1))
28554 +               return VM_FAULT_OOM;
28555         new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret);
28556         /*
28557          * No smp_rmb is needed here as long as there's a full
28558 @@ -2203,21 +2212,32 @@ static inline int handle_pte_fault(struc
28559         pte_t entry;
28560         pte_t old_entry;
28561         spinlock_t *ptl;
28562 +       int ret, type = VXPT_UNKNOWN;
28563  
28564         old_entry = entry = *pte;
28565         if (!pte_present(entry)) {
28566                 if (pte_none(entry)) {
28567 -                       if (!vma->vm_ops || !vma->vm_ops->nopage)
28568 -                               return do_anonymous_page(mm, vma, address,
28569 +                       if (!vma->vm_ops || !vma->vm_ops->nopage) {
28570 +                               ret = do_anonymous_page(mm, vma, address,
28571                                         pte, pmd, write_access);
28572 -                       return do_no_page(mm, vma, address,
28573 +                               type = VXPT_ANON;
28574 +                               goto out;
28575 +                       }
28576 +                       ret = do_no_page(mm, vma, address,
28577                                         pte, pmd, write_access);
28578 +                       type = VXPT_NONE;
28579 +                       goto out;
28580                 }
28581 -               if (pte_file(entry))
28582 -                       return do_file_page(mm, vma, address,
28583 +               if (pte_file(entry)) {
28584 +                       ret = do_file_page(mm, vma, address,
28585                                         pte, pmd, write_access, entry);
28586 -               return do_swap_page(mm, vma, address,
28587 +                       type = VXPT_FILE;
28588 +                       goto out;
28589 +               }
28590 +               ret = do_swap_page(mm, vma, address,
28591                                         pte, pmd, write_access, entry);
28592 +               type = VXPT_SWAP;
28593 +               goto out;
28594         }
28595  
28596         ptl = pte_lockptr(mm, pmd);
28597 @@ -2225,9 +2245,12 @@ static inline int handle_pte_fault(struc
28598         if (unlikely(!pte_same(*pte, entry)))
28599                 goto unlock;
28600         if (write_access) {
28601 -               if (!pte_write(entry))
28602 -                       return do_wp_page(mm, vma, address,
28603 +               if (!pte_write(entry)) {
28604 +                       ret = do_wp_page(mm, vma, address,
28605                                         pte, pmd, ptl, entry);
28606 +                       type = VXPT_WRITE;
28607 +                       goto out;
28608 +               }
28609                 entry = pte_mkdirty(entry);
28610         }
28611         entry = pte_mkyoung(entry);
28612 @@ -2247,7 +2270,10 @@ static inline int handle_pte_fault(struc
28613         }
28614  unlock:
28615         pte_unmap_unlock(pte, ptl);
28616 -       return VM_FAULT_MINOR;
28617 +       ret = VM_FAULT_MINOR;
28618 +out:
28619 +       vx_page_fault(mm, vma, type, ret);
28620 +       return ret;
28621  }
28622  
28623  /*
28624 diff -NurpP --minimal linux-2.6.17.11/mm/mempolicy.c linux-2.6.17.11-vs2.1.1-rc31/mm/mempolicy.c
28625 --- linux-2.6.17.11/mm/mempolicy.c      2006-06-18 04:55:36 +0200
28626 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/mempolicy.c 2006-07-09 17:07:14 +0200
28627 @@ -87,6 +87,7 @@
28628  #include <linux/seq_file.h>
28629  #include <linux/proc_fs.h>
28630  #include <linux/migrate.h>
28631 +#include <linux/vs_pid.h>
28632  
28633  #include <asm/tlbflush.h>
28634  #include <asm/uaccess.h>
28635 diff -NurpP --minimal linux-2.6.17.11/mm/mlock.c linux-2.6.17.11-vs2.1.1-rc31/mm/mlock.c
28636 --- linux-2.6.17.11/mm/mlock.c  2006-04-09 13:49:58 +0200
28637 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/mlock.c     2006-07-09 17:07:14 +0200
28638 @@ -10,6 +10,7 @@
28639  #include <linux/mm.h>
28640  #include <linux/mempolicy.h>
28641  #include <linux/syscalls.h>
28642 +#include <linux/vs_memory.h>
28643  
28644  
28645  static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
28646 @@ -65,7 +66,7 @@ success:
28647                         ret = make_pages_present(start, end);
28648         }
28649  
28650 -       vma->vm_mm->locked_vm -= pages;
28651 +       vx_vmlocked_sub(vma->vm_mm, pages);
28652  out:
28653         if (ret == -ENOMEM)
28654                 ret = -EAGAIN;
28655 @@ -123,7 +124,7 @@ static int do_mlock(unsigned long start,
28656  
28657  asmlinkage long sys_mlock(unsigned long start, size_t len)
28658  {
28659 -       unsigned long locked;
28660 +       unsigned long locked, grow;
28661         unsigned long lock_limit;
28662         int error = -ENOMEM;
28663  
28664 @@ -134,8 +135,10 @@ asmlinkage long sys_mlock(unsigned long 
28665         len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
28666         start &= PAGE_MASK;
28667  
28668 -       locked = len >> PAGE_SHIFT;
28669 -       locked += current->mm->locked_vm;
28670 +       grow = len >> PAGE_SHIFT;
28671 +       if (!vx_vmlocked_avail(current->mm, grow))
28672 +               goto out;
28673 +       locked = current->mm->locked_vm + grow;
28674  
28675         lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
28676         lock_limit >>= PAGE_SHIFT;
28677 @@ -143,6 +146,7 @@ asmlinkage long sys_mlock(unsigned long 
28678         /* check against resource limits */
28679         if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
28680                 error = do_mlock(start, len, 1);
28681 +out:
28682         up_write(&current->mm->mmap_sem);
28683         return error;
28684  }
28685 @@ -202,6 +206,8 @@ asmlinkage long sys_mlockall(int flags)
28686         lock_limit >>= PAGE_SHIFT;
28687  
28688         ret = -ENOMEM;
28689 +       if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
28690 +               goto out;
28691         if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
28692             capable(CAP_IPC_LOCK))
28693                 ret = do_mlockall(flags);
28694 diff -NurpP --minimal linux-2.6.17.11/mm/mmap.c linux-2.6.17.11-vs2.1.1-rc31/mm/mmap.c
28695 --- linux-2.6.17.11/mm/mmap.c   2006-08-25 00:25:37 +0200
28696 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/mmap.c      2006-08-25 00:12:52 +0200
28697 @@ -1126,10 +1126,10 @@ munmap_back:
28698                 kmem_cache_free(vm_area_cachep, vma);
28699         }
28700  out:   
28701 -       mm->total_vm += len >> PAGE_SHIFT;
28702 +       vx_vmpages_add(mm, len >> PAGE_SHIFT);
28703         vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
28704         if (vm_flags & VM_LOCKED) {
28705 -               mm->locked_vm += len >> PAGE_SHIFT;
28706 +               vx_vmlocked_add(mm, len >> PAGE_SHIFT);
28707                 make_pages_present(addr, addr + len);
28708         }
28709         if (flags & MAP_POPULATE) {
28710 @@ -1489,9 +1489,9 @@ static int acct_stack_growth(struct vm_a
28711                 return -ENOMEM;
28712  
28713         /* Ok, everything looks good - let it rip */
28714 -       mm->total_vm += grow;
28715 +       vx_vmpages_add(mm, grow);
28716         if (vma->vm_flags & VM_LOCKED)
28717 -               mm->locked_vm += grow;
28718 +               vx_vmlocked_add(mm, grow);
28719         vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
28720         return 0;
28721  }
28722 @@ -1644,9 +1644,9 @@ static void remove_vma_list(struct mm_st
28723         do {
28724                 long nrpages = vma_pages(vma);
28725  
28726 -               mm->total_vm -= nrpages;
28727 +               vx_vmpages_sub(mm, nrpages);
28728                 if (vma->vm_flags & VM_LOCKED)
28729 -                       mm->locked_vm -= nrpages;
28730 +                       vx_vmlocked_sub(mm, nrpages);
28731                 vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
28732                 vma = remove_vma(vma);
28733         } while (vma);
28734 @@ -1882,6 +1882,8 @@ unsigned long do_brk(unsigned long addr,
28735                 lock_limit >>= PAGE_SHIFT;
28736                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
28737                         return -EAGAIN;
28738 +               if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
28739 +                       return -ENOMEM;
28740         }
28741  
28742         /*
28743 @@ -1908,7 +1910,8 @@ unsigned long do_brk(unsigned long addr,
28744         if (mm->map_count > sysctl_max_map_count)
28745                 return -ENOMEM;
28746  
28747 -       if (security_vm_enough_memory(len >> PAGE_SHIFT))
28748 +       if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
28749 +               !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
28750                 return -ENOMEM;
28751  
28752         /* Can we just expand an old private anonymous mapping? */
28753 @@ -1933,9 +1936,9 @@ unsigned long do_brk(unsigned long addr,
28754         vma->vm_page_prot = protection_map[flags & 0x0f];
28755         vma_link(mm, vma, prev, rb_link, rb_parent);
28756  out:
28757 -       mm->total_vm += len >> PAGE_SHIFT;
28758 +       vx_vmpages_add(mm, len >> PAGE_SHIFT);
28759         if (flags & VM_LOCKED) {
28760 -               mm->locked_vm += len >> PAGE_SHIFT;
28761 +               vx_vmlocked_add(mm, len >> PAGE_SHIFT);
28762                 make_pages_present(addr, addr + len);
28763         }
28764         return addr;
28765 @@ -1961,6 +1964,11 @@ void exit_mmap(struct mm_struct *mm)
28766         free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
28767         tlb_finish_mmu(tlb, 0, end);
28768  
28769 +       set_mm_counter(mm, file_rss, 0);
28770 +       set_mm_counter(mm, anon_rss, 0);
28771 +       vx_vmpages_sub(mm, mm->total_vm);
28772 +       vx_vmlocked_sub(mm, mm->locked_vm);
28773 +
28774         /*
28775          * Walk the list again, actually closing and freeing it,
28776          * with preemption enabled, without holding any MM locks.
28777 @@ -2000,7 +2008,8 @@ int insert_vm_struct(struct mm_struct * 
28778         if (__vma && __vma->vm_start < vma->vm_end)
28779                 return -ENOMEM;
28780         if ((vma->vm_flags & VM_ACCOUNT) &&
28781 -            security_vm_enough_memory(vma_pages(vma)))
28782 +               (security_vm_enough_memory(vma_pages(vma)) ||
28783 +               !vx_vmpages_avail(mm, vma_pages(vma))))
28784                 return -ENOMEM;
28785         vma_link(mm, vma, prev, rb_link, rb_parent);
28786         return 0;
28787 @@ -2073,5 +2082,7 @@ int may_expand_vm(struct mm_struct *mm, 
28788  
28789         if (cur + npages > lim)
28790                 return 0;
28791 +       if (!vx_vmpages_avail(mm, npages))
28792 +               return 0;
28793         return 1;
28794  }
28795 diff -NurpP --minimal linux-2.6.17.11/mm/mremap.c linux-2.6.17.11-vs2.1.1-rc31/mm/mremap.c
28796 --- linux-2.6.17.11/mm/mremap.c 2006-04-09 13:49:58 +0200
28797 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/mremap.c    2006-07-09 17:07:14 +0200
28798 @@ -18,6 +18,7 @@
28799  #include <linux/highmem.h>
28800  #include <linux/security.h>
28801  #include <linux/syscalls.h>
28802 +#include <linux/vs_memory.h>
28803  
28804  #include <asm/uaccess.h>
28805  #include <asm/cacheflush.h>
28806 @@ -211,7 +212,7 @@ static unsigned long move_vma(struct vm_
28807          * If this were a serious issue, we'd add a flag to do_munmap().
28808          */
28809         hiwater_vm = mm->hiwater_vm;
28810 -       mm->total_vm += new_len >> PAGE_SHIFT;
28811 +       vx_vmpages_add(mm, new_len >> PAGE_SHIFT);
28812         vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
28813  
28814         if (do_munmap(mm, old_addr, old_len) < 0) {
28815 @@ -229,7 +230,7 @@ static unsigned long move_vma(struct vm_
28816         }
28817  
28818         if (vm_flags & VM_LOCKED) {
28819 -               mm->locked_vm += new_len >> PAGE_SHIFT;
28820 +               vx_vmlocked_add(mm, new_len >> PAGE_SHIFT);
28821                 if (new_len > old_len)
28822                         make_pages_present(new_addr + old_len,
28823                                            new_addr + new_len);
28824 @@ -336,6 +337,9 @@ unsigned long do_mremap(unsigned long ad
28825                 ret = -EAGAIN;
28826                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
28827                         goto out;
28828 +               if (!vx_vmlocked_avail(current->mm,
28829 +                       (new_len - old_len) >> PAGE_SHIFT))
28830 +                       goto out;
28831         }
28832         if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
28833                 ret = -ENOMEM;
28834 @@ -364,10 +368,10 @@ unsigned long do_mremap(unsigned long ad
28835                         vma_adjust(vma, vma->vm_start,
28836                                 addr + new_len, vma->vm_pgoff, NULL);
28837  
28838 -                       mm->total_vm += pages;
28839 +                       vx_vmpages_add(mm, pages);
28840                         vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
28841                         if (vma->vm_flags & VM_LOCKED) {
28842 -                               mm->locked_vm += pages;
28843 +                               vx_vmlocked_add(mm, pages);
28844                                 make_pages_present(addr + old_len,
28845                                                    addr + new_len);
28846                         }
28847 diff -NurpP --minimal linux-2.6.17.11/mm/nommu.c linux-2.6.17.11-vs2.1.1-rc31/mm/nommu.c
28848 --- linux-2.6.17.11/mm/nommu.c  2006-06-18 04:55:36 +0200
28849 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/nommu.c     2006-07-09 17:07:14 +0200
28850 @@ -820,7 +820,7 @@ unsigned long do_mmap_pgoff(struct file 
28851         realalloc += kobjsize(vma);
28852         askedalloc += sizeof(*vma);
28853  
28854 -       current->mm->total_vm += len >> PAGE_SHIFT;
28855 +       vx_vmpages_add(current->mm, len >> PAGE_SHIFT);
28856  
28857         add_nommu_vma(vma);
28858  
28859 @@ -937,7 +937,7 @@ int do_munmap(struct mm_struct *mm, unsi
28860         kfree(vml);
28861  
28862         update_hiwater_vm(mm);
28863 -       mm->total_vm -= len >> PAGE_SHIFT;
28864 +       vx_vmpages_sub(mm, len >> PAGE_SHIFT);
28865  
28866  #ifdef DEBUG
28867         show_process_blocks();
28868 @@ -956,7 +956,7 @@ void exit_mmap(struct mm_struct * mm)
28869                 printk("Exit_mmap:\n");
28870  #endif
28871  
28872 -               mm->total_vm = 0;
28873 +               vx_vmpages_sub(mm, mm->total_vm);
28874  
28875                 while ((tmp = mm->context.vmlist)) {
28876                         mm->context.vmlist = tmp->next;
28877 diff -NurpP --minimal linux-2.6.17.11/mm/oom_kill.c linux-2.6.17.11-vs2.1.1-rc31/mm/oom_kill.c
28878 --- linux-2.6.17.11/mm/oom_kill.c       2006-06-18 04:55:36 +0200
28879 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/oom_kill.c  2006-07-09 17:07:14 +0200
28880 @@ -66,6 +66,8 @@ unsigned long badness(struct task_struct
28881          */
28882         task_unlock(p);
28883  
28884 +       /* FIXME: add vserver badness ;) */
28885 +
28886         /*
28887          * Processes which fork a lot of child processes are likely
28888          * a good choice. We add half the vmsize of the children if they
28889 @@ -240,8 +242,8 @@ static void __oom_kill_task(task_t *p, c
28890                 return;
28891         }
28892         task_unlock(p);
28893 -       printk(KERN_ERR "%s: Killed process %d (%s).\n",
28894 -                               message, p->pid, p->comm);
28895 +       printk(KERN_ERR "%s: Killed process %d[#%u] (%s).\n",
28896 +               message, p->pid, p->xid, p->comm);
28897  
28898         /*
28899          * We give our sacrificial lamb high priority and access to
28900 diff -NurpP --minimal linux-2.6.17.11/mm/page_alloc.c linux-2.6.17.11-vs2.1.1-rc31/mm/page_alloc.c
28901 --- linux-2.6.17.11/mm/page_alloc.c     2006-06-18 04:55:36 +0200
28902 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/page_alloc.c        2006-07-09 17:07:14 +0200
28903 @@ -37,6 +37,7 @@
28904  #include <linux/nodemask.h>
28905  #include <linux/vmalloc.h>
28906  #include <linux/mempolicy.h>
28907 +#include <linux/vs_limit.h>
28908  
28909  #include <asm/tlbflush.h>
28910  #include <asm/div64.h>
28911 @@ -1375,6 +1376,8 @@ void si_meminfo(struct sysinfo *val)
28912         val->freehigh = 0;
28913  #endif
28914         val->mem_unit = PAGE_SIZE;
28915 +       if (vx_flags(VXF_VIRT_MEM, 0))
28916 +               vx_vsi_meminfo(val);
28917  }
28918  
28919  EXPORT_SYMBOL(si_meminfo);
28920 @@ -1389,6 +1392,8 @@ void si_meminfo_node(struct sysinfo *val
28921         val->totalhigh = pgdat->node_zones[ZONE_HIGHMEM].present_pages;
28922         val->freehigh = pgdat->node_zones[ZONE_HIGHMEM].free_pages;
28923         val->mem_unit = PAGE_SIZE;
28924 +       if (vx_flags(VXF_VIRT_MEM, 0))
28925 +               vx_vsi_meminfo(val);
28926  }
28927  #endif
28928  
28929 diff -NurpP --minimal linux-2.6.17.11/mm/rmap.c linux-2.6.17.11-vs2.1.1-rc31/mm/rmap.c
28930 --- linux-2.6.17.11/mm/rmap.c   2006-06-18 04:55:36 +0200
28931 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/rmap.c      2006-07-09 17:07:14 +0200
28932 @@ -53,6 +53,7 @@
28933  #include <linux/rmap.h>
28934  #include <linux/rcupdate.h>
28935  #include <linux/module.h>
28936 +#include <linux/vs_memory.h>
28937  
28938  #include <asm/tlbflush.h>
28939  
28940 diff -NurpP --minimal linux-2.6.17.11/mm/shmem.c linux-2.6.17.11-vs2.1.1-rc31/mm/shmem.c
28941 --- linux-2.6.17.11/mm/shmem.c  2006-06-18 04:55:36 +0200
28942 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/shmem.c     2006-07-09 17:07:14 +0200
28943 @@ -53,7 +53,6 @@
28944  #include <asm/pgtable.h>
28945  
28946  /* This magic number is used in glibc for posix shared memory */
28947 -#define TMPFS_MAGIC    0x01021994
28948  
28949  #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
28950  #define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
28951 @@ -1658,7 +1657,7 @@ static int shmem_statfs(struct super_blo
28952  {
28953         struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
28954  
28955 -       buf->f_type = TMPFS_MAGIC;
28956 +       buf->f_type = TMPFS_SUPER_MAGIC;
28957         buf->f_bsize = PAGE_CACHE_SIZE;
28958         buf->f_namelen = NAME_MAX;
28959         spin_lock(&sbinfo->stat_lock);
28960 @@ -2101,7 +2100,7 @@ static int shmem_fill_super(struct super
28961         sb->s_maxbytes = SHMEM_MAX_BYTES;
28962         sb->s_blocksize = PAGE_CACHE_SIZE;
28963         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
28964 -       sb->s_magic = TMPFS_MAGIC;
28965 +       sb->s_magic = TMPFS_SUPER_MAGIC;
28966         sb->s_op = &shmem_ops;
28967         sb->s_time_gran = 1;
28968  
28969 diff -NurpP --minimal linux-2.6.17.11/mm/slab.c linux-2.6.17.11-vs2.1.1-rc31/mm/slab.c
28970 --- linux-2.6.17.11/mm/slab.c   2006-06-18 04:55:37 +0200
28971 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/slab.c      2006-07-09 17:07:14 +0200
28972 @@ -489,6 +489,8 @@ struct kmem_cache {
28973  #define STATS_INC_FREEMISS(x)  do { } while (0)
28974  #endif
28975  
28976 +#include "slab_vs.h"
28977 +
28978  #if DEBUG
28979  /*
28980   * Magic nums for obj red zoning.
28981 @@ -2891,6 +2893,7 @@ static __always_inline void *__cache_all
28982  
28983         local_irq_save(save_flags);
28984         objp = ____cache_alloc(cachep, flags);
28985 +       vx_slab_alloc(cachep, flags);
28986         local_irq_restore(save_flags);
28987         objp = cache_alloc_debugcheck_after(cachep, flags, objp,
28988                                             caller);
28989 @@ -2959,6 +2962,7 @@ retry:
28990  
28991         obj = slab_get_obj(cachep, slabp, nodeid);
28992         check_slabp(cachep, slabp);
28993 +       vx_slab_alloc(cachep, flags);
28994         l3->free_objects--;
28995         /* move slabp to correct slabp list: */
28996         list_del(&slabp->list);
28997 @@ -2993,6 +2997,7 @@ static void free_block(struct kmem_cache
28998         int i;
28999         struct kmem_list3 *l3;
29000  
29001 +       // printk("·· free_block(%x) = %dx%x\n", cachep->gfpflags, nr_objects, cachep->objsize);
29002         for (i = 0; i < nr_objects; i++) {
29003                 void *objp = objpp[i];
29004                 struct slab *slabp;
29005 @@ -3086,6 +3091,7 @@ static inline void __cache_free(struct k
29006  
29007         check_irq_off();
29008         objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
29009 +       vx_slab_free(cachep);
29010  
29011         /* Make sure we are not freeing a object from another
29012          * node to the array cache on this cpu.
29013 diff -NurpP --minimal linux-2.6.17.11/mm/slab_vs.h linux-2.6.17.11-vs2.1.1-rc31/mm/slab_vs.h
29014 --- linux-2.6.17.11/mm/slab_vs.h        1970-01-01 01:00:00 +0100
29015 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/slab_vs.h   2006-07-09 17:07:14 +0200
29016 @@ -0,0 +1,23 @@
29017 +
29018 +static inline
29019 +void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
29020 +{
29021 +       int what = gfp_zone(cachep->gfpflags);
29022 +
29023 +       if (!current->vx_info)
29024 +               return;
29025 +
29026 +       atomic_add(cachep->buffer_size, &current->vx_info->cacct.slab[what]);
29027 +}
29028 +
29029 +static inline
29030 +void vx_slab_free(struct kmem_cache *cachep)
29031 +{
29032 +       int what = gfp_zone(cachep->gfpflags);
29033 +
29034 +       if (!current->vx_info)
29035 +               return;
29036 +
29037 +       atomic_sub(cachep->buffer_size, &current->vx_info->cacct.slab[what]);
29038 +}
29039 +
29040 diff -NurpP --minimal linux-2.6.17.11/mm/swapfile.c linux-2.6.17.11-vs2.1.1-rc31/mm/swapfile.c
29041 --- linux-2.6.17.11/mm/swapfile.c       2006-08-25 00:25:37 +0200
29042 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/swapfile.c  2006-08-25 00:12:52 +0200
29043 @@ -32,6 +32,7 @@
29044  #include <asm/pgtable.h>
29045  #include <asm/tlbflush.h>
29046  #include <linux/swapops.h>
29047 +#include <linux/vs_memory.h>
29048  
29049  DEFINE_SPINLOCK(swap_lock);
29050  unsigned int nr_swapfiles;
29051 @@ -1696,6 +1697,8 @@ void si_swapinfo(struct sysinfo *val)
29052         val->freeswap = nr_swap_pages + nr_to_be_unused;
29053         val->totalswap = total_swap_pages + nr_to_be_unused;
29054         spin_unlock(&swap_lock);
29055 +       if (vx_flags(VXF_VIRT_MEM, 0))
29056 +               vx_vsi_swapinfo(val);
29057  }
29058  
29059  /*
29060 diff -NurpP --minimal linux-2.6.17.11/mm/vmscan.c linux-2.6.17.11-vs2.1.1-rc31/mm/vmscan.c
29061 --- linux-2.6.17.11/mm/vmscan.c 2006-06-18 04:55:37 +0200
29062 +++ linux-2.6.17.11-vs2.1.1-rc31/mm/vmscan.c    2006-07-09 17:07:14 +0200
29063 @@ -1357,7 +1357,7 @@ static int __init kswapd_init(void)
29064                 pid = kernel_thread(kswapd, pgdat, CLONE_KERNEL);
29065                 BUG_ON(pid < 0);
29066                 read_lock(&tasklist_lock);
29067 -               pgdat->kswapd = find_task_by_pid(pid);
29068 +               pgdat->kswapd = find_task_by_real_pid(pid);
29069                 read_unlock(&tasklist_lock);
29070         }
29071         total_memory = nr_free_pagecache_pages();
29072 diff -NurpP --minimal linux-2.6.17.11/net/core/dev.c linux-2.6.17.11-vs2.1.1-rc31/net/core/dev.c
29073 --- linux-2.6.17.11/net/core/dev.c      2006-08-25 00:25:37 +0200
29074 +++ linux-2.6.17.11-vs2.1.1-rc31/net/core/dev.c 2006-07-26 21:36:47 +0200
29075 @@ -115,6 +115,7 @@
29076  #include <net/iw_handler.h>
29077  #include <asm/current.h>
29078  #include <linux/audit.h>
29079 +#include <linux/vs_network.h>
29080  
29081  /*
29082   *     The list of packet types we will receive (as opposed to discard)
29083 @@ -1945,6 +1946,9 @@ static int dev_ifconf(char __user *arg)
29084  
29085         total = 0;
29086         for (dev = dev_base; dev; dev = dev->next) {
29087 +               if (vx_flags(VXF_HIDE_NETIF, 0) &&
29088 +                       !dev_in_nx_info(dev, current->nx_info))
29089 +                       continue;
29090                 for (i = 0; i < NPROTO; i++) {
29091                         if (gifconf_list[i]) {
29092                                 int done;
29093 @@ -2005,6 +2009,10 @@ void dev_seq_stop(struct seq_file *seq, 
29094  
29095  static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
29096  {
29097 +       struct nx_info *nxi = current->nx_info;
29098 +
29099 +       if (vx_flags(VXF_HIDE_NETIF, 0) && !dev_in_nx_info(dev, nxi))
29100 +               return;
29101         if (dev->get_stats) {
29102                 struct net_device_stats *stats = dev->get_stats(dev);
29103  
29104 diff -NurpP --minimal linux-2.6.17.11/net/core/rtnetlink.c linux-2.6.17.11-vs2.1.1-rc31/net/core/rtnetlink.c
29105 --- linux-2.6.17.11/net/core/rtnetlink.c        2006-08-25 00:25:37 +0200
29106 +++ linux-2.6.17.11-vs2.1.1-rc31/net/core/rtnetlink.c   2006-08-25 00:12:52 +0200
29107 @@ -323,6 +323,9 @@ static int rtnetlink_dump_ifinfo(struct 
29108         for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
29109                 if (idx < s_idx)
29110                         continue;
29111 +               if (vx_info_flags(skb->sk->sk_vx_info, VXF_HIDE_NETIF, 0) &&
29112 +                       !dev_in_nx_info(dev, skb->sk->sk_nx_info))
29113 +                       continue;
29114                 if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK,
29115                                           NETLINK_CB(cb->skb).pid,
29116                                           cb->nlh->nlmsg_seq, 0,
29117 @@ -613,6 +616,9 @@ void rtmsg_ifinfo(int type, struct net_d
29118                                sizeof(struct rtnl_link_ifmap) +
29119                                sizeof(struct rtnl_link_stats) + 128);
29120  
29121 +       if (vx_flags(VXF_HIDE_NETIF, 0) &&
29122 +               !dev_in_nx_info(dev, current->nx_info))
29123 +               return;
29124         skb = alloc_skb(size, GFP_KERNEL);
29125         if (!skb)
29126                 return;
29127 diff -NurpP --minimal linux-2.6.17.11/net/core/sock.c linux-2.6.17.11-vs2.1.1-rc31/net/core/sock.c
29128 --- linux-2.6.17.11/net/core/sock.c     2006-06-18 04:55:39 +0200
29129 +++ linux-2.6.17.11-vs2.1.1-rc31/net/core/sock.c        2006-07-09 17:07:14 +0200
29130 @@ -125,6 +125,9 @@
29131  #include <linux/ipsec.h>
29132  
29133  #include <linux/filter.h>
29134 +#include <linux/vs_socket.h>
29135 +#include <linux/vs_limit.h>
29136 +#include <linux/vs_context.h>
29137  
29138  #ifdef CONFIG_INET
29139  #include <net/tcp.h>
29140 @@ -768,6 +771,8 @@ struct sock *sk_alloc(int family, gfp_t 
29141                         sk->sk_prot = sk->sk_prot_creator = prot;
29142                         sock_lock_init(sk);
29143                 }
29144 +               sock_vx_init(sk);
29145 +               sock_nx_init(sk);
29146                 
29147                 if (security_sk_alloc(sk, family, priority))
29148                         goto out_free;
29149 @@ -806,6 +811,11 @@ void sk_free(struct sock *sk)
29150                        __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
29151  
29152         security_sk_free(sk);
29153 +       vx_sock_dec(sk);
29154 +       clr_vx_info(&sk->sk_vx_info);
29155 +       sk->sk_xid = -1;
29156 +       clr_nx_info(&sk->sk_nx_info);
29157 +       sk->sk_nid = -1;
29158         if (sk->sk_prot_creator->slab != NULL)
29159                 kmem_cache_free(sk->sk_prot_creator->slab, sk);
29160         else
29161 @@ -823,6 +833,8 @@ struct sock *sk_clone(const struct sock 
29162                 memcpy(newsk, sk, sk->sk_prot->obj_size);
29163  
29164                 /* SANITY */
29165 +               sock_vx_init(newsk);
29166 +               sock_nx_init(newsk);
29167                 sk_node_init(&newsk->sk_node);
29168                 sock_lock_init(newsk);
29169                 bh_lock_sock(newsk);
29170 @@ -863,6 +875,12 @@ struct sock *sk_clone(const struct sock 
29171                 newsk->sk_priority = 0;
29172                 atomic_set(&newsk->sk_refcnt, 2);
29173  
29174 +               set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
29175 +               newsk->sk_xid = sk->sk_xid;
29176 +               vx_sock_inc(newsk);
29177 +               set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
29178 +               newsk->sk_nid = sk->sk_nid;
29179 +
29180                 /*
29181                  * Increment the counter in the same struct proto as the master
29182                  * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
29183 @@ -1427,6 +1445,11 @@ void sock_init_data(struct socket *sock,
29184         sk->sk_stamp.tv_sec     = -1L;
29185         sk->sk_stamp.tv_usec    = -1L;
29186  
29187 +       set_vx_info(&sk->sk_vx_info, current->vx_info);
29188 +       sk->sk_xid = vx_current_xid();
29189 +       vx_sock_inc(sk);
29190 +       set_nx_info(&sk->sk_nx_info, current->nx_info);
29191 +       sk->sk_nid = nx_current_nid();
29192         atomic_set(&sk->sk_refcnt, 1);
29193  }
29194  
29195 diff -NurpP --minimal linux-2.6.17.11/net/ipv4/af_inet.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/af_inet.c
29196 --- linux-2.6.17.11/net/ipv4/af_inet.c  2006-06-18 04:55:43 +0200
29197 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/af_inet.c     2006-07-09 17:07:14 +0200
29198 @@ -114,6 +114,7 @@
29199  #ifdef CONFIG_IP_MROUTE
29200  #include <linux/mroute.h>
29201  #endif
29202 +#include <linux/vs_limit.h>
29203  
29204  DEFINE_SNMP_STAT(struct linux_mib, net_statistics) __read_mostly;
29205  
29206 @@ -282,9 +283,11 @@ lookup_protocol:
29207         }
29208  
29209         err = -EPERM;
29210 +       if ((protocol == IPPROTO_ICMP) && vx_ccaps(VXC_RAW_ICMP))
29211 +               goto override;
29212         if (answer->capability > 0 && !capable(answer->capability))
29213                 goto out_rcu_unlock;
29214 -
29215 +override:
29216         sock->ops = answer->ops;
29217         answer_prot = answer->prot;
29218         answer_no_check = answer->no_check;
29219 @@ -401,6 +404,10 @@ int inet_bind(struct socket *sock, struc
29220         unsigned short snum;
29221         int chk_addr_ret;
29222         int err;
29223 +       __u32 s_addr;   /* Address used for validation */
29224 +       __u32 s_addr1;  /* Address used for socket */
29225 +       __u32 s_addr2;  /* Broadcast address for the socket */
29226 +       struct nx_info *nxi = sk->sk_nx_info;
29227  
29228         /* If the socket has its own bind function then use it. (RAW) */
29229         if (sk->sk_prot->bind) {
29230 @@ -411,7 +418,40 @@ int inet_bind(struct socket *sock, struc
29231         if (addr_len < sizeof(struct sockaddr_in))
29232                 goto out;
29233  
29234 -       chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
29235 +       s_addr = addr->sin_addr.s_addr;
29236 +       s_addr1 = s_addr;
29237 +       s_addr2 = 0xffffffffl;
29238 +
29239 +       vxdprintk(VXD_CBIT(net, 3),
29240 +               "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d",
29241 +               sk, sk->sk_nx_info, sk->sk_socket,
29242 +               (sk->sk_socket?sk->sk_socket->flags:0),
29243 +               VXD_QUAD(s_addr));
29244 +       if (nxi) {
29245 +               __u32 v4_bcast = nxi->v4_bcast;
29246 +               __u32 ipv4root = nxi->ipv4[0];
29247 +               int nbipv4 = nxi->nbipv4;
29248 +
29249 +               if (s_addr == 0) {
29250 +                       /* bind to any for 1-n */
29251 +                       s_addr = ipv4root;
29252 +                       s_addr1 = (nbipv4 > 1) ? 0 : s_addr;
29253 +                       s_addr2 = v4_bcast;
29254 +               } else if (s_addr == IPI_LOOPBACK) {
29255 +                       /* rewrite localhost to ipv4root */
29256 +                       s_addr = ipv4root;
29257 +                       s_addr1 = ipv4root;
29258 +               } else if (s_addr != v4_bcast) {
29259 +                       /* normal address bind */
29260 +                       if (!addr_in_nx_info(nxi, s_addr))
29261 +                               return -EADDRNOTAVAIL;
29262 +               }
29263 +       }
29264 +       chk_addr_ret = inet_addr_type(s_addr);
29265 +
29266 +       vxdprintk(VXD_CBIT(net, 3),
29267 +               "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d",
29268 +               sk, VXD_QUAD(s_addr), VXD_QUAD(s_addr1), VXD_QUAD(s_addr2));
29269  
29270         /* Not specified by any standard per-se, however it breaks too
29271          * many applications when removed.  It is unfortunate since
29272 @@ -423,7 +463,7 @@ int inet_bind(struct socket *sock, struc
29273         err = -EADDRNOTAVAIL;
29274         if (!sysctl_ip_nonlocal_bind &&
29275             !inet->freebind &&
29276 -           addr->sin_addr.s_addr != INADDR_ANY &&
29277 +           s_addr != INADDR_ANY &&
29278             chk_addr_ret != RTN_LOCAL &&
29279             chk_addr_ret != RTN_MULTICAST &&
29280             chk_addr_ret != RTN_BROADCAST)
29281 @@ -448,7 +488,8 @@ int inet_bind(struct socket *sock, struc
29282         if (sk->sk_state != TCP_CLOSE || inet->num)
29283                 goto out_release_sock;
29284  
29285 -       inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr;
29286 +       inet->rcv_saddr = inet->saddr = s_addr1;
29287 +       inet->rcv_saddr2 = s_addr2;
29288         if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
29289                 inet->saddr = 0;  /* Use device */
29290  
29291 diff -NurpP --minimal linux-2.6.17.11/net/ipv4/devinet.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/devinet.c
29292 --- linux-2.6.17.11/net/ipv4/devinet.c  2006-06-18 04:55:43 +0200
29293 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/devinet.c     2006-07-09 17:07:14 +0200
29294 @@ -609,6 +609,9 @@ int devinet_ioctl(unsigned int cmd, void
29295                 *colon = ':';
29296  
29297         if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
29298 +               struct nx_info *nxi = current->nx_info;
29299 +               int hide_netif = vx_flags(VXF_HIDE_NETIF, 0);
29300 +
29301                 if (tryaddrmatch) {
29302                         /* Matthias Andree */
29303                         /* compare label and address (4.4BSD style) */
29304 @@ -617,6 +620,8 @@ int devinet_ioctl(unsigned int cmd, void
29305                            This is checked above. */
29306                         for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
29307                              ifap = &ifa->ifa_next) {
29308 +                               if (hide_netif && !ifa_in_nx_info(ifa, nxi))
29309 +                                       continue;
29310                                 if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
29311                                     sin_orig.sin_addr.s_addr ==
29312                                                         ifa->ifa_address) {
29313 @@ -629,9 +634,12 @@ int devinet_ioctl(unsigned int cmd, void
29314                    comparing just the label */
29315                 if (!ifa) {
29316                         for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
29317 -                            ifap = &ifa->ifa_next)
29318 +                            ifap = &ifa->ifa_next) {
29319 +                               if (hide_netif && !ifa_in_nx_info(ifa, nxi))
29320 +                                       continue;
29321                                 if (!strcmp(ifr.ifr_name, ifa->ifa_label))
29322                                         break;
29323 +                       }
29324                 }
29325         }
29326  
29327 @@ -782,6 +790,9 @@ static int inet_gifconf(struct net_devic
29328                 goto out;
29329  
29330         for (; ifa; ifa = ifa->ifa_next) {
29331 +               if (vx_flags(VXF_HIDE_NETIF, 0) &&
29332 +                       !ifa_in_nx_info(ifa, current->nx_info))
29333 +                       continue;
29334                 if (!buf) {
29335                         done += sizeof(ifr);
29336                         continue;
29337 @@ -1093,6 +1104,7 @@ static int inet_dump_ifaddr(struct sk_bu
29338         struct net_device *dev;
29339         struct in_device *in_dev;
29340         struct in_ifaddr *ifa;
29341 +       struct sock *sk = skb->sk;
29342         int s_ip_idx, s_idx = cb->args[0];
29343  
29344         s_ip_idx = ip_idx = cb->args[1];
29345 @@ -1110,6 +1122,9 @@ static int inet_dump_ifaddr(struct sk_bu
29346  
29347                 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
29348                      ifa = ifa->ifa_next, ip_idx++) {
29349 +                       if (sk && vx_info_flags(sk->sk_vx_info, VXF_HIDE_NETIF, 0) &&
29350 +                               !ifa_in_nx_info(ifa, sk->sk_nx_info))
29351 +                               continue;
29352                         if (ip_idx < s_ip_idx)
29353                                 continue;
29354                         if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
29355 diff -NurpP --minimal linux-2.6.17.11/net/ipv4/fib_hash.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/fib_hash.c
29356 --- linux-2.6.17.11/net/ipv4/fib_hash.c 2006-04-09 13:49:59 +0200
29357 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/fib_hash.c    2006-07-09 17:07:14 +0200
29358 @@ -989,6 +989,8 @@ static unsigned fib_flag_trans(int type,
29359         return flags;
29360  }
29361  
29362 +extern int dev_in_nx_info(struct net_device *, struct nx_info *);
29363 +
29364  /* 
29365   *     This outputs /proc/net/route.
29366   *
29367 @@ -1019,7 +1021,8 @@ static int fib_seq_show(struct seq_file 
29368         prefix  = f->fn_key;
29369         mask    = FZ_MASK(iter->zone);
29370         flags   = fib_flag_trans(fa->fa_type, mask, fi);
29371 -       if (fi)
29372 +       if (fi && (!vx_flags(VXF_HIDE_NETIF, 0) ||
29373 +               dev_in_nx_info(fi->fib_dev, current->nx_info)))
29374                 snprintf(bf, sizeof(bf),
29375                          "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
29376                          fi->fib_dev ? fi->fib_dev->name : "*", prefix,
29377 diff -NurpP --minimal linux-2.6.17.11/net/ipv4/inet_connection_sock.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/inet_connection_sock.c
29378 --- linux-2.6.17.11/net/ipv4/inet_connection_sock.c     2006-06-18 04:55:43 +0200
29379 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/inet_connection_sock.c        2006-07-09 17:07:14 +0200
29380 @@ -40,7 +40,6 @@ int sysctl_local_port_range[2] = { 1024,
29381  int inet_csk_bind_conflict(const struct sock *sk,
29382                            const struct inet_bind_bucket *tb)
29383  {
29384 -       const u32 sk_rcv_saddr = inet_rcv_saddr(sk);
29385         struct sock *sk2;
29386         struct hlist_node *node;
29387         int reuse = sk->sk_reuse;
29388 @@ -53,9 +52,8 @@ int inet_csk_bind_conflict(const struct 
29389                      sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
29390                         if (!reuse || !sk2->sk_reuse ||
29391                             sk2->sk_state == TCP_LISTEN) {
29392 -                               const u32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
29393 -                               if (!sk2_rcv_saddr || !sk_rcv_saddr ||
29394 -                                   sk2_rcv_saddr == sk_rcv_saddr)
29395 +                               if (nx_addr_conflict(sk->sk_nx_info,
29396 +                                       inet_rcv_saddr(sk), sk2))
29397                                         break;
29398                         }
29399                 }
29400 diff -NurpP --minimal linux-2.6.17.11/net/ipv4/inet_diag.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/inet_diag.c
29401 --- linux-2.6.17.11/net/ipv4/inet_diag.c        2006-04-09 13:49:59 +0200
29402 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/inet_diag.c   2006-08-06 06:06:12 +0200
29403 @@ -694,6 +694,8 @@ static int inet_diag_dump(struct sk_buff
29404                         sk_for_each(sk, node, &hashinfo->listening_hash[i]) {
29405                                 struct inet_sock *inet = inet_sk(sk);
29406  
29407 +                               if (!vx_check(sk->sk_xid, VX_WATCH_P|VX_IDENT))
29408 +                                       continue;
29409                                 if (num < s_num) {
29410                                         num++;
29411                                         continue;
29412 @@ -754,6 +756,8 @@ skip_listen_ht:
29413                 sk_for_each(sk, node, &head->chain) {
29414                         struct inet_sock *inet = inet_sk(sk);
29415  
29416 +                       if (!vx_check(sk->sk_xid, VX_WATCH_P|VX_IDENT))
29417 +                               continue;
29418                         if (num < s_num)
29419                                 goto next_normal;
29420                         if (!(r->idiag_states & (1 << sk->sk_state)))
29421 @@ -778,6 +782,8 @@ next_normal:
29422                         inet_twsk_for_each(tw, node,
29423                                     &hashinfo->ehash[i + hashinfo->ehash_size].chain) {
29424  
29425 +                               if (!vx_check(tw->tw_xid, VX_WATCH_P|VX_IDENT))
29426 +                                       continue;
29427                                 if (num < s_num)
29428                                         goto next_dying;
29429                                 if (r->id.idiag_sport != tw->tw_sport &&
29430 diff -NurpP --minimal linux-2.6.17.11/net/ipv4/inet_hashtables.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/inet_hashtables.c
29431 --- linux-2.6.17.11/net/ipv4/inet_hashtables.c  2006-06-18 04:55:43 +0200
29432 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/inet_hashtables.c     2006-07-09 17:07:14 +0200
29433 @@ -139,11 +139,10 @@ struct sock *__inet_lookup_listener(cons
29434                         const __u32 rcv_saddr = inet->rcv_saddr;
29435                         int score = sk->sk_family == PF_INET ? 1 : 0;
29436  
29437 -                       if (rcv_saddr) {
29438 -                               if (rcv_saddr != daddr)
29439 -                                       continue;
29440 +                       if (inet_addr_match(sk->sk_nx_info, daddr, rcv_saddr))
29441                                 score += 2;
29442 -                       }
29443 +                       else
29444 +                               continue;
29445                         if (sk->sk_bound_dev_if) {
29446                                 if (sk->sk_bound_dev_if != dif)
29447                                         continue;
29448 diff -NurpP --minimal linux-2.6.17.11/net/ipv4/raw.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/raw.c
29449 --- linux-2.6.17.11/net/ipv4/raw.c      2006-06-18 04:55:45 +0200
29450 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/raw.c 2006-08-06 06:06:25 +0200
29451 @@ -102,6 +102,27 @@ static void raw_v4_unhash(struct sock *s
29452         write_unlock_bh(&raw_v4_lock);
29453  }
29454  
29455 +
29456 +/*
29457 + *     Check if a given address matches for a socket
29458 + *
29459 + *     nxi:            the socket's nx_info if any
29460 + *     addr:           to be verified address
29461 + *     saddr/baddr:    socket addresses
29462 + */
29463 +static inline int raw_addr_match (
29464 +       struct nx_info *nxi,
29465 +       uint32_t addr,
29466 +       uint32_t saddr,
29467 +       uint32_t baddr)
29468 +{
29469 +       if (addr && (saddr == addr || baddr == addr))
29470 +               return 1;
29471 +       if (!saddr)
29472 +               return addr_in_nx_info(nxi, addr);
29473 +       return 0;
29474 +}
29475 +
29476  struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
29477                              unsigned long raddr, unsigned long laddr,
29478                              int dif)
29479 @@ -113,7 +134,8 @@ struct sock *__raw_v4_lookup(struct sock
29480  
29481                 if (inet->num == num                                    &&
29482                     !(inet->daddr && inet->daddr != raddr)              &&
29483 -                   !(inet->rcv_saddr && inet->rcv_saddr != laddr)      &&
29484 +                   raw_addr_match(sk->sk_nx_info, laddr,
29485 +                       inet->rcv_saddr, inet->rcv_saddr2)              &&
29486                     !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
29487                         goto found; /* gotcha */
29488         }
29489 @@ -313,6 +335,11 @@ static int raw_send_hdrinc(struct sock *
29490                 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
29491         }
29492  
29493 +       err = -EPERM;
29494 +       if (!vx_check(0, VX_ADMIN) && !capable(CAP_NET_RAW)
29495 +               && (!addr_in_nx_info(sk->sk_nx_info, iph->saddr)))
29496 +               goto error_free;
29497 +
29498         err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
29499                       dst_output);
29500         if (err > 0)
29501 @@ -324,6 +351,7 @@ out:
29502  
29503  error_fault:
29504         err = -EFAULT;
29505 +error_free:
29506         kfree_skb(skb);
29507  error:
29508         IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
29509 @@ -484,6 +512,12 @@ static int raw_sendmsg(struct kiocb *ioc
29510                 if (!inet->hdrincl)
29511                         raw_probe_proto_opt(&fl, msg);
29512  
29513 +               if (sk->sk_nx_info) {
29514 +                       err = ip_find_src(sk->sk_nx_info, &rt, &fl);
29515 +
29516 +                       if (err)
29517 +                               goto done;
29518 +               }
29519                 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
29520         }
29521         if (err)
29522 @@ -787,7 +821,8 @@ static struct sock *raw_get_first(struct
29523                 struct hlist_node *node;
29524  
29525                 sk_for_each(sk, node, &raw_v4_htable[state->bucket])
29526 -                       if (sk->sk_family == PF_INET)
29527 +                       if (sk->sk_family == PF_INET &&
29528 +                               vx_check(sk->sk_xid, VX_WATCH_P|VX_IDENT))
29529                                 goto found;
29530         }
29531         sk = NULL;
29532 @@ -803,7 +838,8 @@ static struct sock *raw_get_next(struct 
29533                 sk = sk_next(sk);
29534  try_again:
29535                 ;
29536 -       } while (sk && sk->sk_family != PF_INET);
29537 +       } while (sk && (sk->sk_family != PF_INET ||
29538 +               !vx_check(sk->sk_xid, VX_WATCH_P|VX_IDENT)));
29539  
29540         if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) {
29541                 sk = sk_head(&raw_v4_htable[state->bucket]);
29542 diff -NurpP --minimal linux-2.6.17.11/net/ipv4/tcp.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/tcp.c
29543 --- linux-2.6.17.11/net/ipv4/tcp.c      2006-06-18 04:55:45 +0200
29544 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/tcp.c 2006-07-09 17:07:14 +0200
29545 @@ -258,6 +258,7 @@
29546  #include <linux/random.h>
29547  #include <linux/bootmem.h>
29548  #include <linux/cache.h>
29549 +#include <linux/in.h>
29550  
29551  #include <net/icmp.h>
29552  #include <net/tcp.h>
29553 diff -NurpP --minimal linux-2.6.17.11/net/ipv4/tcp_ipv4.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/tcp_ipv4.c
29554 --- linux-2.6.17.11/net/ipv4/tcp_ipv4.c 2006-06-18 04:55:45 +0200
29555 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/tcp_ipv4.c    2006-08-06 06:07:04 +0200
29556 @@ -77,6 +77,7 @@
29557  #include <linux/stddef.h>
29558  #include <linux/proc_fs.h>
29559  #include <linux/seq_file.h>
29560 +#include <linux/vserver/debug.h>
29561  
29562  int sysctl_tcp_tw_reuse;
29563  int sysctl_tcp_low_latency;
29564 @@ -1355,6 +1356,12 @@ static void *listening_get_next(struct s
29565                 req = req->dl_next;
29566                 while (1) {
29567                         while (req) {
29568 +                               vxdprintk(VXD_CBIT(net, 6),
29569 +                                       "sk,req: %p [#%d] (from %d)", req->sk,
29570 +                                       (req->sk)?req->sk->sk_xid:0, vx_current_xid());
29571 +                               if (req->sk &&
29572 +                                       !vx_check(req->sk->sk_xid, VX_WATCH_P|VX_IDENT))
29573 +                                       continue;
29574                                 if (req->rsk_ops->family == st->family) {
29575                                         cur = req;
29576                                         goto out;
29577 @@ -1379,6 +1386,10 @@ get_req:
29578         }
29579  get_sk:
29580         sk_for_each_from(sk, node) {
29581 +               vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
29582 +                       sk, sk->sk_xid, vx_current_xid());
29583 +               if (!vx_check(sk->sk_xid, VX_WATCH_P|VX_IDENT))
29584 +                       continue;
29585                 if (sk->sk_family == st->family) {
29586                         cur = sk;
29587                         goto out;
29588 @@ -1430,18 +1441,26 @@ static void *established_get_first(struc
29589  
29590                 read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
29591                 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
29592 -                       if (sk->sk_family != st->family) {
29593 +                       vxdprintk(VXD_CBIT(net, 6),
29594 +                               "sk,egf: %p [#%d] (from %d)",
29595 +                               sk, sk->sk_xid, vx_current_xid());
29596 +                       if (!vx_check(sk->sk_xid, VX_WATCH_P|VX_IDENT))
29597 +                               continue;
29598 +                       if (sk->sk_family != st->family)
29599                                 continue;
29600 -                       }
29601                         rc = sk;
29602                         goto out;
29603                 }
29604                 st->state = TCP_SEQ_STATE_TIME_WAIT;
29605                 inet_twsk_for_each(tw, node,
29606                                    &tcp_hashinfo.ehash[st->bucket + tcp_hashinfo.ehash_size].chain) {
29607 -                       if (tw->tw_family != st->family) {
29608 +                       vxdprintk(VXD_CBIT(net, 6),
29609 +                               "tw: %p [#%d] (from %d)",
29610 +                               tw, tw->tw_xid, vx_current_xid());
29611 +                       if (!vx_check(tw->tw_xid, VX_WATCH_P|VX_IDENT))
29612 +                               continue;
29613 +                       if (tw->tw_family != st->family)
29614                                 continue;
29615 -                       }
29616                         rc = tw;
29617                         goto out;
29618                 }
29619 @@ -1465,7 +1484,8 @@ static void *established_get_next(struct
29620                 tw = cur;
29621                 tw = tw_next(tw);
29622  get_tw:
29623 -               while (tw && tw->tw_family != st->family) {
29624 +               while (tw && (tw->tw_family != st->family ||
29625 +                       !vx_check(tw->tw_xid, VX_WATCH_P|VX_IDENT))) {
29626                         tw = tw_next(tw);
29627                 }
29628                 if (tw) {
29629 @@ -1489,6 +1509,11 @@ get_tw:
29630                 sk = sk_next(sk);
29631  
29632         sk_for_each_from(sk, node) {
29633 +               vxdprintk(VXD_CBIT(net, 6),
29634 +                       "sk,egn: %p [#%d] (from %d)",
29635 +                       sk, sk->sk_xid, vx_current_xid());
29636 +               if (!vx_check(sk->sk_xid, VX_WATCH_P|VX_IDENT))
29637 +                       continue;
29638                 if (sk->sk_family == st->family)
29639                         goto found;
29640         }
29641 diff -NurpP --minimal linux-2.6.17.11/net/ipv4/tcp_minisocks.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/tcp_minisocks.c
29642 --- linux-2.6.17.11/net/ipv4/tcp_minisocks.c    2006-04-09 13:49:59 +0200
29643 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/tcp_minisocks.c       2006-07-09 17:07:14 +0200
29644 @@ -29,6 +29,10 @@
29645  #include <net/inet_common.h>
29646  #include <net/xfrm.h>
29647  
29648 +#include <linux/vs_limit.h>
29649 +#include <linux/vs_socket.h>
29650 +#include <linux/vs_context.h>
29651 +
29652  #ifdef CONFIG_SYSCTL
29653  #define SYNC_INIT 0 /* let the user enable it */
29654  #else
29655 @@ -295,6 +299,11 @@ void tcp_time_wait(struct sock *sk, int 
29656                 tcptw->tw_ts_recent     = tp->rx_opt.ts_recent;
29657                 tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp;
29658  
29659 +               tw->tw_xid              = sk->sk_xid;
29660 +               tw->tw_vx_info          = NULL;
29661 +               tw->tw_nid              = sk->sk_nid;
29662 +               tw->tw_nx_info          = NULL;
29663 +
29664  #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
29665                 if (tw->tw_family == PF_INET6) {
29666                         struct ipv6_pinfo *np = inet6_sk(sk);
29667 diff -NurpP --minimal linux-2.6.17.11/net/ipv4/udp.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/udp.c
29668 --- linux-2.6.17.11/net/ipv4/udp.c      2006-06-18 04:55:45 +0200
29669 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv4/udp.c 2006-08-17 01:24:55 +0200
29670 @@ -176,14 +176,12 @@ gotit:
29671                         struct inet_sock *inet2 = inet_sk(sk2);
29672  
29673                         if (inet2->num == snum &&
29674 -                           sk2 != sk &&
29675 -                           !ipv6_only_sock(sk2) &&
29676 +                           sk2 != sk && !ipv6_only_sock(sk2) &&
29677                             (!sk2->sk_bound_dev_if ||
29678                              !sk->sk_bound_dev_if ||
29679                              sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
29680 -                           (!inet2->rcv_saddr ||
29681 -                            !inet->rcv_saddr ||
29682 -                            inet2->rcv_saddr == inet->rcv_saddr) &&
29683 +                           nx_addr_conflict(sk->sk_nx_info,
29684 +                            inet_rcv_saddr(sk), sk2) &&
29685                             (!sk2->sk_reuse || !sk->sk_reuse))
29686                                 goto fail;
29687                 }
29688 @@ -238,6 +236,11 @@ static struct sock *udp_v4_lookup_longwa
29689                                 if (inet->rcv_saddr != daddr)
29690                                         continue;
29691                                 score+=2;
29692 +                       } else if (sk->sk_nx_info) {
29693 +                               if (addr_in_nx_info(sk->sk_nx_info, daddr))
29694 +                                       score+=2;
29695 +                               else
29696 +                                       continue;
29697                         }
29698                         if (inet->daddr) {
29699                                 if (inet->daddr != saddr)
29700 @@ -294,7 +297,8 @@ static inline struct sock *udp_v4_mcast_
29701                 if (inet->num != hnum                                   ||
29702                     (inet->daddr && inet->daddr != rmt_addr)            ||
29703                     (inet->dport != rmt_port && inet->dport)            ||
29704 -                   (inet->rcv_saddr && inet->rcv_saddr != loc_addr)    ||
29705 +                   (inet->rcv_saddr && inet->rcv_saddr != loc_addr &&
29706 +                    inet->rcv_saddr2 && inet->rcv_saddr2 != loc_addr)  ||
29707                     ipv6_only_sock(s)                                   ||
29708                     (s->sk_bound_dev_if && s->sk_bound_dev_if != dif))
29709                         continue;
29710 @@ -604,6 +608,19 @@ int udp_sendmsg(struct kiocb *iocb, stru
29711                                     .uli_u = { .ports =
29712                                                { .sport = inet->sport,
29713                                                  .dport = dport } } };
29714 +               struct nx_info *nxi = sk->sk_nx_info;
29715 +
29716 +               if (nxi) {
29717 +                       err = ip_find_src(nxi, &rt, &fl);
29718 +                       if (err)
29719 +                               goto out;
29720 +                       if (daddr == IPI_LOOPBACK && !vx_check(0, VX_ADMIN))
29721 +                               daddr = fl.fl4_dst = nxi->ipv4[0];
29722 +#ifdef CONFIG_VSERVER_REMAP_SADDR
29723 +                       if (saddr == IPI_LOOPBACK && !vx_check(0, VX_ADMIN))
29724 +                               saddr = fl.fl4_src = nxi->ipv4[0];
29725 +#endif
29726 +               }
29727                 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
29728                 if (err)
29729                         goto out;
29730 @@ -1403,8 +1420,10 @@ static struct sock *udp_get_first(struct
29731  
29732         for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
29733                 struct hlist_node *node;
29734 +
29735                 sk_for_each(sk, node, &udp_hash[state->bucket]) {
29736 -                       if (sk->sk_family == state->family)
29737 +                       if (sk->sk_family == state->family &&
29738 +                               vx_check(sk->sk_xid, VX_WATCH_P|VX_IDENT))
29739                                 goto found;
29740                 }
29741         }
29742 @@ -1421,7 +1440,8 @@ static struct sock *udp_get_next(struct 
29743                 sk = sk_next(sk);
29744  try_again:
29745                 ;
29746 -       } while (sk && sk->sk_family != state->family);
29747 +       } while (sk && (sk->sk_family != state->family ||
29748 +               !vx_check(sk->sk_xid, VX_WATCH_P|VX_IDENT)));
29749  
29750         if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
29751                 sk = sk_head(&udp_hash[state->bucket]);
29752 diff -NurpP --minimal linux-2.6.17.11/net/ipv6/addrconf.c linux-2.6.17.11-vs2.1.1-rc31/net/ipv6/addrconf.c
29753 --- linux-2.6.17.11/net/ipv6/addrconf.c 2006-08-25 00:25:37 +0200
29754 +++ linux-2.6.17.11-vs2.1.1-rc31/net/ipv6/addrconf.c    2006-07-26 21:36:47 +0200
29755 @@ -2654,7 +2654,10 @@ static void if6_seq_stop(struct seq_file
29756  static int if6_seq_show(struct seq_file *seq, void *v)
29757  {
29758         struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
29759 -       seq_printf(seq,
29760 +
29761 +       /* no ipv6 inside a vserver for now */
29762 +       if (vx_check(0, VX_ADMIN|VX_WATCH))
29763 +               seq_printf(seq,
29764                    NIP6_SEQFMT " %02x %02x %02x %02x %8s\n",
29765                    NIP6(ifp->addr),
29766                    ifp->idev->dev->ifindex,
29767 @@ -3014,6 +3017,10 @@ static int inet6_dump_addr(struct sk_buf
29768         struct ifmcaddr6 *ifmca;
29769         struct ifacaddr6 *ifaca;
29770  
29771 +       /* no ipv6 inside a vserver for now */
29772 +       if (skb->sk && skb->sk->sk_vx_info)
29773 +               return skb->len;
29774 +
29775         s_idx = cb->args[0];
29776         s_ip_idx = ip_idx = cb->args[1];
29777         read_lock(&dev_base_lock);
29778 @@ -3239,6 +3246,10 @@ static int inet6_dump_ifinfo(struct sk_b
29779         struct net_device *dev;
29780         struct inet6_dev *idev;
29781  
29782 +       /* no ipv6 inside a vserver for now */
29783 +       if (skb->sk && skb->sk->sk_vx_info)
29784 +               return skb->len;
29785 +
29786         read_lock(&dev_base_lock);
29787         for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
29788                 if (idx < s_idx)
29789 diff -NurpP --minimal linux-2.6.17.11/net/netlink/af_netlink.c linux-2.6.17.11-vs2.1.1-rc31/net/netlink/af_netlink.c
29790 --- linux-2.6.17.11/net/netlink/af_netlink.c    2006-06-18 04:55:50 +0200
29791 +++ linux-2.6.17.11-vs2.1.1-rc31/net/netlink/af_netlink.c       2006-07-09 17:07:14 +0200
29792 @@ -57,6 +57,9 @@
29793  #include <linux/types.h>
29794  #include <linux/audit.h>
29795  #include <linux/selinux.h>
29796 +#include <linux/vs_context.h>
29797 +#include <linux/vs_network.h>
29798 +#include <linux/vs_limit.h>
29799  
29800  #include <net/sock.h>
29801  #include <net/scm.h>
29802 diff -NurpP --minimal linux-2.6.17.11/net/socket.c linux-2.6.17.11-vs2.1.1-rc31/net/socket.c
29803 --- linux-2.6.17.11/net/socket.c        2006-06-18 04:55:52 +0200
29804 +++ linux-2.6.17.11-vs2.1.1-rc31/net/socket.c   2006-07-09 17:07:14 +0200
29805 @@ -94,6 +94,7 @@
29806  
29807  #include <net/sock.h>
29808  #include <linux/netfilter.h>
29809 +#include <linux/vs_socket.h>
29810  
29811  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
29812  static ssize_t sock_aio_read(struct kiocb *iocb, char __user *buf,
29813 @@ -582,7 +583,7 @@ static inline int __sock_sendmsg(struct 
29814                                  struct msghdr *msg, size_t size)
29815  {
29816         struct sock_iocb *si = kiocb_to_siocb(iocb);
29817 -       int err;
29818 +       int err, len;
29819  
29820         si->sock = sock;
29821         si->scm = NULL;
29822 @@ -593,7 +594,21 @@ static inline int __sock_sendmsg(struct 
29823         if (err)
29824                 return err;
29825  
29826 -       return sock->ops->sendmsg(iocb, sock, msg, size);
29827 +       len = sock->ops->sendmsg(iocb, sock, msg, size);
29828 +       if (sock->sk) {
29829 +               if (len == size)
29830 +                       vx_sock_send(sock->sk, size);
29831 +               else
29832 +                       vx_sock_fail(sock->sk, size);
29833 +       }
29834 +       vxdprintk(VXD_CBIT(net, 7),
29835 +               "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d",
29836 +               sock, sock->sk,
29837 +               (sock->sk)?sock->sk->sk_nx_info:0,
29838 +               (sock->sk)?sock->sk->sk_vx_info:0,
29839 +               (sock->sk)?sock->sk->sk_xid:0,
29840 +               (unsigned int)size, len);
29841 +       return len;
29842  }
29843  
29844  int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
29845 @@ -631,7 +646,7 @@ int kernel_sendmsg(struct socket *sock, 
29846  static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock, 
29847                                  struct msghdr *msg, size_t size, int flags)
29848  {
29849 -       int err;
29850 +       int err, len;
29851         struct sock_iocb *si = kiocb_to_siocb(iocb);
29852  
29853         si->sock = sock;
29854 @@ -644,7 +659,17 @@ static inline int __sock_recvmsg(struct 
29855         if (err)
29856                 return err;
29857  
29858 -       return sock->ops->recvmsg(iocb, sock, msg, size, flags);
29859 +       len = sock->ops->recvmsg(iocb, sock, msg, size, flags);
29860 +       if ((len >= 0) && sock->sk)
29861 +               vx_sock_recv(sock->sk, len);
29862 +       vxdprintk(VXD_CBIT(net, 7),
29863 +               "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d",
29864 +               sock, sock->sk,
29865 +               (sock->sk)?sock->sk->sk_nx_info:0,
29866 +               (sock->sk)?sock->sk->sk_vx_info:0,
29867 +               (sock->sk)?sock->sk->sk_xid:0,
29868 +               (unsigned int)size, len);
29869 +       return len;
29870  }
29871  
29872  int sock_recvmsg(struct socket *sock, struct msghdr *msg, 
29873 @@ -1134,6 +1159,10 @@ static int __sock_create(int family, int
29874         if (type < 0 || type >= SOCK_MAX)
29875                 return -EINVAL;
29876  
29877 +       /* disable IPv6 inside vservers for now */
29878 +       if (family == PF_INET6 && !vx_check(0, VX_ADMIN))
29879 +               return -EAFNOSUPPORT;
29880 +
29881         /* Compatibility.
29882  
29883            This uglymoron is moved from INET layer to here to avoid
29884 @@ -1244,6 +1273,7 @@ asmlinkage long sys_socket(int family, i
29885         if (retval < 0)
29886                 goto out;
29887  
29888 +       set_bit(SOCK_USER_SOCKET, &sock->flags);
29889         retval = sock_map_fd(sock);
29890         if (retval < 0)
29891                 goto out_release;
29892 @@ -1274,10 +1304,12 @@ asmlinkage long sys_socketpair(int famil
29893         err = sock_create(family, type, protocol, &sock1);
29894         if (err < 0)
29895                 goto out;
29896 +       set_bit(SOCK_USER_SOCKET, &sock1->flags);
29897  
29898         err = sock_create(family, type, protocol, &sock2);
29899         if (err < 0)
29900                 goto out_release_1;
29901 +       set_bit(SOCK_USER_SOCKET, &sock2->flags);
29902  
29903         err = sock1->ops->socketpair(sock1, sock2);
29904         if (err < 0) 
29905 diff -NurpP --minimal linux-2.6.17.11/net/sunrpc/auth.c linux-2.6.17.11-vs2.1.1-rc31/net/sunrpc/auth.c
29906 --- linux-2.6.17.11/net/sunrpc/auth.c   2006-06-18 04:55:52 +0200
29907 +++ linux-2.6.17.11-vs2.1.1-rc31/net/sunrpc/auth.c      2006-07-09 17:07:14 +0200
29908 @@ -13,6 +13,7 @@
29909  #include <linux/errno.h>
29910  #include <linux/sunrpc/clnt.h>
29911  #include <linux/spinlock.h>
29912 +#include <linux/vs_tag.h>
29913  
29914  #ifdef RPC_DEBUG
29915  # define RPCDBG_FACILITY       RPCDBG_AUTH
29916 @@ -263,6 +264,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
29917         struct auth_cred acred = {
29918                 .uid = current->fsuid,
29919                 .gid = current->fsgid,
29920 +               .tag = dx_current_tag(),
29921                 .group_info = current->group_info,
29922         };
29923         struct rpc_cred *ret;
29924 @@ -282,6 +284,7 @@ rpcauth_bindcred(struct rpc_task *task)
29925         struct auth_cred acred = {
29926                 .uid = current->fsuid,
29927                 .gid = current->fsgid,
29928 +               .tag = dx_current_tag(),
29929                 .group_info = current->group_info,
29930         };
29931         struct rpc_cred *ret;
29932 diff -NurpP --minimal linux-2.6.17.11/net/sunrpc/auth_unix.c linux-2.6.17.11-vs2.1.1-rc31/net/sunrpc/auth_unix.c
29933 --- linux-2.6.17.11/net/sunrpc/auth_unix.c      2006-02-18 14:40:43 +0100
29934 +++ linux-2.6.17.11-vs2.1.1-rc31/net/sunrpc/auth_unix.c 2006-07-09 17:07:14 +0200
29935 @@ -11,12 +11,14 @@
29936  #include <linux/module.h>
29937  #include <linux/sunrpc/clnt.h>
29938  #include <linux/sunrpc/auth.h>
29939 +#include <linux/vs_tag.h>
29940  
29941  #define NFS_NGROUPS    16
29942  
29943  struct unx_cred {
29944         struct rpc_cred         uc_base;
29945         gid_t                   uc_gid;
29946 +       tag_t                   uc_tag;
29947         gid_t                   uc_gids[NFS_NGROUPS];
29948  };
29949  #define uc_uid                 uc_base.cr_uid
29950 @@ -78,6 +80,7 @@ unx_create_cred(struct rpc_auth *auth, s
29951         if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
29952                 cred->uc_uid = 0;
29953                 cred->uc_gid = 0;
29954 +               cred->uc_tag = dx_current_tag();
29955                 cred->uc_gids[0] = NOGROUP;
29956         } else {
29957                 int groups = acred->group_info->ngroups;
29958 @@ -86,6 +89,7 @@ unx_create_cred(struct rpc_auth *auth, s
29959  
29960                 cred->uc_uid = acred->uid;
29961                 cred->uc_gid = acred->gid;
29962 +               cred->uc_tag = acred->tag;
29963                 for (i = 0; i < groups; i++)
29964                         cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
29965                 if (i < NFS_NGROUPS)
29966 @@ -117,7 +121,8 @@ unx_match(struct auth_cred *acred, struc
29967                 int groups;
29968  
29969                 if (cred->uc_uid != acred->uid
29970 -                || cred->uc_gid != acred->gid)
29971 +                || cred->uc_gid != acred->gid
29972 +                || cred->uc_tag != acred->tag)
29973                         return 0;
29974  
29975                 groups = acred->group_info->ngroups;
29976 @@ -143,7 +148,7 @@ unx_marshal(struct rpc_task *task, u32 *
29977         struct rpc_clnt *clnt = task->tk_client;
29978         struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
29979         u32             *base, *hold;
29980 -       int             i;
29981 +       int             i, tag;
29982  
29983         *p++ = htonl(RPC_AUTH_UNIX);
29984         base = p++;
29985 @@ -153,9 +158,12 @@ unx_marshal(struct rpc_task *task, u32 *
29986          * Copy the UTS nodename captured when the client was created.
29987          */
29988         p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
29989 +       tag = task->tk_client->cl_tag;
29990  
29991 -       *p++ = htonl((u32) cred->uc_uid);
29992 -       *p++ = htonl((u32) cred->uc_gid);
29993 +       *p++ = htonl((u32) TAGINO_UID(tag,
29994 +               cred->uc_uid, cred->uc_tag));
29995 +       *p++ = htonl((u32) TAGINO_GID(tag,
29996 +               cred->uc_gid, cred->uc_tag));
29997         hold = p++;
29998         for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
29999                 *p++ = htonl((u32) cred->uc_gids[i]);
30000 diff -NurpP --minimal linux-2.6.17.11/net/sunrpc/clnt.c linux-2.6.17.11-vs2.1.1-rc31/net/sunrpc/clnt.c
30001 --- linux-2.6.17.11/net/sunrpc/clnt.c   2006-06-18 04:55:52 +0200
30002 +++ linux-2.6.17.11-vs2.1.1-rc31/net/sunrpc/clnt.c      2006-07-09 17:07:14 +0200
30003 @@ -29,6 +29,7 @@
30004  #include <linux/slab.h>
30005  #include <linux/utsname.h>
30006  #include <linux/workqueue.h>
30007 +#include <linux/vs_cvirt.h>
30008  
30009  #include <linux/sunrpc/clnt.h>
30010  #include <linux/sunrpc/rpc_pipe_fs.h>
30011 @@ -176,10 +177,10 @@ rpc_new_client(struct rpc_xprt *xprt, ch
30012         }
30013  
30014         /* save the nodename */
30015 -       clnt->cl_nodelen = strlen(system_utsname.nodename);
30016 +       clnt->cl_nodelen = strlen(vx_new_uts(nodename));
30017         if (clnt->cl_nodelen > UNX_MAXNODENAME)
30018                 clnt->cl_nodelen = UNX_MAXNODENAME;
30019 -       memcpy(clnt->cl_nodename, system_utsname.nodename, clnt->cl_nodelen);
30020 +       memcpy(clnt->cl_nodename, vx_new_uts(nodename), clnt->cl_nodelen);
30021         return clnt;
30022  
30023  out_no_auth:
30024 diff -NurpP --minimal linux-2.6.17.11/net/unix/af_unix.c linux-2.6.17.11-vs2.1.1-rc31/net/unix/af_unix.c
30025 --- linux-2.6.17.11/net/unix/af_unix.c  2006-06-18 04:55:56 +0200
30026 +++ linux-2.6.17.11-vs2.1.1-rc31/net/unix/af_unix.c     2006-08-06 06:07:35 +0200
30027 @@ -117,6 +117,9 @@
30028  #include <linux/mount.h>
30029  #include <net/checksum.h>
30030  #include <linux/security.h>
30031 +#include <linux/vs_context.h>
30032 +#include <linux/vs_network.h>
30033 +#include <linux/vs_limit.h>
30034  
30035  int sysctl_unix_max_dgram_qlen = 10;
30036  
30037 @@ -235,6 +238,8 @@ static struct sock *__unix_find_socket_b
30038         sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
30039                 struct unix_sock *u = unix_sk(s);
30040  
30041 +               if (!vx_check(s->sk_xid, VX_WATCH_P|VX_IDENT))
30042 +                       continue;
30043                 if (u->addr->len == len &&
30044                     !memcmp(u->addr->name, sunname, len))
30045                         goto found;
30046 @@ -781,7 +786,7 @@ static int unix_bind(struct socket *sock
30047                  */
30048                 mode = S_IFSOCK |
30049                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
30050 -               err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
30051 +               err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
30052                 if (err)
30053                         goto out_mknod_dput;
30054                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
30055 diff -NurpP --minimal linux-2.6.17.11/net/x25/af_x25.c linux-2.6.17.11-vs2.1.1-rc31/net/x25/af_x25.c
30056 --- linux-2.6.17.11/net/x25/af_x25.c    2006-06-18 04:55:56 +0200
30057 +++ linux-2.6.17.11-vs2.1.1-rc31/net/x25/af_x25.c       2006-07-09 17:07:14 +0200
30058 @@ -502,7 +502,10 @@ static int x25_create(struct socket *soc
30059  
30060         x25 = x25_sk(sk);
30061  
30062 -       sock_init_data(sock, sk);
30063 +       sk->sk_socket = sock;
30064 +       sk->sk_type = sock->type;
30065 +       sk->sk_sleep = &sock->wait;
30066 +       sock->sk = sk;
30067  
30068         x25_init_timers(sk);
30069  
30070 diff -NurpP --minimal linux-2.6.17.11/security/commoncap.c linux-2.6.17.11-vs2.1.1-rc31/security/commoncap.c
30071 --- linux-2.6.17.11/security/commoncap.c        2006-06-18 04:55:57 +0200
30072 +++ linux-2.6.17.11-vs2.1.1-rc31/security/commoncap.c   2006-08-26 01:57:30 +0200
30073 @@ -27,7 +27,7 @@
30074  
30075  int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
30076  {
30077 -       NETLINK_CB(skb).eff_cap = current->cap_effective;
30078 +       cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
30079         return 0;
30080  }
30081  
30082 @@ -45,7 +45,7 @@ EXPORT_SYMBOL(cap_netlink_recv);
30083  int cap_capable (struct task_struct *tsk, int cap)
30084  {
30085         /* Derived from include/linux/sched.h:capable. */
30086 -       if (cap_raised(tsk->cap_effective, cap))
30087 +       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
30088                 return 0;
30089         return -EPERM;
30090  }
30091 @@ -143,7 +143,8 @@ void cap_bprm_apply_creds (struct linux_
30092         /* Derived from fs/exec.c:compute_creds. */
30093         kernel_cap_t new_permitted, working;
30094  
30095 -       new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
30096 +       new_permitted = cap_intersect (bprm->cap_permitted,
30097 +                                       vx_current_cap_bset());
30098         working = cap_intersect (bprm->cap_inheritable,
30099                                  current->cap_inheritable);
30100         new_permitted = cap_combine (new_permitted, working);
30101 @@ -312,7 +313,8 @@ void cap_task_reparent_to_init (struct t
30102  
30103  int cap_syslog (int type)
30104  {
30105 -       if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
30106 +       if ((type != 3 && type != 10) &&
30107 +               !vx_capable(CAP_SYS_ADMIN, VXC_SYSLOG))
30108                 return -EPERM;
30109         return 0;
30110  }
30111 diff -NurpP --minimal linux-2.6.17.11/security/dummy.c linux-2.6.17.11-vs2.1.1-rc31/security/dummy.c
30112 --- linux-2.6.17.11/security/dummy.c    2006-06-18 04:55:57 +0200
30113 +++ linux-2.6.17.11-vs2.1.1-rc31/security/dummy.c       2006-07-09 17:07:14 +0200
30114 @@ -85,7 +85,7 @@ static int dummy_sysctl (ctl_table * tab
30115         return 0;
30116  }
30117  
30118 -static int dummy_quotactl (int cmds, int type, int id, struct super_block *sb)
30119 +static int dummy_quotactl (int cmds, int type, int id, struct dqhash *hash)
30120  {
30121         return 0;
30122  }
30123 @@ -661,7 +661,7 @@ static int dummy_sem_semop (struct sem_a
30124  
30125  static int dummy_netlink_send (struct sock *sk, struct sk_buff *skb)
30126  {
30127 -       NETLINK_CB(skb).eff_cap = current->cap_effective;
30128 +       cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
30129         return 0;
30130  }
30131  
30132 diff -NurpP --minimal linux-2.6.17.11/security/selinux/hooks.c linux-2.6.17.11-vs2.1.1-rc31/security/selinux/hooks.c
30133 --- linux-2.6.17.11/security/selinux/hooks.c    2006-06-18 04:55:58 +0200
30134 +++ linux-2.6.17.11-vs2.1.1-rc31/security/selinux/hooks.c       2006-07-09 17:07:14 +0200
30135 @@ -1379,9 +1379,10 @@ static int selinux_sysctl(ctl_table *tab
30136         return error;
30137  }
30138  
30139 -static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
30140 +static int selinux_quotactl(int cmds, int type, int id, struct dqhash *hash)
30141  {
30142         int rc = 0;
30143 +       struct super_block *sb = hash->dqh_sb;
30144  
30145         if (!sb)
30146                 return 0;
This page took 2.533951 seconds and 3 git commands to generate.