]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.6-vs2.3.patch
- take from suse kernel-source-2.6.22.5-31.src.rpm -> patches.fixes.tar.bz2 -> patche...
[packages/kernel.git] / linux-2.6-vs2.3.patch
1 diff -NurpP --minimal linux-2.6.19.1/Documentation/vserver/debug.txt linux-2.6.19.1-vs2.3.0.6/Documentation/vserver/debug.txt
2 --- linux-2.6.19.1/Documentation/vserver/debug.txt      1970-01-01 01:00:00 +0100
3 +++ linux-2.6.19.1-vs2.3.0.6/Documentation/vserver/debug.txt    2006-11-08 04:57:48 +0100
4 @@ -0,0 +1,154 @@
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 %ld,%ld [mult=%d]"
18 + 3   8 "ext3_has_free_blocks(%p): %lu<%lu+1, %c, %u!=%u r=%d"
19 +       "ext3_has_free_blocks(%p): free=%lu, root=%lu"
20 +       "rcu_free_dl_info(%p)"
21 + 4  10 "alloc_dl_info(%p,%d) = %p"
22 +       "dealloc_dl_info(%p)"
23 +       "get_dl_info(%p[#%d.%d])"
24 +       "put_dl_info(%p[#%d.%d])"
25 + 5  20 "alloc_dl_info(%p,%d)*"
26 + 6  40 "__hash_dl_info: %p[#%d]"
27 +       "__unhash_dl_info: %p[#%d]"
28 + 7  80 "locate_dl_info(%p,#%d) = %p"
29 +
30 +debug_misc:
31 +
32 + 0   1 "destroy_dqhash: %p [#0x%08x] c=%d"
33 +       "new_dqhash: %p [#0x%08x]"
34 +       "vroot[%d]_clr_dev: dev=%p[%lu,%d:%d]"
35 +       "vroot[%d]_get_real_bdev: dev=%p[%lu,%d:%d]"
36 +       "vroot[%d]_set_dev: dev=%p[%lu,%d:%d]"
37 +       "vroot_get_real_bdev not set"
38 + 1   2 "cow_break_link(»%s«)"
39 +       "temp copy »%s«"
40 + 2   4 "dentry_open(new): %p"
41 +       "dentry_open(old): %p"
42 +       "lookup_create(new): %p"
43 +       "old path »%s«"
44 +       "path_lookup(old): %d"
45 +       "vfs_create(new): %d"
46 +       "vfs_rename: %d"
47 +       "vfs_sendfile: %d"
48 + 3   8 "fput(new_file=%p[#%d])"
49 +       "fput(old_file=%p[#%d])"
50 + 4  10 "vx_info_kill(%p[#%d],%d,%d) = %d"
51 +       "vx_info_kill(%p[#%d],%d,%d)*"
52 + 5  20 "vs_reboot(%p[#%d],%d)"
53 + 6  40 "dropping task %p[#%u,%u] for %p[#%u,%u]"
54 +
55 +debug_net:
56 +
57 + 2   4 "nx_addr_conflict(%p,%p) %d.%d,%d.%d"
58 + 3   8 "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d"
59 +       "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d"
60 + 4  10 "ip_route_connect(%p) %p,%p;%lx"
61 + 5  20 "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx"
62 + 6  40 "sk,egf: %p [#%d] (from %d)"
63 +       "sk,egn: %p [#%d] (from %d)"
64 +       "sk,req: %p [#%d] (from %d)"
65 +       "sk: %p [#%d] (from %d)"
66 +       "tw: %p [#%d] (from %d)"
67 + 7  80 "__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d"
68 +       "__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d"
69 +
70 +debug_nid:
71 +
72 + 0   1 "__lookup_nx_info(#%u): %p[#%u]"
73 +       "alloc_nx_info(%d) = %p"
74 +       "create_nx_info(%d) (dynamic rejected)"
75 +       "create_nx_info(%d) = %p (already there)"
76 +       "create_nx_info(%d) = %p (new)"
77 +       "dealloc_nx_info(%p)"
78 + 1   2 "alloc_nx_info(%d)*"
79 +       "create_nx_info(%d)*"
80 + 2   4 "get_nx_info(%p[#%d.%d])"
81 +       "put_nx_info(%p[#%d.%d])"
82 + 3   8 "claim_nx_info(%p[#%d.%d.%d]) %p"
83 +       "clr_nx_info(%p[#%d.%d])"
84 +       "init_nx_info(%p[#%d.%d])"
85 +       "release_nx_info(%p[#%d.%d.%d]) %p"
86 +       "set_nx_info(%p[#%d.%d])"
87 + 4  10 "__hash_nx_info: %p[#%d]"
88 +       "__nx_dynamic_id: [#%d]"
89 +       "__unhash_nx_info: %p[#%d]"
90 + 5  20 "moved task %p into nxi:%p[#%d]"
91 +       "nx_migrate_task(%p,%p[#%d.%d.%d])"
92 +       "task_get_nx_info(%p)"
93 + 6  40 "nx_clear_persistent(%p[#%d])"
94 +
95 +debug_quota:
96 +
97 + 0   1 "quota_sync_dqh(%p,%d) discard inode %p"
98 + 1   2 "quota_sync_dqh(%p,%d)"
99 +       "sync_dquots(%p,%d)"
100 +       "sync_dquots_dqh(%p,%d)"
101 + 3   8 "do_quotactl(%p,%d,cmd=%d,id=%d,%p)"
102 +
103 +debug_switch:
104 +
105 + 0   1 "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]"
106 + 1   2 "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]"
107 + 4  10 "%s: (%s %s) returned %s with %d"
108 +
109 +debug_tag:
110 +
111 + 7  80 "dx_parse_tag(»%s«): %d:#%d"
112 +       "dx_propagate_tag(%p[#%lu.%d]): %d,%d"
113 +
114 +debug_xid:
115 +
116 + 0   1 "__lookup_vx_info(#%u): %p[#%u]"
117 +       "alloc_vx_info(%d) = %p"
118 +       "alloc_vx_info(%d)*"
119 +       "create_vx_info(%d) (dynamic rejected)"
120 +       "create_vx_info(%d) = %p (already there)"
121 +       "create_vx_info(%d) = %p (new)"
122 +       "dealloc_vx_info(%p)"
123 +       "loc_vx_info(%d) = %p (found)"
124 +       "loc_vx_info(%d) = %p (new)"
125 +       "loc_vx_info(%d) = %p (not available)"
126 + 1   2 "create_vx_info(%d)*"
127 +       "loc_vx_info(%d)*"
128 + 2   4 "get_vx_info(%p[#%d.%d])"
129 +       "put_vx_info(%p[#%d.%d])"
130 + 3   8 "claim_vx_info(%p[#%d.%d.%d]) %p"
131 +       "clr_vx_info(%p[#%d.%d])"
132 +       "init_vx_info(%p[#%d.%d])"
133 +       "release_vx_info(%p[#%d.%d.%d]) %p"
134 +       "set_vx_info(%p[#%d.%d])"
135 +       "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]"
136 + 4  10 "__hash_vx_info: %p[#%d]"
137 +       "__unhash_vx_info: %p[#%d]"
138 +       "__vx_dynamic_id: [#%d]"
139 + 5  20 "enter_vx_info(%p[#%d],%p) %p[#%d,%p]"
140 +       "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]"
141 +       "moved task %p into vxi:%p[#%d]"
142 +       "task_get_vx_info(%p)"
143 +       "vx_migrate_task(%p,%p[#%d.%d])"
144 + 6  40 "vx_clear_persistent(%p[#%d])"
145 +       "vx_exit_init(%p[#%d],%p[#%d,%d,%d])"
146 +       "vx_set_init(%p[#%d],%p[#%d,%d,%d])"
147 +       "vx_set_persistent(%p[#%d])"
148 +       "vx_set_reaper(%p[#%d],%p[#%d,%d])"
149 +
150 +
151 +debug_limit:
152 +
153 + n 2^n "vx_acc_cres[%5d,%s,%2d]: %5d%s"
154 +       "vx_cres_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
155 +
156 + m 2^m "vx_acc_page[%5d,%s,%2d]: %5d%s"
157 +       "vx_acc_pages[%5d,%s,%2d]: %5d += %5d"
158 +       "vx_pages_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
159 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/alpha/Kconfig
160 --- linux-2.6.19.1/arch/alpha/Kconfig   2006-11-30 21:18:23 +0100
161 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/Kconfig 2006-11-08 04:57:40 +0100
162 @@ -632,6 +632,8 @@ source "arch/alpha/oprofile/Kconfig"
163  
164  source "arch/alpha/Kconfig.debug"
165  
166 +source "kernel/vserver/Kconfig"
167 +
168  source "security/Kconfig"
169  
170  source "crypto/Kconfig"
171 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/asm-offsets.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/asm-offsets.c
172 --- linux-2.6.19.1/arch/alpha/kernel/asm-offsets.c      2006-02-15 13:54:10 +0100
173 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/asm-offsets.c    2006-11-08 04:57:50 +0100
174 @@ -36,6 +36,7 @@ void foo(void)
175         DEFINE(PT_PTRACED, PT_PTRACED);
176         DEFINE(CLONE_VM, CLONE_VM);
177         DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
178 +       DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
179         DEFINE(SIGCHLD, SIGCHLD);
180         BLANK();
181  
182 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/entry.S linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/entry.S
183 --- linux-2.6.19.1/arch/alpha/kernel/entry.S    2006-11-30 21:18:23 +0100
184 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/entry.S  2006-11-08 04:57:52 +0100
185 @@ -644,7 +644,7 @@ kernel_thread:
186         stq     $2, 152($sp)            /* HAE */
187  
188         /* Shuffle FLAGS to the front; add CLONE_VM.  */
189 -       ldi     $1, CLONE_VM|CLONE_UNTRACED
190 +       ldi     $1, CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
191         or      $18, $1, $16
192         bsr     $26, sys_clone
193  
194 @@ -873,24 +873,15 @@ sys_getxgid:
195         .globl  sys_getxpid
196         .ent    sys_getxpid
197  sys_getxpid:
198 +       lda     $sp, -16($sp)
199 +       stq     $26, 0($sp)
200         .prologue 0
201 -       ldq     $2, TI_TASK($8)
202  
203 -       /* See linux/kernel/timer.c sys_getppid for discussion
204 -          about this loop.  */
205 -       ldq     $3, TASK_GROUP_LEADER($2)
206 -       ldq     $4, TASK_REAL_PARENT($3)
207 -       ldl     $0, TASK_TGID($2)
208 -1:     ldl     $1, TASK_TGID($4)
209 -#ifdef CONFIG_SMP
210 -       mov     $4, $5
211 -       mb
212 -       ldq     $3, TASK_GROUP_LEADER($2)
213 -       ldq     $4, TASK_REAL_PARENT($3)
214 -       cmpeq   $4, $5, $5
215 -       beq     $5, 1b
216 -#endif
217 -       stq     $1, 80($sp)
218 +       lda     $16, 96($sp)
219 +       jsr     $26, do_getxpid
220 +       ldq     $26, 0($sp)
221 +
222 +       lda     $sp, 16($sp)
223         ret
224  .end sys_getxpid
225  
226 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/osf_sys.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/osf_sys.c
227 --- linux-2.6.19.1/arch/alpha/kernel/osf_sys.c  2006-11-30 21:18:23 +0100
228 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/osf_sys.c        2006-12-02 01:37:05 +0100
229 @@ -885,7 +885,7 @@ osf_gettimeofday(struct timeval32 __user
230  {
231         if (tv) {
232                 struct timeval ktv;
233 -               do_gettimeofday(&ktv);
234 +               vx_gettimeofday(&ktv);
235                 if (put_tv32(tv, &ktv))
236                         return -EFAULT;
237         }
238 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/ptrace.c
239 --- linux-2.6.19.1/arch/alpha/kernel/ptrace.c   2006-04-09 13:49:39 +0200
240 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/ptrace.c 2006-11-30 18:53:18 +0100
241 @@ -15,6 +15,7 @@
242  #include <linux/slab.h>
243  #include <linux/security.h>
244  #include <linux/signal.h>
245 +#include <linux/vs_base.h>
246  
247  #include <asm/uaccess.h>
248  #include <asm/pgtable.h>
249 @@ -283,6 +284,11 @@ do_sys_ptrace(long request, long pid, lo
250                 goto out_notsk;
251         }
252  
253 +       if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT)) {
254 +               ret = -EPERM;
255 +               goto out;
256 +       }
257 +
258         if (request == PTRACE_ATTACH) {
259                 ret = ptrace_attach(child);
260                 goto out;
261 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/semaphore.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/semaphore.c
262 --- linux-2.6.19.1/arch/alpha/kernel/semaphore.c        2004-08-14 12:55:32 +0200
263 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/semaphore.c      2006-11-08 04:57:42 +0100
264 @@ -68,8 +68,8 @@ __down_failed(struct semaphore *sem)
265         DECLARE_WAITQUEUE(wait, tsk);
266  
267  #ifdef CONFIG_DEBUG_SEMAPHORE
268 -       printk("%s(%d): down failed(%p)\n",
269 -              tsk->comm, tsk->pid, sem);
270 +       printk("%s(%d:#%u): down failed(%p)\n",
271 +              tsk->comm, tsk->pid, tsk->xid, sem);
272  #endif
273  
274         tsk->state = TASK_UNINTERRUPTIBLE;
275 @@ -97,8 +97,8 @@ __down_failed(struct semaphore *sem)
276         wake_up(&sem->wait);
277  
278  #ifdef CONFIG_DEBUG_SEMAPHORE
279 -       printk("%s(%d): down acquired(%p)\n",
280 -              tsk->comm, tsk->pid, sem);
281 +       printk("%s(%d:#%u): down acquired(%p)\n",
282 +              tsk->comm, tsk->pid, tsk->xid, sem);
283  #endif
284  }
285  
286 @@ -110,8 +110,8 @@ __down_failed_interruptible(struct semap
287         long ret = 0;
288  
289  #ifdef CONFIG_DEBUG_SEMAPHORE
290 -       printk("%s(%d): down failed(%p)\n",
291 -              tsk->comm, tsk->pid, sem);
292 +       printk("%s(%d:#%u): down failed(%p)\n",
293 +              tsk->comm, tsk->pid, tsk->xid, sem);
294  #endif
295  
296         tsk->state = TASK_INTERRUPTIBLE;
297 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/systbls.S linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/systbls.S
298 --- linux-2.6.19.1/arch/alpha/kernel/systbls.S  2006-11-30 21:18:23 +0100
299 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/systbls.S        2006-11-08 04:57:41 +0100
300 @@ -446,7 +446,7 @@ sys_call_table:
301         .quad sys_stat64                        /* 425 */
302         .quad sys_lstat64
303         .quad sys_fstat64
304 -       .quad sys_ni_syscall                    /* sys_vserver */
305 +       .quad sys_vserver                       /* sys_vserver */
306         .quad sys_ni_syscall                    /* sys_mbind */
307         .quad sys_ni_syscall                    /* sys_get_mempolicy */
308         .quad sys_ni_syscall                    /* sys_set_mempolicy */
309 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/traps.c
310 --- linux-2.6.19.1/arch/alpha/kernel/traps.c    2006-09-20 16:57:57 +0200
311 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/kernel/traps.c  2006-11-08 04:57:42 +0100
312 @@ -182,7 +182,8 @@ die_if_kernel(char * str, struct pt_regs
313  #ifdef CONFIG_SMP
314         printk("CPU %d ", hard_smp_processor_id());
315  #endif
316 -       printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
317 +       printk("%s(%d[#%u]): %s %ld\n", current->comm,
318 +               current->pid, current->xid, str, err);
319         dik_show_regs(regs, r9_15);
320         dik_show_trace((unsigned long *)(regs+1));
321         dik_show_code((unsigned int *)regs->pc);
322 diff -NurpP --minimal linux-2.6.19.1/arch/alpha/mm/init.c linux-2.6.19.1-vs2.3.0.6/arch/alpha/mm/init.c
323 --- linux-2.6.19.1/arch/alpha/mm/init.c 2006-11-30 21:18:23 +0100
324 +++ linux-2.6.19.1-vs2.3.0.6/arch/alpha/mm/init.c       2006-11-08 04:57:39 +0100
325 @@ -20,6 +20,7 @@
326  #include <linux/init.h>
327  #include <linux/bootmem.h> /* max_low_pfn */
328  #include <linux/vmalloc.h>
329 +#include <linux/pagemap.h>
330  
331  #include <asm/system.h>
332  #include <asm/uaccess.h>
333 diff -NurpP --minimal linux-2.6.19.1/arch/arm/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/arm/Kconfig
334 --- linux-2.6.19.1/arch/arm/Kconfig     2006-11-30 21:18:24 +0100
335 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm/Kconfig   2006-11-30 20:55:45 +0100
336 @@ -935,6 +935,8 @@ source "arch/arm/oprofile/Kconfig"
337  
338  source "arch/arm/Kconfig.debug"
339  
340 +source "kernel/vserver/Kconfig"
341 +
342  source "security/Kconfig"
343  
344  source "crypto/Kconfig"
345 diff -NurpP --minimal linux-2.6.19.1/arch/arm/kernel/calls.S linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/calls.S
346 --- linux-2.6.19.1/arch/arm/kernel/calls.S      2006-02-18 14:39:40 +0100
347 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/calls.S    2006-11-08 04:57:41 +0100
348 @@ -322,7 +322,7 @@
349  /* 310 */      CALL(sys_request_key)
350                 CALL(sys_keyctl)
351                 CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
352 -/* vserver */  CALL(sys_ni_syscall)
353 +               CALL(sys_vserver)
354                 CALL(sys_ioprio_set)
355  /* 315 */      CALL(sys_ioprio_get)
356                 CALL(sys_inotify_init)
357 diff -NurpP --minimal linux-2.6.19.1/arch/arm/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/process.c
358 --- linux-2.6.19.1/arch/arm/kernel/process.c    2006-11-30 21:18:24 +0100
359 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/process.c  2006-11-08 04:57:50 +0100
360 @@ -246,7 +246,8 @@ void __show_regs(struct pt_regs *regs)
361  void show_regs(struct pt_regs * regs)
362  {
363         printk("\n");
364 -       printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
365 +       printk("Pid: %d[#%u], comm: %20s\n",
366 +               current->pid, current->xid, current->comm);
367         __show_regs(regs);
368         __backtrace();
369  }
370 @@ -469,7 +470,8 @@ pid_t kernel_thread(int (*fn)(void *), v
371         regs.ARM_pc = (unsigned long)kernel_thread_helper;
372         regs.ARM_cpsr = SVC_MODE;
373  
374 -       return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
375 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
376 +               0, &regs, 0, NULL, NULL);
377  }
378  EXPORT_SYMBOL(kernel_thread);
379  
380 diff -NurpP --minimal linux-2.6.19.1/arch/arm/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/traps.c
381 --- linux-2.6.19.1/arch/arm/kernel/traps.c      2006-11-30 21:18:24 +0100
382 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm/kernel/traps.c    2006-11-08 04:57:42 +0100
383 @@ -205,8 +205,8 @@ static void __die(const char *str, int e
384         printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
385         print_modules();
386         __show_regs(regs);
387 -       printk("Process %s (pid: %d, stack limit = 0x%p)\n",
388 -               tsk->comm, tsk->pid, thread + 1);
389 +       printk("Process %s (pid: %d:#%u, stack limit = 0x%p)\n",
390 +               tsk->comm, tsk->pid, tsk->xid, thread + 1);
391  
392         if (!user_mode(regs) || in_interrupt()) {
393                 dump_mem("Stack: ", regs->ARM_sp,
394 diff -NurpP --minimal linux-2.6.19.1/arch/arm26/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/arm26/Kconfig
395 --- linux-2.6.19.1/arch/arm26/Kconfig   2006-09-20 16:57:57 +0200
396 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm26/Kconfig 2006-11-08 04:57:40 +0100
397 @@ -234,6 +234,8 @@ source "drivers/usb/Kconfig"
398  
399  source "arch/arm26/Kconfig.debug"
400  
401 +source "kernel/vserver/Kconfig"
402 +
403  source "security/Kconfig"
404  
405  source "crypto/Kconfig"
406 diff -NurpP --minimal linux-2.6.19.1/arch/arm26/kernel/calls.S linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/calls.S
407 --- linux-2.6.19.1/arch/arm26/kernel/calls.S    2005-03-02 12:38:19 +0100
408 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/calls.S  2006-11-08 04:57:41 +0100
409 @@ -257,6 +257,11 @@ __syscall_start:
410                 .long   sys_lremovexattr
411                 .long   sys_fremovexattr
412                 .long   sys_tkill
413 +
414 +               .rept   313 - (. - __syscall_start) / 4
415 +                       .long   sys_ni_syscall
416 +               .endr
417 +               .long   sys_vserver     /* 313 */
418  __syscall_end:
419  
420                 .rept   NR_syscalls - (__syscall_end - __syscall_start) / 4
421 diff -NurpP --minimal linux-2.6.19.1/arch/arm26/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/process.c
422 --- linux-2.6.19.1/arch/arm26/kernel/process.c  2006-09-20 16:57:57 +0200
423 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/process.c        2006-11-08 04:57:50 +0100
424 @@ -365,7 +365,8 @@ pid_t kernel_thread(int (*fn)(void *), v
425          regs.ARM_r3 = (unsigned long)do_exit;
426          regs.ARM_pc = (unsigned long)kernel_thread_helper | MODE_SVC26;
427  
428 -        return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
429 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
430 +               0, &regs, 0, NULL, NULL);
431  }
432  EXPORT_SYMBOL(kernel_thread);
433  
434 diff -NurpP --minimal linux-2.6.19.1/arch/arm26/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/traps.c
435 --- linux-2.6.19.1/arch/arm26/kernel/traps.c    2006-09-20 16:57:57 +0200
436 +++ linux-2.6.19.1-vs2.3.0.6/arch/arm26/kernel/traps.c  2006-11-08 04:57:42 +0100
437 @@ -185,8 +185,9 @@ NORET_TYPE void die(const char *str, str
438         printk("Internal error: %s: %x\n", str, err);
439         printk("CPU: %d\n", smp_processor_id());
440         show_regs(regs);
441 -       printk("Process %s (pid: %d, stack limit = 0x%p)\n",
442 -               current->comm, current->pid, end_of_stack(tsk));
443 +       printk("Process %s (pid: %d[#%u], stack limit = 0x%p)\n",
444 +               current->comm, current->pid,
445 +               current->xid, end_of_stack(tsk));
446  
447         if (!user_mode(regs) || in_interrupt()) {
448                 __dump_stack(tsk, (unsigned long)(regs + 1));
449 diff -NurpP --minimal linux-2.6.19.1/arch/cris/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/cris/Kconfig
450 --- linux-2.6.19.1/arch/cris/Kconfig    2006-09-20 16:57:57 +0200
451 +++ linux-2.6.19.1-vs2.3.0.6/arch/cris/Kconfig  2006-11-08 04:57:40 +0100
452 @@ -185,6 +185,8 @@ source "drivers/usb/Kconfig"
453  
454  source "arch/cris/Kconfig.debug"
455  
456 +source "kernel/vserver/Kconfig"
457 +
458  source "security/Kconfig"
459  
460  source "crypto/Kconfig"
461 diff -NurpP --minimal linux-2.6.19.1/arch/cris/arch-v10/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/cris/arch-v10/kernel/process.c
462 --- linux-2.6.19.1/arch/cris/arch-v10/kernel/process.c  2006-09-20 16:57:57 +0200
463 +++ linux-2.6.19.1-vs2.3.0.6/arch/cris/arch-v10/kernel/process.c        2006-11-08 04:57:50 +0100
464 @@ -103,7 +103,8 @@ int kernel_thread(int (*fn)(void *), voi
465         regs.dccr = 1 << I_DCCR_BITNR;
466  
467         /* Ok, create the new process.. */
468 -        return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
469 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
470 +               0, &regs, 0, NULL, NULL);
471  }
472  
473  /* setup the child's kernel stack with a pt_regs and switch_stack on it.
474 diff -NurpP --minimal linux-2.6.19.1/arch/cris/arch-v32/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/cris/arch-v32/kernel/process.c
475 --- linux-2.6.19.1/arch/cris/arch-v32/kernel/process.c  2006-09-20 16:57:57 +0200
476 +++ linux-2.6.19.1-vs2.3.0.6/arch/cris/arch-v32/kernel/process.c        2006-11-08 04:57:50 +0100
477 @@ -120,7 +120,8 @@ kernel_thread(int (*fn)(void *), void * 
478         regs.ccs = 1 << (I_CCS_BITNR + CCS_SHIFT);
479  
480         /* Create the new process. */
481 -        return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
482 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
483 +               0, &regs, 0, NULL, NULL);
484  }
485  
486  /*
487 diff -NurpP --minimal linux-2.6.19.1/arch/cris/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/cris/kernel/irq.c
488 --- linux-2.6.19.1/arch/cris/kernel/irq.c       2006-09-20 16:57:57 +0200
489 +++ linux-2.6.19.1-vs2.3.0.6/arch/cris/kernel/irq.c     2006-11-30 18:26:05 +0100
490 @@ -92,6 +92,7 @@ skip:
491  asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
492  {
493         unsigned long sp;
494 +
495         irq_enter();
496         sp = rdsp();
497         if (unlikely((sp & (PAGE_SIZE - 1)) < (PAGE_SIZE/8))) {
498 diff -NurpP --minimal linux-2.6.19.1/arch/frv/kernel/kernel_thread.S linux-2.6.19.1-vs2.3.0.6/arch/frv/kernel/kernel_thread.S
499 --- linux-2.6.19.1/arch/frv/kernel/kernel_thread.S      2005-03-02 12:38:20 +0100
500 +++ linux-2.6.19.1-vs2.3.0.6/arch/frv/kernel/kernel_thread.S    2006-11-08 04:57:50 +0100
501 @@ -13,6 +13,8 @@
502  #include <asm/unistd.h>
503  
504  #define CLONE_VM       0x00000100      /* set if VM shared between processes */
505 +#define CLONE_KTHREAD  0x10000000      /* kernel thread */
506 +#define CLONE_KT       (CLONE_VM | CLONE_KTHREAD)      /* kernel thread flags */
507  #define        KERN_ERR        "<3>"
508  
509         .section .rodata
510 @@ -37,7 +39,7 @@ kernel_thread:
511  
512         # start by forking the current process, but with shared VM
513         setlos.p        #__NR_clone,gr7         ; syscall number
514 -       ori             gr10,#CLONE_VM,gr8      ; first syscall arg     [clone_flags]
515 +       ori             gr10,#CLONE_KT,gr8      ; first syscall arg     [clone_flags]
516         sethi.p         #0xe4e4,gr9             ; second syscall arg    [newsp]
517         setlo           #0xe4e4,gr9
518         setlos.p        #0,gr10                 ; third syscall arg     [parent_tidptr]
519 diff -NurpP --minimal linux-2.6.19.1/arch/h8300/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/h8300/Kconfig
520 --- linux-2.6.19.1/arch/h8300/Kconfig   2006-06-18 04:51:49 +0200
521 +++ linux-2.6.19.1-vs2.3.0.6/arch/h8300/Kconfig 2006-11-08 04:57:40 +0100
522 @@ -199,6 +199,8 @@ source "fs/Kconfig"
523  
524  source "arch/h8300/Kconfig.debug"
525  
526 +source "kernel/vserver/Kconfig"
527 +
528  source "security/Kconfig"
529  
530  source "crypto/Kconfig"
531 diff -NurpP --minimal linux-2.6.19.1/arch/h8300/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/h8300/kernel/process.c
532 --- linux-2.6.19.1/arch/h8300/kernel/process.c  2006-09-20 16:57:58 +0200
533 +++ linux-2.6.19.1-vs2.3.0.6/arch/h8300/kernel/process.c        2006-11-08 04:57:50 +0100
534 @@ -134,7 +134,7 @@ int kernel_thread(int (*fn)(void *), voi
535  
536         fs = get_fs();
537         set_fs (KERNEL_DS);
538 -       clone_arg = flags | CLONE_VM;
539 +       clone_arg = flags | CLONE_VM | CLONE_KTHREAD;
540         __asm__("mov.l sp,er3\n\t"
541                 "sub.l er2,er2\n\t"
542                 "mov.l %2,er1\n\t"
543 diff -NurpP --minimal linux-2.6.19.1/arch/i386/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/i386/Kconfig
544 --- linux-2.6.19.1/arch/i386/Kconfig    2006-11-30 21:18:25 +0100
545 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/Kconfig  2006-11-08 04:57:40 +0100
546 @@ -1153,6 +1153,8 @@ endmenu
547  
548  source "arch/i386/Kconfig.debug"
549  
550 +source "kernel/vserver/Kconfig"
551 +
552  source "security/Kconfig"
553  
554  source "crypto/Kconfig"
555 diff -NurpP --minimal linux-2.6.19.1/arch/i386/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/irq.c
556 --- linux-2.6.19.1/arch/i386/kernel/irq.c       2006-11-30 21:18:26 +0100
557 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/irq.c     2006-11-30 18:26:37 +0100
558 @@ -84,7 +84,6 @@ fastcall unsigned int do_IRQ(struct pt_r
559                 }
560         }
561  #endif
562 -
563  #ifdef CONFIG_4KSTACKS
564  
565         curctx = (union irq_ctx *) current_thread_info();
566 @@ -124,7 +123,6 @@ fastcall unsigned int do_IRQ(struct pt_r
567         } else
568  #endif
569                 desc->handle_irq(irq, desc);
570 -
571         irq_exit();
572         set_irq_regs(old_regs);
573         return 1;
574 diff -NurpP --minimal linux-2.6.19.1/arch/i386/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/process.c
575 --- linux-2.6.19.1/arch/i386/kernel/process.c   2006-11-30 21:18:26 +0100
576 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/process.c 2006-11-30 20:55:45 +0100
577 @@ -300,8 +300,10 @@ void show_regs(struct pt_regs * regs)
578         unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
579  
580         printk("\n");
581 -       printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
582 -       printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
583 +       printk("Pid: %d[#%u], comm: %20s\n",
584 +               current->pid, current->xid, current->comm);
585 +       printk("EIP: %04x:[<%08lx>] CPU: %d\n",
586 +               0xffff & regs->xcs,regs->eip, smp_processor_id());
587         print_symbol("EIP is at %s\n", regs->eip);
588  
589         if (user_mode_vm(regs))
590 @@ -352,7 +354,8 @@ int kernel_thread(int (*fn)(void *), voi
591         regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
592  
593         /* Ok, create the new process.. */
594 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
595 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
596 +               0, &regs, 0, NULL, NULL);
597  }
598  EXPORT_SYMBOL(kernel_thread);
599  
600 diff -NurpP --minimal linux-2.6.19.1/arch/i386/kernel/syscall_table.S linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/syscall_table.S
601 --- linux-2.6.19.1/arch/i386/kernel/syscall_table.S     2006-11-30 21:18:26 +0100
602 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/syscall_table.S   2006-11-08 04:57:41 +0100
603 @@ -272,7 +272,7 @@ ENTRY(sys_call_table)
604         .long sys_tgkill        /* 270 */
605         .long sys_utimes
606         .long sys_fadvise64_64
607 -       .long sys_ni_syscall    /* sys_vserver */
608 +       .long sys_vserver
609         .long sys_mbind
610         .long sys_get_mempolicy
611         .long sys_set_mempolicy
612 diff -NurpP --minimal linux-2.6.19.1/arch/i386/kernel/sysenter.c linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/sysenter.c
613 --- linux-2.6.19.1/arch/i386/kernel/sysenter.c  2006-09-20 16:57:58 +0200
614 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/sysenter.c        2006-11-08 04:57:47 +0100
615 @@ -17,6 +17,7 @@
616  #include <linux/elf.h>
617  #include <linux/mm.h>
618  #include <linux/module.h>
619 +#include <linux/vs_memory.h>
620  
621  #include <asm/cpufeature.h>
622  #include <asm/msr.h>
623 @@ -156,7 +157,7 @@ int arch_setup_additional_pages(struct l
624         current->mm->context.vdso = (void *)addr;
625         current_thread_info()->sysenter_return =
626                                     (void *)VDSO_SYM(&SYSENTER_RETURN);
627 -       mm->total_vm++;
628 +       vx_vmpages_inc(mm);
629  up_fail:
630         up_write(&mm->mmap_sem);
631         return ret;
632 diff -NurpP --minimal linux-2.6.19.1/arch/i386/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/traps.c
633 --- linux-2.6.19.1/arch/i386/kernel/traps.c     2006-11-30 21:18:26 +0100
634 +++ linux-2.6.19.1-vs2.3.0.6/arch/i386/kernel/traps.c   2006-11-30 20:55:45 +0100
635 @@ -54,6 +54,8 @@
636  #include <asm/stacktrace.h>
637  
638  #include <linux/module.h>
639 +#include <linux/vs_context.h>
640 +#include <linux/vserver/history.h>
641  
642  #include "mach_traps.h"
643  
644 @@ -371,8 +373,8 @@ void show_registers(struct pt_regs *regs
645                 regs->esi, regs->edi, regs->ebp, esp);
646         printk(KERN_EMERG "ds: %04x   es: %04x   ss: %04x\n",
647                 regs->xds & 0xffff, regs->xes & 0xffff, ss);
648 -       printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",
649 -               TASK_COMM_LEN, current->comm, current->pid,
650 +       printk(KERN_EMERG "Process %.*s (pid: %d[#%u], ti=%p task=%p task.ti=%p)",
651 +               TASK_COMM_LEN, current->comm, current->pid, current->xid,
652                 current_thread_info(), current, current->thread_info);
653         /*
654          * When in-kernel, we also print out the stack and code at the
655 @@ -461,6 +463,8 @@ void die(const char * str, struct pt_reg
656  
657         oops_enter();
658  
659 +       vxh_throw_oops();
660 +
661         if (die.lock_owner != raw_smp_processor_id()) {
662                 console_verbose();
663                 spin_lock_irqsave(&die.lock, flags);
664 @@ -497,9 +501,9 @@ void die(const char * str, struct pt_reg
665                 if (nl)
666                         printk("\n");
667                 if (notify_die(DIE_OOPS, str, regs, err,
668 -                                       current->thread.trap_no, SIGSEGV) !=
669 -                               NOTIFY_STOP) {
670 +                       current->thread.trap_no, SIGSEGV) != NOTIFY_STOP) {
671                         show_registers(regs);
672 +                       vxh_dump_history();
673                         /* Executive summary in case the oops scrolled away */
674                         esp = (unsigned long) (&regs->esp);
675                         savesegment(ss, ss);
676 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/ia64/Kconfig
677 --- linux-2.6.19.1/arch/ia64/Kconfig    2006-11-30 21:18:26 +0100
678 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/Kconfig  2006-11-20 21:12:32 +0100
679 @@ -537,6 +537,8 @@ endmenu
680  
681  source "arch/ia64/Kconfig.debug"
682  
683 +source "kernel/vserver/Kconfig"
684 +
685  source "security/Kconfig"
686  
687  source "crypto/Kconfig"
688 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/ia32/binfmt_elf32.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/binfmt_elf32.c
689 --- linux-2.6.19.1/arch/ia64/ia32/binfmt_elf32.c        2006-09-20 16:57:58 +0200
690 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/binfmt_elf32.c      2006-11-08 04:57:47 +0100
691 @@ -238,7 +238,8 @@ ia32_setup_arg_pages (struct linux_binpr
692                         kmem_cache_free(vm_area_cachep, mpnt);
693                         return ret;
694                 }
695 -               current->mm->stack_vm = current->mm->total_vm = vma_pages(mpnt);
696 +               vx_vmpages_sub(current->mm, current->mm->total_vm - vma_pages(mpnt));
697 +               current->mm->stack_vm = current->mm->total_vm;
698         }
699  
700         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
701 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/ia32/ia32_entry.S linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/ia32_entry.S
702 --- linux-2.6.19.1/arch/ia64/ia32/ia32_entry.S  2006-06-18 04:51:55 +0200
703 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/ia32_entry.S        2006-11-08 04:57:41 +0100
704 @@ -483,7 +483,7 @@ ia32_syscall_table:
705         data8 sys_tgkill        /* 270 */
706         data8 compat_sys_utimes
707         data8 sys32_fadvise64_64
708 -       data8 sys_ni_syscall
709 +       data8 sys32_vserver
710         data8 sys_ni_syscall
711         data8 sys_ni_syscall    /* 275 */
712         data8 sys_ni_syscall
713 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/ia32/sys_ia32.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/sys_ia32.c
714 --- linux-2.6.19.1/arch/ia64/ia32/sys_ia32.c    2006-11-30 21:18:26 +0100
715 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/ia32/sys_ia32.c  2006-11-08 04:57:44 +0100
716 @@ -1182,7 +1182,7 @@ sys32_gettimeofday (struct compat_timeva
717  {
718         if (tv) {
719                 struct timeval ktv;
720 -               do_gettimeofday(&ktv);
721 +               vx_gettimeofday(&ktv);
722                 if (put_tv32(tv, &ktv))
723                         return -EFAULT;
724         }
725 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/asm-offsets.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/asm-offsets.c
726 --- linux-2.6.19.1/arch/ia64/kernel/asm-offsets.c       2006-09-20 16:57:58 +0200
727 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/asm-offsets.c     2006-11-08 04:57:50 +0100
728 @@ -191,6 +191,7 @@ void foo(void)
729      /* for assembly files which can't include sched.h: */
730         DEFINE(IA64_CLONE_VFORK, CLONE_VFORK);
731         DEFINE(IA64_CLONE_VM, CLONE_VM);
732 +       DEFINE(IA64_CLONE_KTHREAD, CLONE_KTHREAD);
733  
734         BLANK();
735         DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET,
736 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/entry.S linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/entry.S
737 --- linux-2.6.19.1/arch/ia64/kernel/entry.S     2006-11-30 21:18:26 +0100
738 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/entry.S   2006-11-08 04:57:41 +0100
739 @@ -1576,7 +1576,7 @@ sys_call_table:
740         data8 sys_mq_notify
741         data8 sys_mq_getsetattr
742         data8 sys_ni_syscall                    // reserved for kexec_load
743 -       data8 sys_ni_syscall                    // reserved for vserver
744 +       data8 sys_vserver
745         data8 sys_waitid                        // 1270
746         data8 sys_add_key
747         data8 sys_request_key
748 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/perfmon.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/perfmon.c
749 --- linux-2.6.19.1/arch/ia64/kernel/perfmon.c   2006-11-30 21:18:27 +0100
750 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/perfmon.c 2006-11-08 04:57:47 +0100
751 @@ -41,6 +41,7 @@
752  #include <linux/capability.h>
753  #include <linux/rcupdate.h>
754  #include <linux/completion.h>
755 +#include <linux/vs_memory.h>
756  
757  #include <asm/errno.h>
758  #include <asm/intrinsics.h>
759 @@ -2357,7 +2358,7 @@ pfm_smpl_buffer_alloc(struct task_struct
760          */
761         insert_vm_struct(mm, vma);
762  
763 -       mm->total_vm  += size >> PAGE_SHIFT;
764 +       vx_vmpages_add(mm, size >> PAGE_SHIFT);
765         vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
766                                                         vma_pages(vma));
767         up_write(&task->mm->mmap_sem);
768 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/process.c
769 --- linux-2.6.19.1/arch/ia64/kernel/process.c   2006-11-30 21:18:27 +0100
770 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/process.c 2006-11-08 04:57:50 +0100
771 @@ -105,7 +105,8 @@ show_regs (struct pt_regs *regs)
772         unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
773  
774         print_modules();
775 -       printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
776 +       printk("\nPid: %d[#%u], CPU %d, comm: %20s\n",
777 +               current->pid, current->xid, smp_processor_id(), current->comm);
778         printk("psr : %016lx ifs : %016lx ip  : [<%016lx>]    %s\n",
779                regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
780         print_symbol("ip is at %s\n", ip);
781 @@ -688,7 +689,8 @@ kernel_thread (int (*fn)(void *), void *
782         regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR);
783         regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET;
784         regs.sw.pr = (1 << PRED_KERNEL_STACK);
785 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs.pt, 0, NULL, NULL);
786 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
787 +               0, &regs.pt, 0, NULL, NULL);
788  }
789  EXPORT_SYMBOL(kernel_thread);
790  
791 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/ptrace.c
792 --- linux-2.6.19.1/arch/ia64/kernel/ptrace.c    2006-09-20 16:57:58 +0200
793 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/ptrace.c  2006-11-30 18:53:18 +0100
794 @@ -17,6 +17,7 @@
795  #include <linux/security.h>
796  #include <linux/audit.h>
797  #include <linux/signal.h>
798 +#include <linux/vs_base.h>
799  
800  #include <asm/pgtable.h>
801  #include <asm/processor.h>
802 @@ -1442,6 +1443,9 @@ sys_ptrace (long request, pid_t pid, uns
803         read_unlock(&tasklist_lock);
804         if (!child)
805                 goto out;
806 +       if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT))
807 +               goto out_tsk;
808 +
809         ret = -EPERM;
810         if (pid == 1)           /* no messing around with init! */
811                 goto out_tsk;
812 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/traps.c
813 --- linux-2.6.19.1/arch/ia64/kernel/traps.c     2006-09-20 16:57:58 +0200
814 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/kernel/traps.c   2006-11-08 04:57:42 +0100
815 @@ -106,8 +106,9 @@ die (const char *str, struct pt_regs *re
816         put_cpu();
817  
818         if (++die.lock_owner_depth < 3) {
819 -               printk("%s[%d]: %s %ld [%d]\n",
820 -                       current->comm, current->pid, str, err, ++die_counter);
821 +               printk("%s[%d[#%u]]: %s %ld [%d]\n",
822 +                       current->comm, current->pid, current->xid,
823 +                       str, err, ++die_counter);
824                 (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
825                 show_regs(regs);
826         } else
827 @@ -331,8 +332,9 @@ handle_fpu_swa (int fp_fault, struct pt_
828                 last_time = jiffies;
829                 ++fpu_swa_count;
830                 printk(KERN_WARNING
831 -                      "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
832 -                      current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
833 +                      "%s(%d[#%u]): floating-point assist fault at ip %016lx, isr %016lx\n",
834 +                      current->comm, current->pid, current->xid,
835 +                      regs->cr_iip + ia64_psr(regs)->ri, isr);
836         }
837  
838         exception = fp_emulate(fp_fault, bundle, &regs->cr_ipsr, &regs->ar_fpsr, &isr, &regs->pr,
839 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/mm/fault.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/mm/fault.c
840 --- linux-2.6.19.1/arch/ia64/mm/fault.c 2006-11-30 21:18:27 +0100
841 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/mm/fault.c       2006-11-08 04:57:40 +0100
842 @@ -10,6 +10,7 @@
843  #include <linux/smp_lock.h>
844  #include <linux/interrupt.h>
845  #include <linux/kprobes.h>
846 +#include <linux/vs_memory.h>
847  
848  #include <asm/pgtable.h>
849  #include <asm/processor.h>
850 diff -NurpP --minimal linux-2.6.19.1/arch/ia64/sn/kernel/xpc_main.c linux-2.6.19.1-vs2.3.0.6/arch/ia64/sn/kernel/xpc_main.c
851 --- linux-2.6.19.1/arch/ia64/sn/kernel/xpc_main.c       2006-11-30 21:18:28 +0100
852 +++ linux-2.6.19.1-vs2.3.0.6/arch/ia64/sn/kernel/xpc_main.c     2006-11-08 04:57:40 +0100
853 @@ -108,6 +108,7 @@ static ctl_table xpc_sys_xpc_hb_dir[] = 
854                 0644,
855                 NULL,
856                 &proc_dointvec_minmax,
857 +               NULL,
858                 &sysctl_intvec,
859                 NULL,
860                 &xpc_hb_min_interval,
861 @@ -121,6 +122,7 @@ static ctl_table xpc_sys_xpc_hb_dir[] = 
862                 0644,
863                 NULL,
864                 &proc_dointvec_minmax,
865 +               NULL,
866                 &sysctl_intvec,
867                 NULL,
868                 &xpc_hb_check_min_interval,
869 @@ -145,6 +147,7 @@ static ctl_table xpc_sys_xpc_dir[] = {
870                 0644,
871                 NULL,
872                 &proc_dointvec_minmax,
873 +               NULL,
874                 &sysctl_intvec,
875                 NULL,
876                 &xpc_disengage_request_min_timelimit,
877 diff -NurpP --minimal linux-2.6.19.1/arch/m32r/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/irq.c
878 --- linux-2.6.19.1/arch/m32r/kernel/irq.c       2006-11-30 21:18:28 +0100
879 +++ linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/irq.c     2006-11-30 18:26:50 +0100
880 @@ -78,6 +78,7 @@ skip:
881  asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs)
882  {
883         struct pt_regs *old_regs;
884 +
885         old_regs = set_irq_regs(regs);
886         irq_enter();
887  
888 diff -NurpP --minimal linux-2.6.19.1/arch/m32r/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/process.c
889 --- linux-2.6.19.1/arch/m32r/kernel/process.c   2006-09-20 16:57:58 +0200
890 +++ linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/process.c 2006-11-08 04:57:50 +0100
891 @@ -211,8 +211,8 @@ int kernel_thread(int (*fn)(void *), voi
892         regs.psw = M32R_PSW_BIE;
893  
894         /* Ok, create the new process. */
895 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL,
896 -               NULL);
897 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
898 +               0, &regs, 0, NULL, NULL);
899  }
900  
901  /*
902 diff -NurpP --minimal linux-2.6.19.1/arch/m32r/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/traps.c
903 --- linux-2.6.19.1/arch/m32r/kernel/traps.c     2006-11-30 21:18:28 +0100
904 +++ linux-2.6.19.1-vs2.3.0.6/arch/m32r/kernel/traps.c   2006-11-08 04:57:42 +0100
905 @@ -195,8 +195,9 @@ static void show_registers(struct pt_reg
906         } else {
907                 printk("SPI: %08lx\n", sp);
908         }
909 -       printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
910 -               current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current);
911 +       printk("Process %s (pid: %d[#%u], process nr: %d, stackpage=%08lx)",
912 +               current->comm, current->pid, current->xid,
913 +               0xffff & i, 4096+(unsigned long)current);
914  
915         /*
916          * When in-kernel, we also print out the stack and code at the
917 diff -NurpP --minimal linux-2.6.19.1/arch/m68k/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/m68k/Kconfig
918 --- linux-2.6.19.1/arch/m68k/Kconfig    2006-11-30 21:18:28 +0100
919 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68k/Kconfig  2006-11-08 04:57:40 +0100
920 @@ -654,6 +654,8 @@ source "fs/Kconfig"
921  
922  source "arch/m68k/Kconfig.debug"
923  
924 +source "kernel/vserver/Kconfig"
925 +
926  source "security/Kconfig"
927  
928  source "crypto/Kconfig"
929 diff -NurpP --minimal linux-2.6.19.1/arch/m68k/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/process.c
930 --- linux-2.6.19.1/arch/m68k/kernel/process.c   2006-11-30 21:18:28 +0100
931 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/process.c 2006-11-08 04:57:50 +0100
932 @@ -159,7 +159,8 @@ int kernel_thread(int (*fn)(void *), voi
933  
934         {
935         register long retval __asm__ ("d0");
936 -       register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
937 +       register long clone_arg __asm__ ("d1") =
938 +               flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
939  
940         retval = __NR_clone;
941         __asm__ __volatile__
942 diff -NurpP --minimal linux-2.6.19.1/arch/m68k/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/ptrace.c
943 --- linux-2.6.19.1/arch/m68k/kernel/ptrace.c    2006-09-20 16:57:58 +0200
944 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/ptrace.c  2006-11-30 18:53:18 +0100
945 @@ -19,6 +19,7 @@
946  #include <linux/ptrace.h>
947  #include <linux/user.h>
948  #include <linux/signal.h>
949 +#include <linux/vs_base.h>
950  
951  #include <asm/uaccess.h>
952  #include <asm/page.h>
953 @@ -279,6 +280,8 @@ long arch_ptrace(struct task_struct *chi
954                 ret = ptrace_request(child, request, addr, data);
955                 break;
956         }
957 +       if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT))
958 +               goto out_tsk;
959  
960         return ret;
961  out_eio:
962 diff -NurpP --minimal linux-2.6.19.1/arch/m68k/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/traps.c
963 --- linux-2.6.19.1/arch/m68k/kernel/traps.c     2006-11-30 21:18:28 +0100
964 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68k/kernel/traps.c   2006-11-08 04:57:42 +0100
965 @@ -899,8 +899,8 @@ void show_registers(struct pt_regs *regs
966         printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
967                regs->d4, regs->d5, regs->a0, regs->a1);
968  
969 -       printk("Process %s (pid: %d, task=%p)\n",
970 -               current->comm, current->pid, current);
971 +       printk("Process %s (pid: %d[#%u], task=%p)\n",
972 +               current->comm, current->pid, current->xid, current);
973         addr = (unsigned long)&fp->un;
974         printk("Frame format=%X ", regs->format);
975         switch (regs->format) {
976 diff -NurpP --minimal linux-2.6.19.1/arch/m68knommu/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/Kconfig
977 --- linux-2.6.19.1/arch/m68knommu/Kconfig       2006-11-30 21:18:28 +0100
978 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/Kconfig     2006-11-08 04:57:40 +0100
979 @@ -663,6 +663,8 @@ source "fs/Kconfig"
980  
981  source "arch/m68knommu/Kconfig.debug"
982  
983 +source "kernel/vserver/Kconfig"
984 +
985  source "security/Kconfig"
986  
987  source "crypto/Kconfig"
988 diff -NurpP --minimal linux-2.6.19.1/arch/m68knommu/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/kernel/process.c
989 --- linux-2.6.19.1/arch/m68knommu/kernel/process.c      2006-09-20 16:57:58 +0200
990 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/kernel/process.c    2006-11-08 04:57:50 +0100
991 @@ -122,7 +122,7 @@ void show_regs(struct pt_regs * regs)
992  int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
993  {
994         int retval;
995 -       long clone_arg = flags | CLONE_VM;
996 +       long clone_arg = flags | CLONE_VM | CLONE_KTHREAD;
997         mm_segment_t fs;
998  
999         fs = get_fs();
1000 diff -NurpP --minimal linux-2.6.19.1/arch/m68knommu/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/kernel/traps.c
1001 --- linux-2.6.19.1/arch/m68knommu/kernel/traps.c        2006-09-20 16:57:58 +0200
1002 +++ linux-2.6.19.1-vs2.3.0.6/arch/m68knommu/kernel/traps.c      2006-11-08 04:57:42 +0100
1003 @@ -80,8 +80,9 @@ void die_if_kernel(char *str, struct pt_
1004         printk(KERN_EMERG "d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
1005                fp->d4, fp->d5, fp->a0, fp->a1);
1006  
1007 -       printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n",
1008 -               current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
1009 +       printk(KERN_EMERG "Process %s (pid: %d[#%u], stackpage=%08lx)\n",
1010 +               current->comm, current->pid, current->xid,
1011 +               PAGE_SIZE+(unsigned long)current);
1012         show_stack(NULL, (unsigned long *)fp);
1013         do_exit(SIGSEGV);
1014  }
1015 diff -NurpP --minimal linux-2.6.19.1/arch/mips/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/mips/Kconfig
1016 --- linux-2.6.19.1/arch/mips/Kconfig    2006-11-30 21:18:28 +0100
1017 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/Kconfig  2006-11-08 21:52:07 +0100
1018 @@ -2006,6 +2006,8 @@ source "arch/mips/oprofile/Kconfig"
1019  
1020  source "arch/mips/Kconfig.debug"
1021  
1022 +source "kernel/vserver/Kconfig"
1023 +
1024  source "security/Kconfig"
1025  
1026  source "crypto/Kconfig"
1027 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/linux32.c linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/linux32.c
1028 --- linux-2.6.19.1/arch/mips/kernel/linux32.c   2006-11-30 21:18:29 +0100
1029 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/linux32.c 2006-12-02 01:37:05 +0100
1030 @@ -300,7 +300,7 @@ sys32_gettimeofday(struct compat_timeval
1031  {
1032         if (tv) {
1033                 struct timeval ktv;
1034 -               do_gettimeofday(&ktv);
1035 +               vx_gettimeofday(&ktv);
1036                 if (put_tv32(tv, &ktv))
1037                         return -EFAULT;
1038         }
1039 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/process.c
1040 --- linux-2.6.19.1/arch/mips/kernel/process.c   2006-11-30 21:18:29 +0100
1041 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/process.c 2006-11-08 04:57:50 +0100
1042 @@ -271,7 +271,8 @@ long kernel_thread(int (*fn)(void *), vo
1043  #endif
1044  
1045         /* Ok, create the new process.. */
1046 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
1047 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
1048 +               0, &regs, 0, NULL, NULL);
1049  }
1050  
1051  /*
1052 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/ptrace.c
1053 --- linux-2.6.19.1/arch/mips/kernel/ptrace.c    2006-11-30 21:18:29 +0100
1054 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/ptrace.c  2006-11-30 18:53:18 +0100
1055 @@ -26,6 +26,7 @@
1056  #include <linux/user.h>
1057  #include <linux/security.h>
1058  #include <linux/signal.h>
1059 +#include <linux/vs_base.h>
1060  
1061  #include <asm/byteorder.h>
1062  #include <asm/cpu.h>
1063 @@ -172,6 +173,9 @@ long arch_ptrace(struct task_struct *chi
1064  {
1065         int ret;
1066  
1067 +       if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT))
1068 +               goto out;
1069 +
1070         switch (request) {
1071         /* when I and D space are separate, these will need to be fixed. */
1072         case PTRACE_PEEKTEXT: /* read word at location addr. */
1073 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/scall32-o32.S linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall32-o32.S
1074 --- linux-2.6.19.1/arch/mips/kernel/scall32-o32.S       2006-11-30 21:18:29 +0100
1075 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall32-o32.S     2006-11-08 04:57:41 +0100
1076 @@ -619,7 +619,7 @@ einval:     li      v0, -EINVAL
1077         sys     sys_mq_timedreceive     5
1078         sys     sys_mq_notify           2       /* 4275 */
1079         sys     sys_mq_getsetattr       3
1080 -       sys     sys_ni_syscall          0       /* sys_vserver */
1081 +       sys     sys_vserver             3
1082         sys     sys_waitid              5
1083         sys     sys_ni_syscall          0       /* available, was setaltroot */
1084         sys     sys_add_key             5       /* 4280 */
1085 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/scall64-64.S linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-64.S
1086 --- linux-2.6.19.1/arch/mips/kernel/scall64-64.S        2006-11-30 21:18:29 +0100
1087 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-64.S      2006-11-08 04:57:41 +0100
1088 @@ -434,7 +434,7 @@ sys_call_table:
1089         PTR     sys_mq_timedreceive
1090         PTR     sys_mq_notify
1091         PTR     sys_mq_getsetattr               /* 5235 */
1092 -       PTR     sys_ni_syscall                  /* sys_vserver */
1093 +       PTR     sys_vserver
1094         PTR     sys_waitid
1095         PTR     sys_ni_syscall                  /* available, was setaltroot */
1096         PTR     sys_add_key
1097 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/scall64-n32.S linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-n32.S
1098 --- linux-2.6.19.1/arch/mips/kernel/scall64-n32.S       2006-11-30 21:18:29 +0100
1099 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-n32.S     2006-11-08 04:57:41 +0100
1100 @@ -360,7 +360,7 @@ EXPORT(sysn32_call_table)
1101         PTR     compat_sys_mq_timedreceive
1102         PTR     compat_sys_mq_notify
1103         PTR     compat_sys_mq_getsetattr
1104 -       PTR     sys_ni_syscall                  /* 6240, sys_vserver */
1105 +       PTR     sys32_vserver                   /* 6240 */
1106         PTR     sysn32_waitid
1107         PTR     sys_ni_syscall                  /* available, was setaltroot */
1108         PTR     sys_add_key
1109 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/scall64-o32.S linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-o32.S
1110 --- linux-2.6.19.1/arch/mips/kernel/scall64-o32.S       2006-11-30 21:18:29 +0100
1111 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/scall64-o32.S     2006-11-08 04:57:41 +0100
1112 @@ -482,7 +482,7 @@ sys_call_table:
1113         PTR     compat_sys_mq_timedreceive
1114         PTR     compat_sys_mq_notify            /* 4275 */
1115         PTR     compat_sys_mq_getsetattr
1116 -       PTR     sys_ni_syscall                  /* sys_vserver */
1117 +       PTR     sys32_vserver
1118         PTR     sys32_waitid
1119         PTR     sys_ni_syscall                  /* available, was setaltroot */
1120         PTR     sys_add_key                     /* 4280 */
1121 diff -NurpP --minimal linux-2.6.19.1/arch/mips/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/traps.c
1122 --- linux-2.6.19.1/arch/mips/kernel/traps.c     2006-11-30 21:18:29 +0100
1123 +++ linux-2.6.19.1-vs2.3.0.6/arch/mips/kernel/traps.c   2006-11-08 21:52:08 +0100
1124 @@ -297,8 +297,9 @@ void show_registers(struct pt_regs *regs
1125  {
1126         show_regs(regs);
1127         print_modules();
1128 -       printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
1129 -               current->comm, current->pid, current_thread_info(), current);
1130 +       printk("Process %s (pid: %d:#%u, threadinfo=%p, task=%p)\n",
1131 +               current->comm, current->pid, current->xid,
1132 +               current_thread_info(), current);
1133         show_stacktrace(current, regs);
1134         show_code((unsigned int *) regs->cp0_epc);
1135         printk("\n");
1136 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/parisc/Kconfig
1137 --- linux-2.6.19.1/arch/parisc/Kconfig  2006-11-30 21:18:30 +0100
1138 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/Kconfig        2006-11-08 04:57:40 +0100
1139 @@ -257,6 +257,8 @@ source "arch/parisc/oprofile/Kconfig"
1140  
1141  source "arch/parisc/Kconfig.debug"
1142  
1143 +source "kernel/vserver/Kconfig"
1144 +
1145  source "security/Kconfig"
1146  
1147  source "crypto/Kconfig"
1148 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/kernel/entry.S linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/entry.S
1149 --- linux-2.6.19.1/arch/parisc/kernel/entry.S   2006-11-30 21:18:30 +0100
1150 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/entry.S 2006-11-08 04:57:50 +0100
1151 @@ -761,6 +761,7 @@ fault_vector_11:
1152  
1153  #define CLONE_VM 0x100 /* Must agree with <linux/sched.h> */
1154  #define CLONE_UNTRACED 0x00800000
1155 +#define CLONE_KTHREAD 0x10000000
1156  
1157         .export __kernel_thread, code
1158         .import do_fork
1159 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/process.c
1160 --- linux-2.6.19.1/arch/parisc/kernel/process.c 2006-11-30 21:18:30 +0100
1161 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/process.c       2006-11-08 04:57:50 +0100
1162 @@ -173,7 +173,7 @@ pid_t kernel_thread(int (*fn)(void *), v
1163          *        kernel_thread can become a #define.
1164          */
1165  
1166 -       return __kernel_thread(fn, arg, flags);
1167 +       return __kernel_thread(fn, arg, flags | CLONE_KTHREAD);
1168  }
1169  EXPORT_SYMBOL(kernel_thread);
1170  
1171 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/kernel/sys_parisc32.c linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/sys_parisc32.c
1172 --- linux-2.6.19.1/arch/parisc/kernel/sys_parisc32.c    2006-11-30 21:18:31 +0100
1173 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/sys_parisc32.c  2006-11-08 04:57:44 +0100
1174 @@ -204,11 +204,11 @@ static inline long get_ts32(struct times
1175  asmlinkage int
1176  sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
1177  {
1178 -    extern void do_gettimeofday(struct timeval *tv);
1179 +    extern void vx_gettimeofday(struct timeval *tv);
1180  
1181      if (tv) {
1182             struct timeval ktv;
1183 -           do_gettimeofday(&ktv);
1184 +           vx_gettimeofday(&ktv);
1185             if (put_compat_timeval(tv, &ktv))
1186                     return -EFAULT;
1187      }
1188 @@ -612,6 +612,7 @@ asmlinkage int sys32_sysinfo(struct sysi
1189  
1190         do {
1191                 seq = read_seqbegin(&xtime_lock);
1192 +               /* FIXME: requires vx virtualization */
1193                 val.uptime = jiffies / HZ;
1194  
1195                 val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
1196 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/kernel/syscall_table.S linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/syscall_table.S
1197 --- linux-2.6.19.1/arch/parisc/kernel/syscall_table.S   2006-11-30 21:18:31 +0100
1198 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/syscall_table.S 2006-11-08 04:57:41 +0100
1199 @@ -368,7 +368,7 @@
1200         ENTRY_COMP(mbind)               /* 260 */
1201         ENTRY_COMP(get_mempolicy)
1202         ENTRY_COMP(set_mempolicy)
1203 -       ENTRY_SAME(ni_syscall)  /* 263: reserved for vserver */
1204 +       ENTRY_DIFF(vserver)
1205         ENTRY_SAME(add_key)
1206         ENTRY_SAME(request_key)         /* 265 */
1207         ENTRY_SAME(keyctl)
1208 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/traps.c
1209 --- linux-2.6.19.1/arch/parisc/kernel/traps.c   2006-11-30 21:18:31 +0100
1210 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/kernel/traps.c 2006-11-08 04:57:42 +0100
1211 @@ -210,8 +210,9 @@ void die_if_kernel(char *str, struct pt_
1212                 if (err == 0)
1213                         return; /* STFU */
1214  
1215 -               printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
1216 -                       current->comm, current->pid, str, err, regs->iaoq[0]);
1217 +               printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld) at " RFMT "\n",
1218 +                       current->comm, current->pid, current->xid,
1219 +                       str, err, regs->iaoq[0]);
1220  #ifdef PRINT_USER_FAULTS
1221                 /* XXX for debugging only */
1222                 show_regs(regs);
1223 @@ -242,8 +243,8 @@ void die_if_kernel(char *str, struct pt_
1224         if (!console_drivers)
1225                 pdc_console_restart();
1226         
1227 -       printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
1228 -               current->comm, current->pid, str, err);
1229 +       printk(KERN_CRIT "%s (pid %d:#%u): %s (code %ld)\n",
1230 +               current->comm, current->pid, current->xid, str, err);
1231         show_regs(regs);
1232  
1233         if (in_interrupt())
1234 diff -NurpP --minimal linux-2.6.19.1/arch/parisc/mm/fault.c linux-2.6.19.1-vs2.3.0.6/arch/parisc/mm/fault.c
1235 --- linux-2.6.19.1/arch/parisc/mm/fault.c       2006-06-18 04:52:15 +0200
1236 +++ linux-2.6.19.1-vs2.3.0.6/arch/parisc/mm/fault.c     2006-11-08 04:57:42 +0100
1237 @@ -213,8 +213,9 @@ bad_area:
1238  
1239  #ifdef PRINT_USER_FAULTS
1240                 printk(KERN_DEBUG "\n");
1241 -               printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n",
1242 -                   tsk->pid, tsk->comm, code, address);
1243 +               printk(KERN_DEBUG "do_page_fault() pid=%d:#%u "
1244 +                   "command='%s' type=%lu address=0x%08lx\n",
1245 +                   tsk->pid, tsk->xid, tsk->comm, code, address);
1246                 if (vma) {
1247                         printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n",
1248                                         vma->vm_start, vma->vm_end);
1249 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/powerpc/Kconfig
1250 --- linux-2.6.19.1/arch/powerpc/Kconfig 2006-11-30 21:18:31 +0100
1251 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/Kconfig       2006-11-20 21:12:32 +0100
1252 @@ -1102,6 +1102,8 @@ endmenu
1253  
1254  source "arch/powerpc/Kconfig.debug"
1255  
1256 +source "kernel/vserver/Kconfig"
1257 +
1258  source "security/Kconfig"
1259  
1260  config KEYS_COMPAT
1261 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/asm-offsets.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/asm-offsets.c
1262 --- linux-2.6.19.1/arch/powerpc/kernel/asm-offsets.c    2006-11-30 21:18:31 +0100
1263 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/asm-offsets.c  2006-11-08 04:57:50 +0100
1264 @@ -243,6 +243,7 @@ int main(void)
1265  
1266         DEFINE(CLONE_VM, CLONE_VM);
1267         DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
1268 +       DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
1269  
1270  #ifndef CONFIG_PPC64
1271         DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
1272 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/irq.c
1273 --- linux-2.6.19.1/arch/powerpc/kernel/irq.c    2006-11-30 21:18:31 +0100
1274 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/irq.c  2006-11-30 18:27:23 +0100
1275 @@ -53,6 +53,7 @@
1276  #include <linux/mutex.h>
1277  #include <linux/bootmem.h>
1278  #include <linux/pci.h>
1279 +#include <linux/vs_context.h>
1280  
1281  #include <asm/uaccess.h>
1282  #include <asm/system.h>
1283 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/misc_32.S linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/misc_32.S
1284 --- linux-2.6.19.1/arch/powerpc/kernel/misc_32.S        2006-11-30 21:18:31 +0100
1285 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/misc_32.S      2006-11-08 04:57:50 +0100
1286 @@ -749,7 +749,7 @@ _GLOBAL(kernel_thread)
1287         mr      r30,r3          /* function */
1288         mr      r31,r4          /* argument */
1289         ori     r3,r5,CLONE_VM  /* flags */
1290 -       oris    r3,r3,CLONE_UNTRACED>>16
1291 +       oris    r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
1292         li      r4,0            /* new sp (unused) */
1293         li      r0,__NR_clone
1294         sc
1295 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/misc_64.S linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/misc_64.S
1296 --- linux-2.6.19.1/arch/powerpc/kernel/misc_64.S        2006-11-30 21:18:31 +0100
1297 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/misc_64.S      2006-11-08 04:57:50 +0100
1298 @@ -394,7 +394,7 @@ _GLOBAL(kernel_thread)
1299         mr      r29,r3
1300         mr      r30,r4
1301         ori     r3,r5,CLONE_VM  /* flags */
1302 -       oris    r3,r3,(CLONE_UNTRACED>>16)
1303 +       oris    r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
1304         li      r4,0            /* new sp (unused) */
1305         li      r0,__NR_clone
1306         sc
1307 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/process.c
1308 --- linux-2.6.19.1/arch/powerpc/kernel/process.c        2006-11-30 21:18:31 +0100
1309 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/process.c      2006-11-08 04:57:42 +0100
1310 @@ -425,8 +425,9 @@ void show_regs(struct pt_regs * regs)
1311         trap = TRAP(regs);
1312         if (trap == 0x300 || trap == 0x600)
1313                 printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
1314 -       printk("TASK = %p[%d] '%s' THREAD: %p",
1315 -              current, current->pid, current->comm, task_thread_info(current));
1316 +       printk("TASK = %p[%d,#%u] '%s' THREAD: %p",
1317 +              current, current->pid, current->xid,
1318 +              current->comm, task_thread_info(current));
1319  
1320  #ifdef CONFIG_SMP
1321         printk(" CPU: %d", smp_processor_id());
1322 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/sys_ppc32.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/sys_ppc32.c
1323 --- linux-2.6.19.1/arch/powerpc/kernel/sys_ppc32.c      2006-11-30 21:18:31 +0100
1324 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/sys_ppc32.c    2006-11-08 04:57:44 +0100
1325 @@ -275,7 +275,7 @@ asmlinkage long compat_sys_gettimeofday(
1326  {
1327         if (tv) {
1328                 struct timeval ktv;
1329 -               do_gettimeofday(&ktv);
1330 +               vx_gettimeofday(&ktv);
1331                 if (put_tv32(tv, &ktv))
1332                         return -EFAULT;
1333         }
1334 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/traps.c
1335 --- linux-2.6.19.1/arch/powerpc/kernel/traps.c  2006-11-30 21:18:31 +0100
1336 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/traps.c        2006-11-08 21:52:08 +0100
1337 @@ -888,8 +888,9 @@ void nonrecoverable_exception(struct pt_
1338  
1339  void trace_syscall(struct pt_regs *regs)
1340  {
1341 -       printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
1342 -              current, current->pid, regs->nip, regs->link, regs->gpr[0],
1343 +       printk("Task: %p(%d[#%u]), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
1344 +              current, current->pid, current->xid,
1345 +              regs->nip, regs->link, regs->gpr[0],
1346                regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
1347  }
1348  
1349 diff -NurpP --minimal linux-2.6.19.1/arch/powerpc/kernel/vdso.c linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/vdso.c
1350 --- linux-2.6.19.1/arch/powerpc/kernel/vdso.c   2006-11-30 21:18:31 +0100
1351 +++ linux-2.6.19.1-vs2.3.0.6/arch/powerpc/kernel/vdso.c 2006-11-08 04:57:47 +0100
1352 @@ -22,6 +22,7 @@
1353  #include <linux/elf.h>
1354  #include <linux/security.h>
1355  #include <linux/bootmem.h>
1356 +#include <linux/vs_memory.h>
1357  
1358  #include <asm/pgtable.h>
1359  #include <asm/system.h>
1360 @@ -295,7 +296,7 @@ int arch_setup_additional_pages(struct l
1361  
1362         /* Put vDSO base into mm struct and account for memory usage */
1363         current->mm->context.vdso_base = vdso_base;
1364 -       mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
1365 +       vx_vmpages_add(mm, (vma->vm_end - vma->vm_start) >> PAGE_SHIFT);
1366         up_write(&mm->mmap_sem);
1367         return 0;
1368  
1369 diff -NurpP --minimal linux-2.6.19.1/arch/ppc/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/ppc/Kconfig
1370 --- linux-2.6.19.1/arch/ppc/Kconfig     2006-11-30 21:18:32 +0100
1371 +++ linux-2.6.19.1-vs2.3.0.6/arch/ppc/Kconfig   2006-11-08 04:57:40 +0100
1372 @@ -1421,6 +1421,8 @@ source "arch/powerpc/oprofile/Kconfig"
1373  
1374  source "arch/ppc/Kconfig.debug"
1375  
1376 +source "kernel/vserver/Kconfig"
1377 +
1378  source "security/Kconfig"
1379  
1380  source "crypto/Kconfig"
1381 diff -NurpP --minimal linux-2.6.19.1/arch/ppc/kernel/asm-offsets.c linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/asm-offsets.c
1382 --- linux-2.6.19.1/arch/ppc/kernel/asm-offsets.c        2006-09-20 16:58:01 +0200
1383 +++ linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/asm-offsets.c      2006-11-08 04:57:50 +0100
1384 @@ -121,6 +121,7 @@ main(void)
1385         DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
1386         DEFINE(CLONE_VM, CLONE_VM);
1387         DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
1388 +       DEFINE(CLONE_KTHREAD, CLONE_KTHREAD);
1389         DEFINE(MM_PGD, offsetof(struct mm_struct, pgd));
1390  
1391         /* About the CPU features table */
1392 diff -NurpP --minimal linux-2.6.19.1/arch/ppc/kernel/misc.S linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/misc.S
1393 --- linux-2.6.19.1/arch/ppc/kernel/misc.S       2006-11-30 21:18:32 +0100
1394 +++ linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/misc.S     2006-11-08 04:57:50 +0100
1395 @@ -848,7 +848,7 @@ _GLOBAL(kernel_thread)
1396         mr      r30,r3          /* function */
1397         mr      r31,r4          /* argument */
1398         ori     r3,r5,CLONE_VM  /* flags */
1399 -       oris    r3,r3,CLONE_UNTRACED>>16
1400 +       oris    r3,r3,(CLONE_UNTRACED|CLONE_KTHREAD)>>16
1401         li      r4,0            /* new sp (unused) */
1402         li      r0,__NR_clone
1403         sc
1404 diff -NurpP --minimal linux-2.6.19.1/arch/ppc/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/traps.c
1405 --- linux-2.6.19.1/arch/ppc/kernel/traps.c      2006-11-30 21:18:32 +0100
1406 +++ linux-2.6.19.1-vs2.3.0.6/arch/ppc/kernel/traps.c    2006-11-08 21:52:08 +0100
1407 @@ -748,8 +748,9 @@ void nonrecoverable_exception(struct pt_
1408  
1409  void trace_syscall(struct pt_regs *regs)
1410  {
1411 -       printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
1412 -              current, current->pid, regs->nip, regs->link, regs->gpr[0],
1413 +       printk("Task: %p(%d[#%u]), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld    %s\n",
1414 +              current, current->pid, current->xid,
1415 +              regs->nip, regs->link, regs->gpr[0],
1416                regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
1417  }
1418  
1419 diff -NurpP --minimal linux-2.6.19.1/arch/s390/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/s390/Kconfig
1420 --- linux-2.6.19.1/arch/s390/Kconfig    2006-11-30 21:18:32 +0100
1421 +++ linux-2.6.19.1-vs2.3.0.6/arch/s390/Kconfig  2006-11-08 21:52:08 +0100
1422 @@ -519,6 +519,8 @@ endmenu
1423  
1424  source "arch/s390/Kconfig.debug"
1425  
1426 +source "kernel/vserver/Kconfig"
1427 +
1428  source "security/Kconfig"
1429  
1430  source "crypto/Kconfig"
1431 diff -NurpP --minimal linux-2.6.19.1/arch/s390/kernel/compat_linux.c linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/compat_linux.c
1432 --- linux-2.6.19.1/arch/s390/kernel/compat_linux.c      2006-11-30 21:18:32 +0100
1433 +++ linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/compat_linux.c    2006-11-08 04:57:44 +0100
1434 @@ -600,7 +600,7 @@ asmlinkage long sys32_gettimeofday(struc
1435  {
1436         if (tv) {
1437                 struct timeval ktv;
1438 -               do_gettimeofday(&ktv);
1439 +               vx_gettimeofday(&ktv);
1440                 if (put_tv32(tv, &ktv))
1441                         return -EFAULT;
1442         }
1443 diff -NurpP --minimal linux-2.6.19.1/arch/s390/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/process.c
1444 --- linux-2.6.19.1/arch/s390/kernel/process.c   2006-11-30 21:18:32 +0100
1445 +++ linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/process.c 2006-11-08 04:57:50 +0100
1446 @@ -165,9 +165,9 @@ void show_regs(struct pt_regs *regs)
1447         struct task_struct *tsk = current;
1448  
1449          printk("CPU:    %d    %s\n", task_thread_info(tsk)->cpu, print_tainted());
1450 -        printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
1451 -              current->comm, current->pid, (void *) tsk,
1452 -              (void *) tsk->thread.ksp);
1453 +       printk("Process %s (pid: %d[#%u], task: %p, ksp: %p)\n",
1454 +              current->comm, current->pid, current->xid,
1455 +              (void *) tsk, (void *) tsk->thread.ksp);
1456  
1457         show_registers(regs);
1458         /* Show stack backtrace if pt_regs is from kernel mode */
1459 @@ -198,7 +198,7 @@ int kernel_thread(int (*fn)(void *), voi
1460         regs.orig_gpr2 = -1;
1461  
1462         /* Ok, create the new process.. */
1463 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
1464 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
1465                        0, &regs, 0, NULL, NULL);
1466  }
1467  
1468 diff -NurpP --minimal linux-2.6.19.1/arch/s390/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/ptrace.c
1469 --- linux-2.6.19.1/arch/s390/kernel/ptrace.c    2006-06-18 04:52:33 +0200
1470 +++ linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/ptrace.c  2006-11-30 18:53:18 +0100
1471 @@ -33,6 +33,7 @@
1472  #include <linux/security.h>
1473  #include <linux/audit.h>
1474  #include <linux/signal.h>
1475 +#include <linux/vs_base.h>
1476  
1477  #include <asm/segment.h>
1478  #include <asm/page.h>
1479 @@ -723,7 +724,13 @@ sys_ptrace(long request, long pid, long 
1480                 goto out;
1481         }
1482  
1483 +       if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT)) {
1484 +               ret = -EPERM;
1485 +               goto out_tsk;
1486 +       }
1487 +
1488         ret = do_ptrace(child, request, addr, data);
1489 +out_tsk:
1490         put_task_struct(child);
1491  out:
1492         unlock_kernel();
1493 diff -NurpP --minimal linux-2.6.19.1/arch/s390/kernel/syscalls.S linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/syscalls.S
1494 --- linux-2.6.19.1/arch/s390/kernel/syscalls.S  2006-11-30 21:18:32 +0100
1495 +++ linux-2.6.19.1-vs2.3.0.6/arch/s390/kernel/syscalls.S        2006-11-08 04:57:41 +0100
1496 @@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,sys_clock_sett
1497  SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper)       /* 260 */
1498  SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper)
1499  SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper)
1500 -NI_SYSCALL                                                     /* reserved for vserver */
1501 +SYSCALL(sys_vserver,sys_vserver,sys32_vserver)
1502  SYSCALL(s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper)
1503  SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper)
1504  SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper)
1505 diff -NurpP --minimal linux-2.6.19.1/arch/sh/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/sh/Kconfig
1506 --- linux-2.6.19.1/arch/sh/Kconfig      2006-11-30 21:18:32 +0100
1507 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh/Kconfig    2006-11-08 04:57:40 +0100
1508 @@ -627,6 +627,8 @@ source "arch/sh/oprofile/Kconfig"
1509  
1510  source "arch/sh/Kconfig.debug"
1511  
1512 +source "kernel/vserver/Kconfig"
1513 +
1514  source "security/Kconfig"
1515  
1516  source "crypto/Kconfig"
1517 diff -NurpP --minimal linux-2.6.19.1/arch/sh/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/irq.c
1518 --- linux-2.6.19.1/arch/sh/kernel/irq.c 2006-11-30 21:18:34 +0100
1519 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/irq.c       2006-11-30 18:27:47 +0100
1520 @@ -12,6 +12,7 @@
1521  #include <linux/kernel_stat.h>
1522  #include <linux/seq_file.h>
1523  #include <linux/io.h>
1524 +#include <linux/vs_context.h>
1525  #include <asm/irq.h>
1526  #include <asm/processor.h>
1527  #include <asm/uaccess.h>
1528 diff -NurpP --minimal linux-2.6.19.1/arch/sh/kernel/kgdb_stub.c linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/kgdb_stub.c
1529 --- linux-2.6.19.1/arch/sh/kernel/kgdb_stub.c   2006-11-30 21:18:34 +0100
1530 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/kgdb_stub.c 2006-11-08 04:57:52 +0100
1531 @@ -389,7 +389,7 @@ static struct task_struct *get_thread(in
1532         if (pid == PID_MAX) pid = 0;
1533  
1534         /* First check via PID */
1535 -       thread = find_task_by_pid(pid);
1536 +       thread = find_task_by_real_pid(pid);
1537  
1538         if (thread)
1539                 return thread;
1540 diff -NurpP --minimal linux-2.6.19.1/arch/sh/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/process.c
1541 --- linux-2.6.19.1/arch/sh/kernel/process.c     2006-11-30 21:18:34 +0100
1542 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/process.c   2006-11-08 04:57:50 +0100
1543 @@ -104,7 +104,8 @@ void machine_power_off(void)
1544  void show_regs(struct pt_regs * regs)
1545  {
1546         printk("\n");
1547 -       printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
1548 +       printk("Pid : %d:#%u, Comm: %20s\n",
1549 +               current->pid, current->xid, current->comm);
1550         print_symbol("PC is at %s\n", instruction_pointer(regs));
1551         printk("PC  : %08lx SP  : %08lx SR  : %08lx ",
1552                regs->pc, regs->regs[15], regs->sr);
1553 @@ -164,7 +165,8 @@ int kernel_thread(int (*fn)(void *), voi
1554         regs.sr = (1 << 30);
1555  
1556         /* Ok, create the new process.. */
1557 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
1558 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
1559 +               0, &regs, 0, NULL, NULL);
1560  }
1561  
1562  /*
1563 diff -NurpP --minimal linux-2.6.19.1/arch/sh/kernel/vsyscall/vsyscall.c linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/vsyscall/vsyscall.c
1564 --- linux-2.6.19.1/arch/sh/kernel/vsyscall/vsyscall.c   2006-11-30 21:18:34 +0100
1565 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh/kernel/vsyscall/vsyscall.c 2006-12-02 01:37:05 +0100
1566 @@ -17,6 +17,7 @@
1567  #include <linux/gfp.h>
1568  #include <linux/module.h>
1569  #include <linux/elf.h>
1570 +#include <linux/vs_memory.h>
1571  
1572  /*
1573   * Should the kernel map a VDSO page into processes and pass its
1574 @@ -120,7 +121,7 @@ int arch_setup_additional_pages(struct l
1575  
1576         current->mm->context.vdso = (void *)addr;
1577  
1578 -       mm->total_vm++;
1579 +       vx_vmpages_inc(mm);
1580  up_fail:
1581         up_write(&mm->mmap_sem);
1582         return ret;
1583 diff -NurpP --minimal linux-2.6.19.1/arch/sh64/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/sh64/kernel/process.c
1584 --- linux-2.6.19.1/arch/sh64/kernel/process.c   2006-11-30 21:18:35 +0100
1585 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh64/kernel/process.c 2006-11-08 04:57:50 +0100
1586 @@ -400,8 +400,8 @@ int kernel_thread(int (*fn)(void *), voi
1587         regs.pc = (unsigned long)kernel_thread_helper;
1588         regs.sr = (1 << 30);
1589  
1590 -       return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
1591 -                      &regs, 0, NULL, NULL);
1592 +       return do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD,
1593 +               0, &regs, 0, NULL, NULL);
1594  }
1595  
1596  /*
1597 diff -NurpP --minimal linux-2.6.19.1/arch/sh64/mm/fault.c linux-2.6.19.1-vs2.3.0.6/arch/sh64/mm/fault.c
1598 --- linux-2.6.19.1/arch/sh64/mm/fault.c 2006-11-30 21:18:35 +0100
1599 +++ linux-2.6.19.1-vs2.3.0.6/arch/sh64/mm/fault.c       2006-11-08 04:57:42 +0100
1600 @@ -82,7 +82,7 @@ static inline void print_vma(struct vm_a
1601  
1602  static inline void print_task(struct task_struct *tsk)
1603  {
1604 -       printk("Task pid %d\n", tsk->pid);
1605 +       printk("Task pid %d:#%u\n", tsk->pid, tsk->xid);
1606  }
1607  
1608  static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address)
1609 diff -NurpP --minimal linux-2.6.19.1/arch/sparc/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/sparc/Kconfig
1610 --- linux-2.6.19.1/arch/sparc/Kconfig   2006-11-30 21:18:35 +0100
1611 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc/Kconfig 2006-11-08 04:57:40 +0100
1612 @@ -298,6 +298,8 @@ endmenu
1613  
1614  source "arch/sparc/Kconfig.debug"
1615  
1616 +source "kernel/vserver/Kconfig"
1617 +
1618  source "security/Kconfig"
1619  
1620  source "crypto/Kconfig"
1621 diff -NurpP --minimal linux-2.6.19.1/arch/sparc/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/process.c
1622 --- linux-2.6.19.1/arch/sparc/kernel/process.c  2006-09-20 16:58:01 +0200
1623 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/process.c        2006-11-08 04:57:50 +0100
1624 @@ -705,7 +705,8 @@ pid_t kernel_thread(int (*fn)(void *), v
1625                              /* Notreached by child. */
1626                              "1: mov %%o0, %0\n\t" :
1627                              "=r" (retval) :
1628 -                            "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED),
1629 +                            "i" (__NR_clone), "r" (flags |
1630 +                                       CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD),
1631                              "i" (__NR_exit),  "r" (fn), "r" (arg) :
1632                              "g1", "g2", "g3", "o0", "o1", "memory", "cc");
1633         return retval;
1634 diff -NurpP --minimal linux-2.6.19.1/arch/sparc/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/ptrace.c
1635 --- linux-2.6.19.1/arch/sparc/kernel/ptrace.c   2006-04-09 13:49:44 +0200
1636 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/ptrace.c 2006-11-30 18:53:18 +0100
1637 @@ -19,6 +19,7 @@
1638  #include <linux/smp_lock.h>
1639  #include <linux/security.h>
1640  #include <linux/signal.h>
1641 +#include <linux/vs_base.h>
1642  
1643  #include <asm/pgtable.h>
1644  #include <asm/system.h>
1645 @@ -299,6 +300,10 @@ asmlinkage void do_ptrace(struct pt_regs
1646                 pt_error_return(regs, -ret);
1647                 goto out;
1648         }
1649 +       if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT)) {
1650 +               pt_error_return(regs, ESRCH);
1651 +               goto out_tsk;
1652 +       }
1653  
1654         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
1655             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
1656 diff -NurpP --minimal linux-2.6.19.1/arch/sparc/kernel/systbls.S linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/systbls.S
1657 --- linux-2.6.19.1/arch/sparc/kernel/systbls.S  2006-11-30 21:18:35 +0100
1658 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/systbls.S        2006-11-08 21:52:08 +0100
1659 @@ -71,7 +71,7 @@ sys_call_table:
1660  /*250*/        .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
1661  /*255*/        .long sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
1662  /*260*/        .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
1663 -/*265*/        .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
1664 +/*265*/        .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
1665  /*270*/        .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
1666  /*275*/        .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
1667  /*280*/        .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
1668 diff -NurpP --minimal linux-2.6.19.1/arch/sparc/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/traps.c
1669 --- linux-2.6.19.1/arch/sparc/kernel/traps.c    2006-09-20 16:58:06 +0200
1670 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc/kernel/traps.c  2006-11-08 04:57:42 +0100
1671 @@ -99,7 +99,8 @@ void die_if_kernel(char *str, struct pt_
1672  "              /_| \\__/ |_\\\n"
1673  "                 \\__U_/\n");
1674  
1675 -       printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
1676 +       printk("%s(%d[#%u]): %s [#%d]\n", current->comm,
1677 +               current->pid, current->xid, str, ++die_counter);
1678         show_regs(regs);
1679  
1680         __SAVE; __SAVE; __SAVE; __SAVE;
1681 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/sparc64/Kconfig
1682 --- linux-2.6.19.1/arch/sparc64/Kconfig 2006-11-30 21:18:35 +0100
1683 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/Kconfig       2006-11-08 04:57:40 +0100
1684 @@ -431,6 +431,8 @@ endmenu
1685  
1686  source "arch/sparc64/Kconfig.debug"
1687  
1688 +source "kernel/vserver/Kconfig"
1689 +
1690  source "security/Kconfig"
1691  
1692  source "crypto/Kconfig"
1693 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/binfmt_aout32.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/binfmt_aout32.c
1694 --- linux-2.6.19.1/arch/sparc64/kernel/binfmt_aout32.c  2006-06-18 04:52:34 +0200
1695 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/binfmt_aout32.c        2006-11-08 04:57:40 +0100
1696 @@ -27,6 +27,7 @@
1697  #include <linux/binfmts.h>
1698  #include <linux/personality.h>
1699  #include <linux/init.h>
1700 +#include <linux/vs_memory.h>
1701  
1702  #include <asm/system.h>
1703  #include <asm/uaccess.h>
1704 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/process.c
1705 --- linux-2.6.19.1/arch/sparc64/kernel/process.c        2006-09-20 16:58:06 +0200
1706 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/process.c      2006-11-08 04:57:50 +0100
1707 @@ -696,7 +696,8 @@ pid_t kernel_thread(int (*fn)(void *), v
1708                              /* Notreached by child. */
1709                              "1:" :
1710                              "=r" (retval) :
1711 -                            "i" (__NR_clone), "r" (flags | CLONE_VM | CLONE_UNTRACED),
1712 +                            "i" (__NR_clone), "r" (flags |
1713 +                               CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD),
1714                              "i" (__NR_exit),  "r" (fn), "r" (arg) :
1715                              "g1", "g2", "g3", "o0", "o1", "memory", "cc");
1716         return retval;
1717 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/ptrace.c
1718 --- linux-2.6.19.1/arch/sparc64/kernel/ptrace.c 2006-06-18 04:52:35 +0200
1719 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/ptrace.c       2006-11-30 18:53:18 +0100
1720 @@ -22,6 +22,7 @@
1721  #include <linux/seccomp.h>
1722  #include <linux/audit.h>
1723  #include <linux/signal.h>
1724 +#include <linux/vs_base.h>
1725  
1726  #include <asm/asi.h>
1727  #include <asm/pgtable.h>
1728 @@ -212,6 +213,10 @@ asmlinkage void do_ptrace(struct pt_regs
1729                 pt_error_return(regs, -ret);
1730                 goto out;
1731         }
1732 +       if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT)) {
1733 +               pt_error_return(regs, ESRCH);
1734 +               goto out_tsk;
1735 +       }
1736  
1737         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
1738             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
1739 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/sys_sparc32.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/sys_sparc32.c
1740 --- linux-2.6.19.1/arch/sparc64/kernel/sys_sparc32.c    2006-11-30 21:18:35 +0100
1741 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/sys_sparc32.c  2006-11-08 04:57:44 +0100
1742 @@ -793,7 +793,7 @@ asmlinkage long sys32_gettimeofday(struc
1743  {
1744         if (tv) {
1745                 struct timeval ktv;
1746 -               do_gettimeofday(&ktv);
1747 +               vx_gettimeofday(&ktv);
1748                 if (put_tv32(tv, &ktv))
1749                         return -EFAULT;
1750         }
1751 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/systbls.S linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/systbls.S
1752 --- linux-2.6.19.1/arch/sparc64/kernel/systbls.S        2006-11-30 21:18:35 +0100
1753 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/systbls.S      2006-11-08 21:52:08 +0100
1754 @@ -72,7 +72,7 @@ sys_call_table32:
1755  /*250*/        .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl
1756         .word sys32_sync_file_range, compat_sys_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep
1757  /*260*/        .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun
1758 -       .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
1759 +       .word sys_timer_delete, compat_sys_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy
1760  /*270*/        .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
1761         .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
1762  /*280*/        .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
1763 @@ -142,7 +142,7 @@ sys_call_table:
1764  /*250*/        .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
1765         .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
1766  /*260*/        .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
1767 -       .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
1768 +       .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy
1769  /*270*/        .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
1770         .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
1771  /*280*/        .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
1772 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/traps.c
1773 --- linux-2.6.19.1/arch/sparc64/kernel/traps.c  2006-11-30 21:18:35 +0100
1774 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/kernel/traps.c        2006-11-08 21:52:08 +0100
1775 @@ -2223,7 +2223,8 @@ void die_if_kernel(char *str, struct pt_
1776  "              /_| \\__/ |_\\\n"
1777  "                 \\__U_/\n");
1778  
1779 -       printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
1780 +       printk("%s(%d[#%u]): %s [#%d]\n", current->comm,
1781 +               current->pid, current->xid, str, ++die_counter);
1782         notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
1783         __asm__ __volatile__("flushw");
1784         __show_regs(regs);
1785 diff -NurpP --minimal linux-2.6.19.1/arch/sparc64/solaris/fs.c linux-2.6.19.1-vs2.3.0.6/arch/sparc64/solaris/fs.c
1786 --- linux-2.6.19.1/arch/sparc64/solaris/fs.c    2006-11-30 21:18:35 +0100
1787 +++ linux-2.6.19.1-vs2.3.0.6/arch/sparc64/solaris/fs.c  2006-11-08 04:57:52 +0100
1788 @@ -368,7 +368,7 @@ static int report_statvfs(struct vfsmoun
1789                 int j = strlen (p);
1790                 
1791                 if (j > 15) j = 15;
1792 -               if (IS_RDONLY(inode)) i = 1;
1793 +               if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
1794                 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
1795                 if (!sysv_valid_dev(inode->i_sb->s_dev))
1796                         return -EOVERFLOW;
1797 @@ -404,7 +404,7 @@ static int report_statvfs64(struct vfsmo
1798                 int j = strlen (p);
1799                 
1800                 if (j > 15) j = 15;
1801 -               if (IS_RDONLY(inode)) i = 1;
1802 +               if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
1803                 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
1804                 if (!sysv_valid_dev(inode->i_sb->s_dev))
1805                         return -EOVERFLOW;
1806 diff -NurpP --minimal linux-2.6.19.1/arch/um/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/um/Kconfig
1807 --- linux-2.6.19.1/arch/um/Kconfig      2006-11-30 21:18:35 +0100
1808 +++ linux-2.6.19.1-vs2.3.0.6/arch/um/Kconfig    2006-11-08 04:57:40 +0100
1809 @@ -306,6 +306,8 @@ source "drivers/connector/Kconfig"
1810  
1811  source "fs/Kconfig"
1812  
1813 +source "kernel/vserver/Kconfig"
1814 +
1815  source "security/Kconfig"
1816  
1817  source "crypto/Kconfig"
1818 diff -NurpP --minimal linux-2.6.19.1/arch/um/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/um/kernel/irq.c
1819 --- linux-2.6.19.1/arch/um/kernel/irq.c 2006-11-30 21:18:36 +0100
1820 +++ linux-2.6.19.1-vs2.3.0.6/arch/um/kernel/irq.c       2006-11-30 18:28:41 +0100
1821 @@ -357,6 +357,7 @@ void forward_interrupts(int pid)
1822  unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
1823  {
1824         struct pt_regs *old_regs = set_irq_regs((struct pt_regs *)regs);
1825 +
1826         irq_enter();
1827         __do_IRQ(irq);
1828         irq_exit();
1829 diff -NurpP --minimal linux-2.6.19.1/arch/um/kernel/syscall.c linux-2.6.19.1-vs2.3.0.6/arch/um/kernel/syscall.c
1830 --- linux-2.6.19.1/arch/um/kernel/syscall.c     2006-11-30 21:18:36 +0100
1831 +++ linux-2.6.19.1-vs2.3.0.6/arch/um/kernel/syscall.c   2006-12-02 01:37:05 +0100
1832 @@ -15,6 +15,7 @@
1833  #include "linux/unistd.h"
1834  #include "linux/slab.h"
1835  #include "linux/utime.h"
1836 +
1837  #include "asm/mman.h"
1838  #include "asm/uaccess.h"
1839  #include "kern_util.h"
1840 @@ -118,6 +119,7 @@ long sys_uname(struct old_utsname __user
1841  long sys_olduname(struct oldold_utsname __user * name)
1842  {
1843         long error;
1844 +       struct new_utsname *ptr;
1845  
1846         if (!name)
1847                 return -EFAULT;
1848 diff -NurpP --minimal linux-2.6.19.1/arch/v850/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/v850/Kconfig
1849 --- linux-2.6.19.1/arch/v850/Kconfig    2006-06-18 04:52:42 +0200
1850 +++ linux-2.6.19.1-vs2.3.0.6/arch/v850/Kconfig  2006-11-08 04:57:40 +0100
1851 @@ -326,6 +326,8 @@ source "drivers/usb/Kconfig"
1852  
1853  source "arch/v850/Kconfig.debug"
1854  
1855 +source "kernel/vserver/Kconfig"
1856 +
1857  source "security/Kconfig"
1858  
1859  source "crypto/Kconfig"
1860 diff -NurpP --minimal linux-2.6.19.1/arch/v850/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/v850/kernel/process.c
1861 --- linux-2.6.19.1/arch/v850/kernel/process.c   2006-09-20 16:58:06 +0200
1862 +++ linux-2.6.19.1-vs2.3.0.6/arch/v850/kernel/process.c 2006-11-08 04:57:50 +0100
1863 @@ -83,7 +83,7 @@ int kernel_thread (int (*fn)(void *), vo
1864         /* Clone this thread.  Note that we don't pass the clone syscall's
1865            second argument -- it's ignored for calls from kernel mode (the
1866            child's SP is always set to the top of the kernel stack).  */
1867 -       arg0 = flags | CLONE_VM;
1868 +       arg0 = flags | CLONE_VM | CLONE_KTHREAD;
1869         syscall = __NR_clone;
1870         asm volatile ("trap " SYSCALL_SHORT_TRAP
1871                       : "=r" (ret), "=r" (syscall)
1872 diff -NurpP --minimal linux-2.6.19.1/arch/v850/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/arch/v850/kernel/ptrace.c
1873 --- linux-2.6.19.1/arch/v850/kernel/ptrace.c    2006-04-09 13:49:44 +0200
1874 +++ linux-2.6.19.1-vs2.3.0.6/arch/v850/kernel/ptrace.c  2006-11-30 18:53:18 +0100
1875 @@ -24,6 +24,7 @@
1876  #include <linux/smp_lock.h>
1877  #include <linux/ptrace.h>
1878  #include <linux/signal.h>
1879 +#include <linux/vs_base.h>
1880  
1881  #include <asm/errno.h>
1882  #include <asm/ptrace.h>
1883 @@ -117,6 +118,9 @@ long arch_ptrace(struct task_struct *chi
1884  {
1885         int rval;
1886  
1887 +       if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT))
1888 +               goto out;
1889 +
1890         switch (request) {
1891                 unsigned long val, copied;
1892  
1893 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/Kconfig linux-2.6.19.1-vs2.3.0.6/arch/x86_64/Kconfig
1894 --- linux-2.6.19.1/arch/x86_64/Kconfig  2006-11-30 21:18:36 +0100
1895 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/Kconfig        2006-11-08 04:57:40 +0100
1896 @@ -701,6 +701,8 @@ endmenu
1897  
1898  source "arch/x86_64/Kconfig.debug"
1899  
1900 +source "kernel/vserver/Kconfig"
1901 +
1902  source "security/Kconfig"
1903  
1904  source "crypto/Kconfig"
1905 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/ia32/ia32_aout.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32_aout.c
1906 --- linux-2.6.19.1/arch/x86_64/ia32/ia32_aout.c 2006-11-30 21:18:37 +0100
1907 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32_aout.c       2006-11-08 04:57:40 +0100
1908 @@ -25,6 +25,7 @@
1909  #include <linux/binfmts.h>
1910  #include <linux/personality.h>
1911  #include <linux/init.h>
1912 +#include <linux/vs_memory.h>
1913  
1914  #include <asm/system.h>
1915  #include <asm/uaccess.h>
1916 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32_binfmt.c
1917 --- linux-2.6.19.1/arch/x86_64/ia32/ia32_binfmt.c       2006-11-30 21:18:37 +0100
1918 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32_binfmt.c     2006-11-08 04:57:47 +0100
1919 @@ -375,7 +375,8 @@ int ia32_setup_arg_pages(struct linux_bi
1920                         kmem_cache_free(vm_area_cachep, mpnt);
1921                         return ret;
1922                 }
1923 -               mm->stack_vm = mm->total_vm = vma_pages(mpnt);
1924 +               vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
1925 +               mm->stack_vm = mm->total_vm;
1926         } 
1927  
1928         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
1929 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/ia32/ia32entry.S linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32entry.S
1930 --- linux-2.6.19.1/arch/x86_64/ia32/ia32entry.S 2006-11-30 21:18:37 +0100
1931 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/ia32entry.S       2006-11-08 04:57:41 +0100
1932 @@ -672,7 +672,7 @@ ia32_sys_call_table:
1933         .quad sys_tgkill                /* 270 */
1934         .quad compat_sys_utimes
1935         .quad sys32_fadvise64_64
1936 -       .quad quiet_ni_syscall  /* sys_vserver */
1937 +       .quad sys32_vserver
1938         .quad sys_mbind
1939         .quad compat_sys_get_mempolicy  /* 275 */
1940         .quad sys_set_mempolicy
1941 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/ia32/sys_ia32.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/sys_ia32.c
1942 --- linux-2.6.19.1/arch/x86_64/ia32/sys_ia32.c  2006-11-30 21:18:37 +0100
1943 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/sys_ia32.c        2006-12-02 01:37:05 +0100
1944 @@ -454,7 +454,7 @@ sys32_gettimeofday(struct compat_timeval
1945  {
1946         if (tv) {
1947                 struct timeval ktv;
1948 -               do_gettimeofday(&ktv);
1949 +               vx_gettimeofday(&ktv);
1950                 if (put_tv32(tv, &ktv))
1951                         return -EFAULT;
1952         }
1953 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/ia32/syscall32.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/syscall32.c
1954 --- linux-2.6.19.1/arch/x86_64/ia32/syscall32.c 2005-10-28 20:49:18 +0200
1955 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/ia32/syscall32.c       2006-11-08 04:57:47 +0100
1956 @@ -10,6 +10,7 @@
1957  #include <linux/init.h>
1958  #include <linux/stringify.h>
1959  #include <linux/security.h>
1960 +#include <linux/vs_memory.h>
1961  #include <asm/proto.h>
1962  #include <asm/tlbflush.h>
1963  #include <asm/ia32_unistd.h>
1964 @@ -70,7 +71,7 @@ int syscall32_setup_pages(struct linux_b
1965                 kmem_cache_free(vm_area_cachep, vma);
1966                 return ret;
1967         }
1968 -       mm->total_vm += npages;
1969 +       vx_vmpages_add(mm, npages);
1970         up_write(&mm->mmap_sem);
1971         return 0;
1972  }
1973 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/irq.c
1974 --- linux-2.6.19.1/arch/x86_64/kernel/irq.c     2006-11-30 21:18:37 +0100
1975 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/irq.c   2006-11-30 18:28:58 +0100
1976 @@ -123,7 +123,6 @@ asmlinkage unsigned int do_IRQ(struct pt
1977         else
1978                 printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
1979                         __func__, smp_processor_id(), vector);
1980 -
1981         irq_exit();
1982  
1983         set_irq_regs(old_regs);
1984 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/process.c
1985 --- linux-2.6.19.1/arch/x86_64/kernel/process.c 2006-11-30 21:18:37 +0100
1986 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/process.c       2006-11-30 20:55:45 +0100
1987 @@ -54,7 +54,8 @@
1988  
1989  asmlinkage extern void ret_from_fork(void);
1990  
1991 -unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
1992 +unsigned long kernel_thread_flags =
1993 +       CLONE_VM | CLONE_UNTRACED | CLONE_KTHREAD;
1994  
1995  unsigned long boot_option_idle_override = 0;
1996  EXPORT_SYMBOL(boot_option_idle_override);
1997 @@ -301,8 +302,8 @@ void __show_regs(struct pt_regs * regs)
1998  
1999         printk("\n");
2000         print_modules();
2001 -       printk("Pid: %d, comm: %.20s %s %s %.*s\n",
2002 -               current->pid, current->comm, print_tainted(),
2003 +       printk("Pid: %d:#%u, comm: %.20s %s %s %.*s\n",
2004 +               current->pid, current->xid, current->comm, print_tainted(),
2005                 init_utsname()->release,
2006                 (int)strcspn(init_utsname()->version, " "),
2007                 init_utsname()->version);
2008 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/kernel/traps.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/traps.c
2009 --- linux-2.6.19.1/arch/x86_64/kernel/traps.c   2006-11-30 21:18:37 +0100
2010 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/kernel/traps.c 2006-11-30 20:55:45 +0100
2011 @@ -487,8 +487,9 @@ void show_registers(struct pt_regs *regs
2012  
2013         printk("CPU %d ", cpu);
2014         __show_regs(regs);
2015 -       printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
2016 -               cur->comm, cur->pid, task_thread_info(cur), cur);
2017 +       printk("Process %s (pid: %d[#%u], threadinfo %p, task %p)\n",
2018 +               cur->comm, cur->pid, cur->xid,
2019 +               task_thread_info(cur), cur);
2020  
2021         /*
2022          * When in-kernel, we also print out the stack and code at the
2023 @@ -657,8 +658,8 @@ static void __kprobes do_trap(int trapnr
2024         if (user_mode(regs)) {
2025                 if (exception_trace && unhandled_signal(tsk, signr))
2026                         printk(KERN_INFO
2027 -                              "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
2028 -                              tsk->comm, tsk->pid, str,
2029 +                              "%s[%d:#%u] trap %s rip:%lx rsp:%lx error:%lx\n",
2030 +                              tsk->comm, tsk->pid, tsk->xid, str,
2031                                regs->rip, regs->rsp, error_code); 
2032  
2033                 if (info)
2034 @@ -758,8 +759,8 @@ asmlinkage void __kprobes do_general_pro
2035         if (user_mode(regs)) {
2036                 if (exception_trace && unhandled_signal(tsk, SIGSEGV))
2037                         printk(KERN_INFO
2038 -                      "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
2039 -                              tsk->comm, tsk->pid,
2040 +                      "%s[%d:#%u] general protection rip:%lx rsp:%lx error:%lx\n",
2041 +                              tsk->comm, tsk->pid, tsk->xid,
2042                                regs->rip, regs->rsp, error_code); 
2043  
2044                 force_sig(SIGSEGV, tsk);
2045 diff -NurpP --minimal linux-2.6.19.1/arch/x86_64/mm/fault.c linux-2.6.19.1-vs2.3.0.6/arch/x86_64/mm/fault.c
2046 --- linux-2.6.19.1/arch/x86_64/mm/fault.c       2006-11-30 21:18:37 +0100
2047 +++ linux-2.6.19.1-vs2.3.0.6/arch/x86_64/mm/fault.c     2006-11-08 04:57:42 +0100
2048 @@ -514,10 +514,10 @@ bad_area_nosemaphore:
2049  
2050                 if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
2051                         printk(
2052 -                      "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
2053 +                      "%s%s[%d:#%u]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
2054                                         tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
2055 -                                       tsk->comm, tsk->pid, address, regs->rip,
2056 -                                       regs->rsp, error_code);
2057 +                                       tsk->comm, tsk->pid, tsk->xid, address,
2058 +                                       regs->rip, regs->rsp, error_code);
2059                 }
2060         
2061                 tsk->thread.cr2 = address;
2062 diff -NurpP --minimal linux-2.6.19.1/arch/xtensa/kernel/irq.c linux-2.6.19.1-vs2.3.0.6/arch/xtensa/kernel/irq.c
2063 --- linux-2.6.19.1/arch/xtensa/kernel/irq.c     2006-09-20 16:58:06 +0200
2064 +++ linux-2.6.19.1-vs2.3.0.6/arch/xtensa/kernel/irq.c   2006-11-30 18:29:29 +0100
2065 @@ -63,9 +63,7 @@ unsigned int  do_IRQ(int irq, struct pt_
2066                                sp - sizeof(struct thread_info));
2067         }
2068  #endif
2069 -
2070         __do_IRQ(irq, regs);
2071 -
2072         irq_exit();
2073  
2074         return 1;
2075 diff -NurpP --minimal linux-2.6.19.1/arch/xtensa/kernel/process.c linux-2.6.19.1-vs2.3.0.6/arch/xtensa/kernel/process.c
2076 --- linux-2.6.19.1/arch/xtensa/kernel/process.c 2006-09-20 16:58:06 +0200
2077 +++ linux-2.6.19.1-vs2.3.0.6/arch/xtensa/kernel/process.c       2006-11-08 04:57:50 +0100
2078 @@ -206,7 +206,7 @@ int kernel_thread(int (*fn)(void *), voi
2079                  :"=r" (retval)
2080                  :"i" (__NR_clone), "i" (__NR_exit),
2081                  "r" (arg), "r" (fn),
2082 -                "r" (flags | CLONE_VM)
2083 +                "r" (flags | CLONE_VM | CLONE_KTHREAD)
2084                  : "a2", "a3", "a4", "a5", "a6" );
2085         return retval;
2086  }
2087 diff -NurpP --minimal linux-2.6.19.1/block/cfq-iosched.c linux-2.6.19.1-vs2.3.0.6/block/cfq-iosched.c
2088 --- linux-2.6.19.1/block/cfq-iosched.c  2006-11-30 21:18:37 +0100
2089 +++ linux-2.6.19.1-vs2.3.0.6/block/cfq-iosched.c        2006-11-08 21:52:08 +0100
2090 @@ -221,6 +221,8 @@ static int cfq_queue_empty(request_queue
2091  
2092  static inline pid_t cfq_queue_pid(struct task_struct *task, int rw)
2093  {
2094 +       if (task->xid)
2095 +               return task->xid + (1 << 16);
2096         if (rw == READ || rw == WRITE_SYNC)
2097                 return task->pid;
2098  
2099 diff -NurpP --minimal linux-2.6.19.1/drivers/block/Kconfig linux-2.6.19.1-vs2.3.0.6/drivers/block/Kconfig
2100 --- linux-2.6.19.1/drivers/block/Kconfig        2006-12-13 07:46:36 +0100
2101 +++ linux-2.6.19.1-vs2.3.0.6/drivers/block/Kconfig      2006-12-13 09:16:31 +0100
2102 @@ -317,6 +317,13 @@ config BLK_DEV_CRYPTOLOOP
2103           instead, which can be configured to be on-disk compatible with the
2104           cryptoloop device.
2105  
2106 +config BLK_DEV_VROOT
2107 +       tristate "Virtual Root device support"
2108 +       depends on QUOTACTL
2109 +       ---help---
2110 +         Saying Y here will allow you to use quota/fs ioctls on a shared
2111 +         partition within a virtual server without compromising security.
2112 +
2113  config BLK_DEV_NBD
2114         tristate "Network block device support"
2115         depends on NET
2116 diff -NurpP --minimal linux-2.6.19.1/drivers/block/Makefile linux-2.6.19.1-vs2.3.0.6/drivers/block/Makefile
2117 --- linux-2.6.19.1/drivers/block/Makefile       2006-06-18 04:52:46 +0200
2118 +++ linux-2.6.19.1-vs2.3.0.6/drivers/block/Makefile     2006-11-08 04:57:51 +0100
2119 @@ -29,4 +29,5 @@ obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryp
2120  obj-$(CONFIG_VIODASD)          += viodasd.o
2121  obj-$(CONFIG_BLK_DEV_SX8)      += sx8.o
2122  obj-$(CONFIG_BLK_DEV_UB)       += ub.o
2123 +obj-$(CONFIG_BLK_DEV_VROOT)    += vroot.o
2124  
2125 diff -NurpP --minimal linux-2.6.19.1/drivers/block/loop.c linux-2.6.19.1-vs2.3.0.6/drivers/block/loop.c
2126 --- linux-2.6.19.1/drivers/block/loop.c 2006-11-30 21:18:39 +0100
2127 +++ linux-2.6.19.1-vs2.3.0.6/drivers/block/loop.c       2006-11-30 18:53:18 +0100
2128 @@ -74,6 +74,7 @@
2129  #include <linux/highmem.h>
2130  #include <linux/gfp.h>
2131  #include <linux/kthread.h>
2132 +#include <linux/vs_context.h>
2133  
2134  #include <asm/uaccess.h>
2135  
2136 @@ -795,6 +796,7 @@ static int loop_set_fd(struct loop_devic
2137         lo->lo_blocksize = lo_blocksize;
2138         lo->lo_device = bdev;
2139         lo->lo_flags = lo_flags;
2140 +       lo->lo_xid = vx_current_xid();
2141         lo->lo_backing_file = file;
2142         lo->transfer = transfer_none;
2143         lo->ioctl = NULL;
2144 @@ -935,7 +937,7 @@ loop_set_status(struct loop_device *lo, 
2145         struct loop_func_table *xfer;
2146  
2147         if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
2148 -           !capable(CAP_SYS_ADMIN))
2149 +           !vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP))
2150                 return -EPERM;
2151         if (lo->lo_state != Lo_bound)
2152                 return -ENXIO;
2153 @@ -1015,7 +1017,8 @@ loop_get_status(struct loop_device *lo, 
2154         memcpy(info->lo_crypt_name, lo->lo_crypt_name, LO_NAME_SIZE);
2155         info->lo_encrypt_type =
2156                 lo->lo_encryption ? lo->lo_encryption->number : 0;
2157 -       if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
2158 +       if (lo->lo_encrypt_key_size &&
2159 +               vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_CLOOP)) {
2160                 info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
2161                 memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
2162                        lo->lo_encrypt_key_size);
2163 @@ -1326,6 +1329,9 @@ static int lo_open(struct inode *inode, 
2164  {
2165         struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
2166  
2167 +       if (!vx_check(lo->lo_xid, VS_WATCH_P|VS_IDENT))
2168 +               return -EACCES;
2169 +
2170         mutex_lock(&lo->lo_ctl_mutex);
2171         lo->lo_refcnt++;
2172         mutex_unlock(&lo->lo_ctl_mutex);
2173 diff -NurpP --minimal linux-2.6.19.1/drivers/block/vroot.c linux-2.6.19.1-vs2.3.0.6/drivers/block/vroot.c
2174 --- linux-2.6.19.1/drivers/block/vroot.c        1970-01-01 01:00:00 +0100
2175 +++ linux-2.6.19.1-vs2.3.0.6/drivers/block/vroot.c      2006-11-30 19:40:17 +0100
2176 @@ -0,0 +1,281 @@
2177 +/*
2178 + *  linux/drivers/block/vroot.c
2179 + *
2180 + *  written by Herbert Pötzl, 9/11/2002
2181 + *  ported to 2.6.10 by Herbert Pötzl, 30/12/2004
2182 + *
2183 + *  based on the loop.c code by Theodore Ts'o.
2184 + *
2185 + * Copyright (C) 2002-2006 by Herbert Pötzl.
2186 + * Redistribution of this file is permitted under the
2187 + * GNU General Public License.
2188 + *
2189 + */
2190 +
2191 +#include <linux/module.h>
2192 +#include <linux/moduleparam.h>
2193 +#include <linux/file.h>
2194 +#include <linux/major.h>
2195 +#include <linux/blkdev.h>
2196 +
2197 +#include <linux/vroot.h>
2198 +#include <linux/vs_context.h>
2199 +
2200 +
2201 +static int max_vroot = 8;
2202 +
2203 +static struct vroot_device *vroot_dev;
2204 +static struct gendisk **disks;
2205 +
2206 +
2207 +static int vroot_set_dev(
2208 +       struct vroot_device *vr,
2209 +       struct file *vr_file,
2210 +       struct block_device *bdev,
2211 +       unsigned int arg)
2212 +{
2213 +       struct block_device *real_bdev;
2214 +       struct file *file;
2215 +       struct inode *inode;
2216 +       int error;
2217 +
2218 +       error = -EBUSY;
2219 +       if (vr->vr_state != Vr_unbound)
2220 +               goto out;
2221 +
2222 +       error = -EBADF;
2223 +       file = fget(arg);
2224 +       if (!file)
2225 +               goto out;
2226 +
2227 +       error = -EINVAL;
2228 +       inode = file->f_dentry->d_inode;
2229 +
2230 +
2231 +       if (S_ISBLK(inode->i_mode)) {
2232 +               real_bdev = inode->i_bdev;
2233 +               vr->vr_device = real_bdev;
2234 +               __iget(real_bdev->bd_inode);
2235 +       } else
2236 +               goto out_fput;
2237 +
2238 +       vxdprintk(VXD_CBIT(misc, 0),
2239 +               "vroot[%d]_set_dev: dev=" VXF_DEV,
2240 +               vr->vr_number, VXD_DEV(real_bdev));
2241 +
2242 +       vr->vr_state = Vr_bound;
2243 +       error = 0;
2244 +
2245 + out_fput:
2246 +       fput(file);
2247 + out:
2248 +       return error;
2249 +}
2250 +
2251 +static int vroot_clr_dev(
2252 +       struct vroot_device *vr,
2253 +       struct file *vr_file,
2254 +       struct block_device *bdev)
2255 +{
2256 +       struct block_device *real_bdev;
2257 +
2258 +       if (vr->vr_state != Vr_bound)
2259 +               return -ENXIO;
2260 +       if (vr->vr_refcnt > 1)  /* we needed one fd for the ioctl */
2261 +               return -EBUSY;
2262 +
2263 +       real_bdev = vr->vr_device;
2264 +
2265 +       vxdprintk(VXD_CBIT(misc, 0),
2266 +               "vroot[%d]_clr_dev: dev=" VXF_DEV,
2267 +               vr->vr_number, VXD_DEV(real_bdev));
2268 +
2269 +       bdput(real_bdev);
2270 +       vr->vr_state = Vr_unbound;
2271 +       vr->vr_device = NULL;
2272 +       return 0;
2273 +}
2274 +
2275 +
2276 +static int vr_ioctl(struct inode * inode, struct file * file,
2277 +       unsigned int cmd, unsigned long arg)
2278 +{
2279 +       struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
2280 +       int err;
2281 +
2282 +       down(&vr->vr_ctl_mutex);
2283 +       switch (cmd) {
2284 +       case VROOT_SET_DEV:
2285 +               err = vroot_set_dev(vr, file, inode->i_bdev, arg);
2286 +               break;
2287 +       case VROOT_CLR_DEV:
2288 +               err = vroot_clr_dev(vr, file, inode->i_bdev);
2289 +               break;
2290 +       default:
2291 +               err = -EINVAL;
2292 +               break;
2293 +       }
2294 +       up(&vr->vr_ctl_mutex);
2295 +       return err;
2296 +}
2297 +
2298 +static int vr_open(struct inode *inode, struct file *file)
2299 +{
2300 +       struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
2301 +
2302 +       down(&vr->vr_ctl_mutex);
2303 +       vr->vr_refcnt++;
2304 +       up(&vr->vr_ctl_mutex);
2305 +       return 0;
2306 +}
2307 +
2308 +static int vr_release(struct inode *inode, struct file *file)
2309 +{
2310 +       struct vroot_device *vr = inode->i_bdev->bd_disk->private_data;
2311 +
2312 +       down(&vr->vr_ctl_mutex);
2313 +       --vr->vr_refcnt;
2314 +       up(&vr->vr_ctl_mutex);
2315 +       return 0;
2316 +}
2317 +
2318 +static struct block_device_operations vr_fops = {
2319 +       .owner =        THIS_MODULE,
2320 +       .open =         vr_open,
2321 +       .release =      vr_release,
2322 +       .ioctl =        vr_ioctl,
2323 +};
2324 +
2325 +struct block_device *__vroot_get_real_bdev(struct block_device *bdev)
2326 +{
2327 +       struct inode *inode = bdev->bd_inode;
2328 +       struct vroot_device *vr;
2329 +       struct block_device *real_bdev;
2330 +       int minor = iminor(inode);
2331 +
2332 +       vr = &vroot_dev[minor];
2333 +       real_bdev = vr->vr_device;
2334 +
2335 +       vxdprintk(VXD_CBIT(misc, 0),
2336 +               "vroot[%d]_get_real_bdev: dev=" VXF_DEV,
2337 +               vr->vr_number, VXD_DEV(real_bdev));
2338 +
2339 +       if (vr->vr_state != Vr_bound)
2340 +               return ERR_PTR(-ENXIO);
2341 +
2342 +       __iget(real_bdev->bd_inode);
2343 +       return real_bdev;
2344 +}
2345 +
2346 +/*
2347 + * And now the modules code and kernel interface.
2348 + */
2349 +
2350 +module_param(max_vroot, int, 0);
2351 +
2352 +MODULE_PARM_DESC(max_vroot, "Maximum number of vroot devices (1-256)");
2353 +MODULE_LICENSE("GPL");
2354 +MODULE_ALIAS_BLOCKDEV_MAJOR(VROOT_MAJOR);
2355 +
2356 +MODULE_AUTHOR ("Herbert Pötzl");
2357 +MODULE_DESCRIPTION ("Virtual Root Device Mapper");
2358 +
2359 +
2360 +int __init vroot_init(void)
2361 +{
2362 +       int err, i;
2363 +
2364 +       if (max_vroot < 1 || max_vroot > 256) {
2365 +               max_vroot = MAX_VROOT_DEFAULT;
2366 +               printk(KERN_WARNING "vroot: invalid max_vroot "
2367 +                       "(must be between 1 and 256), "
2368 +                       "using default (%d)\n", max_vroot);
2369 +       }
2370 +
2371 +       if (register_blkdev(VROOT_MAJOR, "vroot"))
2372 +               return -EIO;
2373 +
2374 +       err = -ENOMEM;
2375 +       vroot_dev = kmalloc(max_vroot * sizeof(struct vroot_device), GFP_KERNEL);
2376 +       if (!vroot_dev)
2377 +               goto out_mem1;
2378 +       memset(vroot_dev, 0, max_vroot * sizeof(struct vroot_device));
2379 +
2380 +       disks = kmalloc(max_vroot * sizeof(struct gendisk *), GFP_KERNEL);
2381 +       if (!disks)
2382 +               goto out_mem2;
2383 +
2384 +       for (i = 0; i < max_vroot; i++) {
2385 +               disks[i] = alloc_disk(1);
2386 +               if (!disks[i])
2387 +                       goto out_mem3;
2388 +       }
2389 +
2390 +       for (i = 0; i < max_vroot; i++) {
2391 +               struct vroot_device *vr = &vroot_dev[i];
2392 +               struct gendisk *disk = disks[i];
2393 +
2394 +               memset(vr, 0, sizeof(*vr));
2395 +               init_MUTEX(&vr->vr_ctl_mutex);
2396 +               vr->vr_number = i;
2397 +               disk->major = VROOT_MAJOR;
2398 +               disk->first_minor = i;
2399 +               disk->fops = &vr_fops;
2400 +               sprintf(disk->disk_name, "vroot%d", i);
2401 +               disk->private_data = vr;
2402 +       }
2403 +
2404 +       err = register_vroot_grb(&__vroot_get_real_bdev);
2405 +       if (err)
2406 +               goto out_mem3;
2407 +
2408 +       for (i = 0; i < max_vroot; i++)
2409 +               add_disk(disks[i]);
2410 +       printk(KERN_INFO "vroot: loaded (max %d devices)\n", max_vroot);
2411 +       return 0;
2412 +
2413 +out_mem3:
2414 +       while (i--)
2415 +               put_disk(disks[i]);
2416 +       kfree(disks);
2417 +out_mem2:
2418 +       kfree(vroot_dev);
2419 +out_mem1:
2420 +       unregister_blkdev(VROOT_MAJOR, "vroot");
2421 +       printk(KERN_ERR "vroot: ran out of memory\n");
2422 +       return err;
2423 +}
2424 +
2425 +void vroot_exit(void)
2426 +{
2427 +       int i;
2428 +
2429 +       if (unregister_vroot_grb(&__vroot_get_real_bdev))
2430 +               printk(KERN_WARNING "vroot: cannot unregister grb\n");
2431 +
2432 +       for (i = 0; i < max_vroot; i++) {
2433 +               del_gendisk(disks[i]);
2434 +               put_disk(disks[i]);
2435 +       }
2436 +       if (unregister_blkdev(VROOT_MAJOR, "vroot"))
2437 +               printk(KERN_WARNING "vroot: cannot unregister blkdev\n");
2438 +
2439 +       kfree(disks);
2440 +       kfree(vroot_dev);
2441 +}
2442 +
2443 +module_init(vroot_init);
2444 +module_exit(vroot_exit);
2445 +
2446 +#ifndef MODULE
2447 +
2448 +static int __init max_vroot_setup(char *str)
2449 +{
2450 +       max_vroot = simple_strtol(str, NULL, 0);
2451 +       return 1;
2452 +}
2453 +
2454 +__setup("max_vroot=", max_vroot_setup);
2455 +
2456 +#endif
2457 +
2458 diff -NurpP --minimal linux-2.6.19.1/drivers/char/random.c linux-2.6.19.1-vs2.3.0.6/drivers/char/random.c
2459 --- linux-2.6.19.1/drivers/char/random.c        2006-11-30 21:18:40 +0100
2460 +++ linux-2.6.19.1-vs2.3.0.6/drivers/char/random.c      2006-11-08 04:57:40 +0100
2461 @@ -1178,7 +1178,7 @@ static char sysctl_bootid[16];
2462  static int proc_do_uuid(ctl_table *table, int write, struct file *filp,
2463                         void __user *buffer, size_t *lenp, loff_t *ppos)
2464  {
2465 -       ctl_table fake_table;
2466 +       ctl_table fake_table = {0};
2467         unsigned char buf[64], tmp_uuid[16], *uuid;
2468  
2469         uuid = table->data;
2470 diff -NurpP --minimal linux-2.6.19.1/drivers/char/sysrq.c linux-2.6.19.1-vs2.3.0.6/drivers/char/sysrq.c
2471 --- linux-2.6.19.1/drivers/char/sysrq.c 2006-11-30 21:18:41 +0100
2472 +++ linux-2.6.19.1-vs2.3.0.6/drivers/char/sysrq.c       2006-12-02 01:37:05 +0100
2473 @@ -36,6 +36,7 @@
2474  #include <linux/workqueue.h>
2475  #include <linux/kexec.h>
2476  #include <linux/irq.h>
2477 +#include <linux/vserver/debug.h>
2478  
2479  #include <asm/ptrace.h>
2480  #include <asm/irq_regs.h>
2481 @@ -260,6 +261,21 @@ static struct sysrq_key_op sysrq_unrt_op
2482         .enable_mask    = SYSRQ_ENABLE_RTNICE,
2483  };
2484  
2485 +
2486 +#ifdef CONFIG_VSERVER_DEBUG
2487 +static void sysrq_handle_vxinfo(int key, struct tty_struct *tty)
2488 +{
2489 +       dump_vx_info_inactive((key == 'x')?0:1);
2490 +}
2491 +
2492 +static struct sysrq_key_op sysrq_showvxinfo_op = {
2493 +       .handler        = sysrq_handle_vxinfo,
2494 +       .help_msg       = "conteXt",
2495 +       .action_msg     = "Show Context Info",
2496 +       .enable_mask    = SYSRQ_ENABLE_DUMP,
2497 +};
2498 +#endif
2499 +
2500  /* Key Operations table and lock */
2501  static DEFINE_SPINLOCK(sysrq_key_table_lock);
2502  
2503 @@ -304,7 +320,11 @@ static struct sysrq_key_op *sysrq_key_ta
2504         /* May be assigned at init time by SMP VOYAGER */
2505         NULL,                           /* v */
2506         NULL,                           /* w */
2507 +#ifdef CONFIG_VSERVER_DEBUG
2508 +       &sysrq_showvxinfo_op,           /* x */
2509 +#else
2510         NULL,                           /* x */
2511 +#endif
2512         NULL,                           /* y */
2513         NULL                            /* z */
2514  };
2515 @@ -318,6 +338,8 @@ static int sysrq_key_table_key2index(int
2516                 retval = key - '0';
2517         else if ((key >= 'a') && (key <= 'z'))
2518                 retval = key + 10 - 'a';
2519 +       else if ((key >= 'A') && (key <= 'Z'))
2520 +               retval = key + 10 - 'A';
2521         else
2522                 retval = -1;
2523         return retval;
2524 diff -NurpP --minimal linux-2.6.19.1/drivers/char/tty_io.c linux-2.6.19.1-vs2.3.0.6/drivers/char/tty_io.c
2525 --- linux-2.6.19.1/drivers/char/tty_io.c        2006-11-30 21:18:41 +0100
2526 +++ linux-2.6.19.1-vs2.3.0.6/drivers/char/tty_io.c      2006-11-08 04:57:52 +0100
2527 @@ -103,6 +103,7 @@
2528  #include <linux/selection.h>
2529  
2530  #include <linux/kmod.h>
2531 +#include <linux/vs_pid.h>
2532  
2533  #undef TTY_DEBUG_HANGUP
2534  
2535 @@ -2941,13 +2942,16 @@ static int tiocsctty(struct tty_struct *
2536  
2537  static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
2538  {
2539 +       pid_t pgrp;
2540         /*
2541          * (tty == real_tty) is a cheap way of
2542          * testing if the tty is NOT a master pty.
2543          */
2544         if (tty == real_tty && current->signal->tty != real_tty)
2545                 return -ENOTTY;
2546 -       return put_user(real_tty->pgrp, p);
2547 +
2548 +       pgrp = vx_map_pid(real_tty->pgrp);
2549 +       return put_user(pgrp, p);
2550  }
2551  
2552  /**
2553 @@ -2977,6 +2981,8 @@ static int tiocspgrp(struct tty_struct *
2554                 return -ENOTTY;
2555         if (get_user(pgrp, p))
2556                 return -EFAULT;
2557 +
2558 +       pgrp = vx_rmap_pid(pgrp);
2559         if (pgrp < 0)
2560                 return -EINVAL;
2561         if (session_of_pgrp(pgrp) != current->signal->session)
2562 diff -NurpP --minimal linux-2.6.19.1/drivers/infiniband/core/uverbs_mem.c linux-2.6.19.1-vs2.3.0.6/drivers/infiniband/core/uverbs_mem.c
2563 --- linux-2.6.19.1/drivers/infiniband/core/uverbs_mem.c 2006-06-18 04:53:04 +0200
2564 +++ linux-2.6.19.1-vs2.3.0.6/drivers/infiniband/core/uverbs_mem.c       2006-11-08 04:57:47 +0100
2565 @@ -36,6 +36,7 @@
2566  
2567  #include <linux/mm.h>
2568  #include <linux/dma-mapping.h>
2569 +#include <linux/vs_memory.h>
2570  
2571  #include "uverbs.h"
2572  
2573 @@ -161,7 +162,7 @@ out:
2574         if (ret < 0)
2575                 __ib_umem_release(dev, mem, 0);
2576         else
2577 -               current->mm->locked_vm = locked;
2578 +               vx_vmlocked_sub(current->mm, current->mm->locked_vm - locked);
2579  
2580         up_write(&current->mm->mmap_sem);
2581         free_page((unsigned long) page_list);
2582 @@ -174,8 +175,8 @@ void ib_umem_release(struct ib_device *d
2583         __ib_umem_release(dev, umem, 1);
2584  
2585         down_write(&current->mm->mmap_sem);
2586 -       current->mm->locked_vm -=
2587 -               PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
2588 +       vx_vmlocked_sub(current->mm,
2589 +               PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT);
2590         up_write(&current->mm->mmap_sem);
2591  }
2592  
2593 @@ -184,7 +185,7 @@ static void ib_umem_account(void *work_p
2594         struct ib_umem_account_work *work = work_ptr;
2595  
2596         down_write(&work->mm->mmap_sem);
2597 -       work->mm->locked_vm -= work->diff;
2598 +       vx_vmlocked_sub(work->mm, work->diff);
2599         up_write(&work->mm->mmap_sem);
2600         mmput(work->mm);
2601         kfree(work);
2602 diff -NurpP --minimal linux-2.6.19.1/drivers/infiniband/hw/ipath/ipath_user_pages.c linux-2.6.19.1-vs2.3.0.6/drivers/infiniband/hw/ipath/ipath_user_pages.c
2603 --- linux-2.6.19.1/drivers/infiniband/hw/ipath/ipath_user_pages.c       2006-11-30 21:18:44 +0100
2604 +++ linux-2.6.19.1-vs2.3.0.6/drivers/infiniband/hw/ipath/ipath_user_pages.c     2006-11-08 04:57:47 +0100
2605 @@ -33,6 +33,7 @@
2606  
2607  #include <linux/mm.h>
2608  #include <linux/device.h>
2609 +#include <linux/vs_memory.h>
2610  
2611  #include "ipath_kernel.h"
2612  
2613 @@ -61,7 +62,8 @@ static int __get_user_pages(unsigned lon
2614         lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >>
2615                 PAGE_SHIFT;
2616  
2617 -       if (num_pages > lock_limit) {
2618 +       if (num_pages > lock_limit ||
2619 +               !vx_vmlocked_avail(current->mm, num_pages)) {
2620                 ret = -ENOMEM;
2621                 goto bail;
2622         }
2623 @@ -78,7 +80,7 @@ static int __get_user_pages(unsigned lon
2624                         goto bail_release;
2625         }
2626  
2627 -       current->mm->locked_vm += num_pages;
2628 +       vx_vmlocked_add(current->mm, num_pages);
2629  
2630         ret = 0;
2631         goto bail;
2632 @@ -203,7 +205,7 @@ void ipath_release_user_pages(struct pag
2633  
2634         __ipath_release_user_pages(p, num_pages, 1);
2635  
2636 -       current->mm->locked_vm -= num_pages;
2637 +       vx_vmlocked_sub(current->mm, num_pages);
2638  
2639         up_write(&current->mm->mmap_sem);
2640  }
2641 @@ -219,7 +221,7 @@ static void user_pages_account(void *ptr
2642         struct ipath_user_pages_work *work = ptr;
2643  
2644         down_write(&work->mm->mmap_sem);
2645 -       work->mm->locked_vm -= work->num_pages;
2646 +       vx_vmlocked_sub(work->mm, work->num_pages);
2647         up_write(&work->mm->mmap_sem);
2648         mmput(work->mm);
2649         kfree(work);
2650 diff -NurpP --minimal linux-2.6.19.1/drivers/md/dm-ioctl.c linux-2.6.19.1-vs2.3.0.6/drivers/md/dm-ioctl.c
2651 --- linux-2.6.19.1/drivers/md/dm-ioctl.c        2006-11-30 21:18:46 +0100
2652 +++ linux-2.6.19.1-vs2.3.0.6/drivers/md/dm-ioctl.c      2006-11-30 19:57:46 +0100
2653 @@ -15,6 +15,7 @@
2654  #include <linux/slab.h>
2655  #include <linux/dm-ioctl.h>
2656  #include <linux/hdreg.h>
2657 +#include <linux/vs_context.h>
2658  
2659  #include <asm/uaccess.h>
2660  
2661 @@ -100,7 +101,8 @@ static struct hash_cell *__get_name_cell
2662         unsigned int h = hash_str(str);
2663  
2664         list_for_each_entry (hc, _name_buckets + h, name_list)
2665 -               if (!strcmp(hc->name, str)) {
2666 +               if (vx_check(dm_get_xid(hc->md), VS_WATCH_P|VS_IDENT) &&
2667 +                       !strcmp(hc->name, str)) {
2668                         dm_get(hc->md);
2669                         return hc;
2670                 }
2671 @@ -114,7 +116,8 @@ static struct hash_cell *__get_uuid_cell
2672         unsigned int h = hash_str(str);
2673  
2674         list_for_each_entry (hc, _uuid_buckets + h, uuid_list)
2675 -               if (!strcmp(hc->uuid, str)) {
2676 +               if (vx_check(dm_get_xid(hc->md), VS_WATCH_P|VS_IDENT) &&
2677 +                       !strcmp(hc->uuid, str)) {
2678                         dm_get(hc->md);
2679                         return hc;
2680                 }
2681 @@ -349,6 +352,9 @@ typedef int (*ioctl_fn)(struct dm_ioctl 
2682  
2683  static int remove_all(struct dm_ioctl *param, size_t param_size)
2684  {
2685 +       if (!vx_check(0, VS_ADMIN))
2686 +               return -EPERM;
2687 +
2688         dm_hash_remove_all(1);
2689         param->data_size = 0;
2690         return 0;
2691 @@ -396,6 +402,8 @@ static int list_devices(struct dm_ioctl 
2692          */
2693         for (i = 0; i < NUM_BUCKETS; i++) {
2694                 list_for_each_entry (hc, _name_buckets + i, name_list) {
2695 +                       if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P|VS_IDENT))
2696 +                               continue;
2697                         needed += sizeof(struct dm_name_list);
2698                         needed += strlen(hc->name) + 1;
2699                         needed += ALIGN_MASK;
2700 @@ -419,6 +427,8 @@ static int list_devices(struct dm_ioctl 
2701          */
2702         for (i = 0; i < NUM_BUCKETS; i++) {
2703                 list_for_each_entry (hc, _name_buckets + i, name_list) {
2704 +                       if (!vx_check(dm_get_xid(hc->md), VS_WATCH_P|VS_IDENT))
2705 +                               continue;
2706                         if (old_nl)
2707                                 old_nl->next = (uint32_t) ((void *) nl -
2708                                                            (void *) old_nl);
2709 @@ -609,10 +619,11 @@ static struct hash_cell *__find_device_h
2710         if (!md)
2711                 goto out;
2712  
2713 -       mdptr = dm_get_mdptr(md);
2714 +       if (vx_check(dm_get_xid(md), VS_WATCH_P|VS_IDENT))
2715 +               mdptr = dm_get_mdptr(md);
2716 +
2717         if (!mdptr)
2718                 dm_put(md);
2719 -
2720  out:
2721         return mdptr;
2722  }
2723 @@ -1405,8 +1416,8 @@ static int ctl_ioctl(struct inode *inode
2724         ioctl_fn fn = NULL;
2725         size_t param_size;
2726  
2727 -       /* only root can play with this */
2728 -       if (!capable(CAP_SYS_ADMIN))
2729 +       /* only root and certain contexts can play with this */
2730 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_ADMIN_MAPPER))
2731                 return -EACCES;
2732  
2733         if (_IOC_TYPE(command) != DM_IOCTL)
2734 diff -NurpP --minimal linux-2.6.19.1/drivers/md/dm.c linux-2.6.19.1-vs2.3.0.6/drivers/md/dm.c
2735 --- linux-2.6.19.1/drivers/md/dm.c      2006-11-30 21:18:46 +0100
2736 +++ linux-2.6.19.1-vs2.3.0.6/drivers/md/dm.c    2006-11-30 18:53:18 +0100
2737 @@ -21,6 +21,7 @@
2738  #include <linux/hdreg.h>
2739  #include <linux/blktrace_api.h>
2740  #include <linux/smp_lock.h>
2741 +#include <linux/vs_base.h>
2742  
2743  #define DM_MSG_PREFIX "core"
2744  
2745 @@ -75,6 +76,7 @@ struct mapped_device {
2746         rwlock_t map_lock;
2747         atomic_t holders;
2748         atomic_t open_count;
2749 +       xid_t xid;
2750  
2751         unsigned long flags;
2752  
2753 @@ -220,6 +222,7 @@ static void __exit dm_exit(void)
2754  static int dm_blk_open(struct inode *inode, struct file *file)
2755  {
2756         struct mapped_device *md;
2757 +       int ret = -ENXIO;
2758  
2759         spin_lock(&_minor_lock);
2760  
2761 @@ -228,18 +231,19 @@ static int dm_blk_open(struct inode *ino
2762                 goto out;
2763  
2764         if (test_bit(DMF_FREEING, &md->flags) ||
2765 -           test_bit(DMF_DELETING, &md->flags)) {
2766 -               md = NULL;
2767 +           test_bit(DMF_DELETING, &md->flags))
2768 +               goto out;
2769 +
2770 +       ret = -EACCES;
2771 +       if (!vx_check(md->xid, VS_IDENT))
2772                 goto out;
2773 -       }
2774  
2775         dm_get(md);
2776         atomic_inc(&md->open_count);
2777 -
2778 +       ret = 0;
2779  out:
2780         spin_unlock(&_minor_lock);
2781 -
2782 -       return md ? 0 : -ENXIO;
2783 +       return ret;
2784  }
2785  
2786  static int dm_blk_close(struct inode *inode, struct file *file)
2787 @@ -435,6 +439,14 @@ int dm_set_geometry(struct mapped_device
2788         return 0;
2789  }
2790  
2791 +/*
2792 + * Get the xid associated with a dm device
2793 + */
2794 +xid_t dm_get_xid(struct mapped_device *md)
2795 +{
2796 +       return md->xid;
2797 +}
2798 +
2799  /*-----------------------------------------------------------------
2800   * CRUD START:
2801   *   A more elegant soln is in the works that uses the queue
2802 @@ -952,6 +964,7 @@ static struct mapped_device *alloc_dev(i
2803         atomic_set(&md->holders, 1);
2804         atomic_set(&md->open_count, 0);
2805         atomic_set(&md->event_nr, 0);
2806 +       md->xid = vx_current_xid();
2807  
2808         md->queue = blk_alloc_queue(GFP_KERNEL);
2809         if (!md->queue)
2810 diff -NurpP --minimal linux-2.6.19.1/drivers/md/dm.h linux-2.6.19.1-vs2.3.0.6/drivers/md/dm.h
2811 --- linux-2.6.19.1/drivers/md/dm.h      2006-11-30 21:18:46 +0100
2812 +++ linux-2.6.19.1-vs2.3.0.6/drivers/md/dm.h    2006-11-08 04:57:52 +0100
2813 @@ -72,6 +72,8 @@ void dm_put_target_type(struct target_ty
2814  int dm_target_iterate(void (*iter_func)(struct target_type *tt,
2815                                         void *param), void *param);
2816  
2817 +xid_t dm_get_xid(struct mapped_device *md);
2818 +
2819  /*-----------------------------------------------------------------
2820   * Useful inlines.
2821   *---------------------------------------------------------------*/
2822 diff -NurpP --minimal linux-2.6.19.1/fs/attr.c linux-2.6.19.1-vs2.3.0.6/fs/attr.c
2823 --- linux-2.6.19.1/fs/attr.c    2006-04-09 13:49:53 +0200
2824 +++ linux-2.6.19.1-vs2.3.0.6/fs/attr.c  2006-11-30 19:40:56 +0100
2825 @@ -15,6 +15,9 @@
2826  #include <linux/fcntl.h>
2827  #include <linux/quotaops.h>
2828  #include <linux/security.h>
2829 +#include <linux/proc_fs.h>
2830 +#include <linux/devpts_fs.h>
2831 +#include <linux/vs_base.h>
2832  
2833  /* Taken over from the old code... */
2834  
2835 @@ -56,6 +59,30 @@ int inode_change_ok(struct inode *inode,
2836                 if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER))
2837                         goto error;
2838         }
2839 +
2840 +       /* Check for evil vserver activity */
2841 +       if (vx_check(0, VS_ADMIN))
2842 +               goto fine;
2843 +
2844 +       if (IS_BARRIER(inode)) {
2845 +               vxwprintk(1, "xid=%d messing with the barrier.",
2846 +                       vx_current_xid());
2847 +               goto error;
2848 +       }
2849 +       switch (inode->i_sb->s_magic) {
2850 +               case PROC_SUPER_MAGIC:
2851 +                       /* maybe allow that in the future? */
2852 +                       vxwprintk(1, "xid=%d messing with the procfs.",
2853 +                               vx_current_xid());
2854 +                       goto error;
2855 +               case DEVPTS_SUPER_MAGIC:
2856 +                       /* devpts is xid tagged */
2857 +                       if (vx_check((xid_t)inode->i_tag, VS_IDENT))
2858 +                               goto fine;
2859 +                       vxwprintk(1, "xid=%d messing with the devpts.",
2860 +                               vx_current_xid());
2861 +                       goto error;
2862 +       }
2863  fine:
2864         retval = 0;
2865  error:
2866 @@ -79,6 +106,8 @@ int inode_setattr(struct inode * inode, 
2867                 inode->i_uid = attr->ia_uid;
2868         if (ia_valid & ATTR_GID)
2869                 inode->i_gid = attr->ia_gid;
2870 +       if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode))
2871 +               inode->i_tag = attr->ia_tag;
2872         if (ia_valid & ATTR_ATIME)
2873                 inode->i_atime = timespec_trunc(attr->ia_atime,
2874                                                 inode->i_sb->s_time_gran);
2875 @@ -153,7 +182,8 @@ int notify_change(struct dentry * dentry
2876                         error = security_inode_setattr(dentry, attr);
2877                 if (!error) {
2878                         if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
2879 -                           (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
2880 +                           (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
2881 +                           (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag))
2882                                 error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
2883                         if (!error)
2884                                 error = inode_setattr(inode, attr);
2885 diff -NurpP --minimal linux-2.6.19.1/fs/binfmt_aout.c linux-2.6.19.1-vs2.3.0.6/fs/binfmt_aout.c
2886 --- linux-2.6.19.1/fs/binfmt_aout.c     2006-11-30 21:19:18 +0100
2887 +++ linux-2.6.19.1-vs2.3.0.6/fs/binfmt_aout.c   2006-11-08 04:57:40 +0100
2888 @@ -24,6 +24,7 @@
2889  #include <linux/binfmts.h>
2890  #include <linux/personality.h>
2891  #include <linux/init.h>
2892 +#include <linux/vs_memory.h>
2893  
2894  #include <asm/system.h>
2895  #include <asm/uaccess.h>
2896 diff -NurpP --minimal linux-2.6.19.1/fs/binfmt_elf.c linux-2.6.19.1-vs2.3.0.6/fs/binfmt_elf.c
2897 --- linux-2.6.19.1/fs/binfmt_elf.c      2006-11-30 21:19:18 +0100
2898 +++ linux-2.6.19.1-vs2.3.0.6/fs/binfmt_elf.c    2006-12-02 01:37:05 +0100
2899 @@ -39,6 +39,7 @@
2900  #include <linux/syscalls.h>
2901  #include <linux/random.h>
2902  #include <linux/elf.h>
2903 +#include <linux/vs_memory.h>
2904  #include <asm/uaccess.h>
2905  #include <asm/param.h>
2906  #include <asm/page.h>
2907 diff -NurpP --minimal linux-2.6.19.1/fs/binfmt_flat.c linux-2.6.19.1-vs2.3.0.6/fs/binfmt_flat.c
2908 --- linux-2.6.19.1/fs/binfmt_flat.c     2006-09-20 16:58:34 +0200
2909 +++ linux-2.6.19.1-vs2.3.0.6/fs/binfmt_flat.c   2006-11-08 04:57:40 +0100
2910 @@ -36,6 +36,7 @@
2911  #include <linux/init.h>
2912  #include <linux/flat.h>
2913  #include <linux/syscalls.h>
2914 +#include <linux/vs_memory.h>
2915  
2916  #include <asm/byteorder.h>
2917  #include <asm/system.h>
2918 diff -NurpP --minimal linux-2.6.19.1/fs/binfmt_som.c linux-2.6.19.1-vs2.3.0.6/fs/binfmt_som.c
2919 --- linux-2.6.19.1/fs/binfmt_som.c      2006-11-30 21:19:19 +0100
2920 +++ linux-2.6.19.1-vs2.3.0.6/fs/binfmt_som.c    2006-11-08 04:57:40 +0100
2921 @@ -28,6 +28,7 @@
2922  #include <linux/shm.h>
2923  #include <linux/personality.h>
2924  #include <linux/init.h>
2925 +#include <linux/vs_memory.h>
2926  
2927  #include <asm/a.out.h>
2928  #include <asm/uaccess.h>
2929 diff -NurpP --minimal linux-2.6.19.1/fs/dcache.c linux-2.6.19.1-vs2.3.0.6/fs/dcache.c
2930 --- linux-2.6.19.1/fs/dcache.c  2006-11-30 21:19:19 +0100
2931 +++ linux-2.6.19.1-vs2.3.0.6/fs/dcache.c        2006-11-08 04:57:48 +0100
2932 @@ -32,6 +32,7 @@
2933  #include <linux/seqlock.h>
2934  #include <linux/swap.h>
2935  #include <linux/bootmem.h>
2936 +#include <linux/vs_limit.h>
2937  #include "internal.h"
2938  
2939  
2940 @@ -147,6 +148,7 @@ void dput(struct dentry *dentry)
2941         if (!dentry)
2942                 return;
2943  
2944 +       vx_dentry_dec(dentry);
2945  repeat:
2946         if (atomic_read(&dentry->d_count) == 1)
2947                 might_sleep();
2948 @@ -160,6 +162,8 @@ repeat:
2949                 return;
2950         }
2951  
2952 +       vx_dentry_dec(dentry);
2953 +
2954         /*
2955          * AV: ->d_delete() is _NOT_ allowed to block now.
2956          */
2957 @@ -270,6 +274,7 @@ static inline struct dentry * __dget_loc
2958         if (!list_empty(&dentry->d_lru)) {
2959                 dentry_stat.nr_unused--;
2960                 list_del_init(&dentry->d_lru);
2961 +               vx_dentry_inc(dentry);
2962         }
2963         return dentry;
2964  }
2965 @@ -861,6 +866,9 @@ struct dentry *d_alloc(struct dentry * p
2966         struct dentry *dentry;
2967         char *dname;
2968  
2969 +       if (!vx_dentry_avail(1))
2970 +               return NULL;
2971 +
2972         dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); 
2973         if (!dentry)
2974                 return NULL;
2975 @@ -909,6 +917,7 @@ struct dentry *d_alloc(struct dentry * p
2976         if (parent)
2977                 list_add(&dentry->d_u.d_child, &parent->d_subdirs);
2978         dentry_stat.nr_dentry++;
2979 +       vx_dentry_inc(dentry);
2980         spin_unlock(&dcache_lock);
2981  
2982         return dentry;
2983 @@ -1258,6 +1267,7 @@ struct dentry * __d_lookup(struct dentry
2984  
2985                 if (!d_unhashed(dentry)) {
2986                         atomic_inc(&dentry->d_count);
2987 +                       vx_dentry_inc(dentry);
2988                         found = dentry;
2989                 }
2990                 spin_unlock(&dentry->d_lock);
2991 diff -NurpP --minimal linux-2.6.19.1/fs/devpts/inode.c linux-2.6.19.1-vs2.3.0.6/fs/devpts/inode.c
2992 --- linux-2.6.19.1/fs/devpts/inode.c    2006-11-30 21:19:19 +0100
2993 +++ linux-2.6.19.1-vs2.3.0.6/fs/devpts/inode.c  2006-11-30 18:53:18 +0100
2994 @@ -19,8 +19,22 @@
2995  #include <linux/tty.h>
2996  #include <linux/devpts_fs.h>
2997  #include <linux/parser.h>
2998 +#include <linux/vs_base.h>
2999  
3000 -#define DEVPTS_SUPER_MAGIC 0x1cd1
3001 +
3002 +static int devpts_permission(struct inode *inode, int mask, struct nameidata *nd)
3003 +{
3004 +       int ret = -EACCES;
3005 +
3006 +       /* devpts is xid tagged */
3007 +       if (vx_check((xid_t)inode->i_tag, VS_WATCH_P|VS_IDENT))
3008 +               ret = generic_permission(inode, mask, NULL);
3009 +       return ret;
3010 +}
3011 +
3012 +static struct inode_operations devpts_file_inode_operations = {
3013 +       .permission     = devpts_permission,
3014 +};
3015  
3016  static struct vfsmount *devpts_mnt;
3017  static struct dentry *devpts_root;
3018 @@ -91,6 +105,25 @@ static int devpts_remount(struct super_b
3019         return 0;
3020  }
3021  
3022 +static int devpts_filter(struct dentry *de)
3023 +{
3024 +       /* devpts is xid tagged */
3025 +       return vx_check((xid_t)de->d_inode->i_tag, VS_WATCH_P|VS_IDENT);
3026 +}
3027 +
3028 +static int devpts_readdir(struct file * filp, void * dirent, filldir_t filldir)
3029 +{
3030 +       return dcache_readdir_filter(filp, dirent, filldir, devpts_filter);
3031 +}
3032 +
3033 +static struct file_operations devpts_dir_operations = {
3034 +       .open           = dcache_dir_open,
3035 +       .release        = dcache_dir_close,
3036 +       .llseek         = dcache_dir_lseek,
3037 +       .read           = generic_read_dir,
3038 +       .readdir        = devpts_readdir,
3039 +};
3040 +
3041  static struct super_operations devpts_sops = {
3042         .statfs         = simple_statfs,
3043         .remount_fs     = devpts_remount,
3044 @@ -116,8 +149,10 @@ devpts_fill_super(struct super_block *s,
3045         inode->i_uid = inode->i_gid = 0;
3046         inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
3047         inode->i_op = &simple_dir_inode_operations;
3048 -       inode->i_fop = &simple_dir_operations;
3049 +       inode->i_fop = &devpts_dir_operations;
3050         inode->i_nlink = 2;
3051 +       /* devpts is xid tagged */
3052 +       inode->i_tag = (tag_t)vx_current_xid();
3053  
3054         devpts_root = s->s_root = d_alloc_root(inode);
3055         if (s->s_root)
3056 @@ -175,6 +210,9 @@ int devpts_pty_new(struct tty_struct *tt
3057         inode->i_gid = config.setgid ? config.gid : current->fsgid;
3058         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
3059         init_special_inode(inode, S_IFCHR|config.mode, device);
3060 +       /* devpts is xid tagged */
3061 +       inode->i_tag = (tag_t)vx_current_xid();
3062 +       inode->i_op = &devpts_file_inode_operations;
3063         inode->i_private = tty;
3064  
3065         dentry = get_node(number);
3066 diff -NurpP --minimal linux-2.6.19.1/fs/dquot.c linux-2.6.19.1-vs2.3.0.6/fs/dquot.c
3067 --- linux-2.6.19.1/fs/dquot.c   2006-11-30 21:19:19 +0100
3068 +++ linux-2.6.19.1-vs2.3.0.6/fs/dquot.c 2006-11-30 19:41:09 +0100
3069 @@ -185,7 +185,7 @@ static void put_quota_format(struct quot
3070  /*
3071   * Dquot List Management:
3072   * The quota code uses three lists for dquot management: the inuse_list,
3073 - * free_dquots, and dquot_hash[] array. A single dquot structure may be
3074 + * free_dquots, and hash->dqh_hash[] array. A single dquot structure may be
3075   * on all three lists, depending on its current state.
3076   *
3077   * All dquots are placed to the end of inuse_list when first created, and this
3078 @@ -198,7 +198,7 @@ static void put_quota_format(struct quot
3079   * dquot is invalidated it's completely released from memory.
3080   *
3081   * Dquots with a specific identity (device, type and id) are placed on
3082 - * one of the dquot_hash[] hash chains. The provides an efficient search
3083 + * one of the hash->dqh_hash[] hash chains. The provides an efficient search
3084   * mechanism to locate a specific dquot.
3085   */
3086  
3087 @@ -212,36 +212,44 @@ struct dqstats dqstats;
3088  static void dqput(struct dquot *dquot);
3089  
3090  static inline unsigned int
3091 -hashfn(const struct super_block *sb, unsigned int id, int type)
3092 +hashfn(struct dqhash *hash, unsigned int id, int type)
3093  {
3094         unsigned long tmp;
3095  
3096 -       tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type);
3097 +       tmp = (((unsigned long)hash >> L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type);
3098         return (tmp + (tmp >> dq_hash_bits)) & dq_hash_mask;
3099  }
3100  
3101  /*
3102   * Following list functions expect dq_list_lock to be held
3103   */
3104 -static inline void insert_dquot_hash(struct dquot *dquot)
3105 +static inline void insert_dquot_hash(struct dqhash *hash, struct dquot *dquot)
3106  {
3107 -       struct hlist_head *head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
3108 +       struct hlist_head *head = dquot_hash +
3109 +               hashfn(hash, dquot->dq_id, dquot->dq_type);
3110 +       /* struct hlist_head *head = hash->dqh_hash +
3111 +               hashfn(dquot->dq_dqh, dquot->dq_id, dquot->dq_type); */
3112         hlist_add_head(&dquot->dq_hash, head);
3113 +       dquot->dq_dqh = dqhget(hash);
3114  }
3115  
3116  static inline void remove_dquot_hash(struct dquot *dquot)
3117  {
3118         hlist_del_init(&dquot->dq_hash);
3119 +       dqhput(dquot->dq_dqh);
3120 +       dquot->dq_dqh = NULL;
3121  }
3122  
3123 -static inline struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, unsigned int id, int type)
3124 +static inline struct dquot *find_dquot(struct dqhash *hash,
3125 +       unsigned int hashent, unsigned int id, int type)
3126  {
3127         struct hlist_node *node;
3128         struct dquot *dquot;
3129  
3130 -       hlist_for_each (node, dquot_hash+hashent) {
3131 +       /* hlist_for_each (node, hash->dqh_hash + hashent) { */
3132 +       hlist_for_each (node, dquot_hash + hashent) {
3133                 dquot = hlist_entry(node, struct dquot, dq_hash);
3134 -               if (dquot->dq_sb == sb && dquot->dq_id == id && dquot->dq_type == type)
3135 +               if (dquot->dq_dqh == hash && dquot->dq_id == id && dquot->dq_type == type)
3136                         return dquot;
3137         }
3138         return NODQUOT;
3139 @@ -285,13 +293,13 @@ static void wait_on_dquot(struct dquot *
3140         mutex_unlock(&dquot->dq_lock);
3141  }
3142  
3143 -#define mark_dquot_dirty(dquot) ((dquot)->dq_sb->dq_op->mark_dirty(dquot))
3144 +#define mark_dquot_dirty(dquot) ((dquot)->dq_dqh->dqh_qop->mark_dirty(dquot))
3145  
3146  int dquot_mark_dquot_dirty(struct dquot *dquot)
3147  {
3148         spin_lock(&dq_list_lock);
3149         if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags))
3150 -               list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)->
3151 +               list_add(&dquot->dq_dirty, &dqh_dqopt(dquot->dq_dqh)->
3152                                 info[dquot->dq_type].dqi_dirty_list);
3153         spin_unlock(&dq_list_lock);
3154         return 0;
3155 @@ -306,9 +314,9 @@ static inline int clear_dquot_dirty(stru
3156         return 1;
3157  }
3158  
3159 -void mark_info_dirty(struct super_block *sb, int type)
3160 +void mark_info_dirty(struct dqhash *hash, int type)
3161  {
3162 -       set_bit(DQF_INFO_DIRTY_B, &sb_dqopt(sb)->info[type].dqi_flags);
3163 +       set_bit(DQF_INFO_DIRTY_B, &dqh_dqopt(hash)->info[type].dqi_flags);
3164  }
3165  EXPORT_SYMBOL(mark_info_dirty);
3166  
3167 @@ -319,7 +327,7 @@ EXPORT_SYMBOL(mark_info_dirty);
3168  int dquot_acquire(struct dquot *dquot)
3169  {
3170         int ret = 0, ret2 = 0;
3171 -       struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
3172 +       struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh);
3173  
3174         mutex_lock(&dquot->dq_lock);
3175         mutex_lock(&dqopt->dqio_mutex);
3176 @@ -333,7 +341,7 @@ int dquot_acquire(struct dquot *dquot)
3177                 ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
3178                 /* Write the info if needed */
3179                 if (info_dirty(&dqopt->info[dquot->dq_type]))
3180 -                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
3181 +                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type);
3182                 if (ret < 0)
3183                         goto out_iolock;
3184                 if (ret2 < 0) {
3185 @@ -354,7 +362,7 @@ out_iolock:
3186  int dquot_commit(struct dquot *dquot)
3187  {
3188         int ret = 0, ret2 = 0;
3189 -       struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
3190 +       struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh);
3191  
3192         mutex_lock(&dqopt->dqio_mutex);
3193         spin_lock(&dq_list_lock);
3194 @@ -368,7 +376,7 @@ int dquot_commit(struct dquot *dquot)
3195         if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
3196                 ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
3197                 if (info_dirty(&dqopt->info[dquot->dq_type]))
3198 -                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
3199 +                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type);
3200                 if (ret >= 0)
3201                         ret = ret2;
3202         }
3203 @@ -383,7 +391,7 @@ out_sem:
3204  int dquot_release(struct dquot *dquot)
3205  {
3206         int ret = 0, ret2 = 0;
3207 -       struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
3208 +       struct quota_info *dqopt = dqh_dqopt(dquot->dq_dqh);
3209  
3210         mutex_lock(&dquot->dq_lock);
3211         /* Check whether we are not racing with some other dqget() */
3212 @@ -394,7 +402,7 @@ int dquot_release(struct dquot *dquot)
3213                 ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);
3214                 /* Write the info */
3215                 if (info_dirty(&dqopt->info[dquot->dq_type]))
3216 -                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
3217 +                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_dqh, dquot->dq_type);
3218                 if (ret >= 0)
3219                         ret = ret2;
3220         }
3221 @@ -411,14 +419,14 @@ out_dqlock:
3222   * just deleted or pruned by prune_icache() (those are not attached to any
3223   * list). We have to wait for such users.
3224   */
3225 -static void invalidate_dquots(struct super_block *sb, int type)
3226 +static void invalidate_dquots(struct dqhash *hash, int type)
3227  {
3228         struct dquot *dquot, *tmp;
3229  
3230  restart:
3231         spin_lock(&dq_list_lock);
3232         list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
3233 -               if (dquot->dq_sb != sb)
3234 +               if (dquot->dq_dqh != hash)
3235                         continue;
3236                 if (dquot->dq_type != type)
3237                         continue;
3238 @@ -458,18 +466,18 @@ restart:
3239         spin_unlock(&dq_list_lock);
3240  }
3241  
3242 -int vfs_quota_sync(struct super_block *sb, int type)
3243 +int vfs_quota_sync(struct dqhash *hash, int type)
3244  {
3245         struct list_head *dirty;
3246         struct dquot *dquot;
3247 -       struct quota_info *dqopt = sb_dqopt(sb);
3248 +       struct quota_info *dqopt = dqh_dqopt(hash);
3249         int cnt;
3250  
3251         mutex_lock(&dqopt->dqonoff_mutex);
3252         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
3253                 if (type != -1 && cnt != type)
3254                         continue;
3255 -               if (!sb_has_quota_enabled(sb, cnt))
3256 +               if (!dqh_has_quota_enabled(hash, cnt))
3257                         continue;
3258                 spin_lock(&dq_list_lock);
3259                 dirty = &dqopt->info[cnt].dqi_dirty_list;
3260 @@ -486,7 +494,7 @@ int vfs_quota_sync(struct super_block *s
3261                         atomic_inc(&dquot->dq_count);
3262                         dqstats.lookups++;
3263                         spin_unlock(&dq_list_lock);
3264 -                       sb->dq_op->write_dquot(dquot);
3265 +                       hash->dqh_qop->write_dquot(dquot);
3266                         dqput(dquot);
3267                         spin_lock(&dq_list_lock);
3268                 }
3269 @@ -494,9 +502,10 @@ int vfs_quota_sync(struct super_block *s
3270         }
3271  
3272         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3273 -               if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt)
3274 +               if ((cnt == type || type == -1)
3275 +                       && dqh_has_quota_enabled(hash, cnt)
3276                         && info_dirty(&dqopt->info[cnt]))
3277 -                       sb->dq_op->write_info(sb, cnt);
3278 +                       hash->dqh_qop->write_info(hash, cnt);
3279         spin_lock(&dq_list_lock);
3280         dqstats.syncs++;
3281         spin_unlock(&dq_list_lock);
3282 @@ -551,7 +560,7 @@ static void dqput(struct dquot *dquot)
3283         if (!atomic_read(&dquot->dq_count)) {
3284                 printk("VFS: dqput: trying to free free dquot\n");
3285                 printk("VFS: device %s, dquot of %s %d\n",
3286 -                       dquot->dq_sb->s_id,
3287 +                       dquot->dq_dqh->dqh_sb->s_id,
3288                         quotatypes[dquot->dq_type],
3289                         dquot->dq_id);
3290                 BUG();
3291 @@ -567,7 +576,7 @@ we_slept:
3292                 /* We have more than one user... nothing to do */
3293                 atomic_dec(&dquot->dq_count);
3294                 /* Releasing dquot during quotaoff phase? */
3295 -               if (!sb_has_quota_enabled(dquot->dq_sb, dquot->dq_type) &&
3296 +               if (!dqh_has_quota_enabled(dquot->dq_dqh, dquot->dq_type) &&
3297                     atomic_read(&dquot->dq_count) == 1)
3298                         wake_up(&dquot->dq_wait_unused);
3299                 spin_unlock(&dq_list_lock);
3300 @@ -577,14 +586,14 @@ we_slept:
3301         if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) {
3302                 spin_unlock(&dq_list_lock);
3303                 /* Commit dquot before releasing */
3304 -               dquot->dq_sb->dq_op->write_dquot(dquot);
3305 +               dquot->dq_dqh->dqh_qop->write_dquot(dquot);
3306                 goto we_slept;
3307         }
3308         /* Clear flag in case dquot was inactive (something bad happened) */
3309         clear_dquot_dirty(dquot);
3310         if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
3311                 spin_unlock(&dq_list_lock);
3312 -               dquot->dq_sb->dq_op->release_dquot(dquot);
3313 +               dquot->dq_dqh->dqh_qop->release_dquot(dquot);
3314                 goto we_slept;
3315         }
3316         atomic_dec(&dquot->dq_count);
3317 @@ -596,7 +605,7 @@ we_slept:
3318         spin_unlock(&dq_list_lock);
3319  }
3320  
3321 -static struct dquot *get_empty_dquot(struct super_block *sb, int type)
3322 +static struct dquot *get_empty_dquot(int type)
3323  {
3324         struct dquot *dquot;
3325  
3326 @@ -611,7 +620,7 @@ static struct dquot *get_empty_dquot(str
3327         INIT_HLIST_NODE(&dquot->dq_hash);
3328         INIT_LIST_HEAD(&dquot->dq_dirty);
3329         init_waitqueue_head(&dquot->dq_wait_unused);
3330 -       dquot->dq_sb = sb;
3331 +       dquot->dq_dqh = NULL;
3332         dquot->dq_type = type;
3333         atomic_set(&dquot->dq_count, 1);
3334  
3335 @@ -622,19 +631,19 @@ static struct dquot *get_empty_dquot(str
3336   * Get reference to dquot
3337   * MUST be called with either dqptr_sem or dqonoff_mutex held
3338   */
3339 -static struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
3340 +static struct dquot *dqget(struct dqhash *hash, unsigned int id, int type)
3341  {
3342 -       unsigned int hashent = hashfn(sb, id, type);
3343 +       unsigned int hashent = hashfn(hash, id, type);
3344         struct dquot *dquot, *empty = NODQUOT;
3345  
3346 -        if (!sb_has_quota_enabled(sb, type))
3347 +       if (!dqh_has_quota_enabled(hash, type))
3348                 return NODQUOT;
3349  we_slept:
3350         spin_lock(&dq_list_lock);
3351 -       if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) {
3352 +       if ((dquot = find_dquot(hash, hashent, id, type)) == NODQUOT) {
3353                 if (empty == NODQUOT) {
3354                         spin_unlock(&dq_list_lock);
3355 -                       if ((empty = get_empty_dquot(sb, type)) == NODQUOT)
3356 +                       if ((empty = get_empty_dquot(type)) == NODQUOT)
3357                                 schedule();     /* Try to wait for a moment... */
3358                         goto we_slept;
3359                 }
3360 @@ -643,7 +652,7 @@ we_slept:
3361                 /* all dquots go on the inuse_list */
3362                 put_inuse(dquot);
3363                 /* hash it first so it can be found */
3364 -               insert_dquot_hash(dquot);
3365 +               insert_dquot_hash(hash, dquot);
3366                 dqstats.lookups++;
3367                 spin_unlock(&dq_list_lock);
3368         } else {
3369 @@ -660,12 +669,13 @@ we_slept:
3370          * finished or it will be canceled due to dq_count > 1 test */
3371         wait_on_dquot(dquot);
3372         /* Read the dquot and instantiate it (everything done only if needed) */
3373 -       if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) {
3374 +       if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) &&
3375 +               hash->dqh_qop->acquire_dquot(dquot) < 0) {
3376                 dqput(dquot);
3377                 return NODQUOT;
3378         }
3379  #ifdef __DQUOT_PARANOIA
3380 -       BUG_ON(!dquot->dq_sb);  /* Has somebody invalidated entry under us? */
3381 +       BUG_ON(!dquot->dq_dqh); /* Has somebody invalidated entry under us? */
3382  #endif
3383  
3384         return dquot;
3385 @@ -686,9 +696,10 @@ static int dqinit_needed(struct inode *i
3386  }
3387  
3388  /* This routine is guarded by dqonoff_mutex mutex */
3389 -static void add_dquot_ref(struct super_block *sb, int type)
3390 +static void add_dquot_ref(struct dqhash *hash, int type)
3391  {
3392         struct list_head *p;
3393 +       struct super_block *sb = hash->dqh_sb;
3394  
3395  restart:
3396         file_list_lock();
3397 @@ -698,7 +709,7 @@ restart:
3398                 if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
3399                         struct dentry *dentry = dget(filp->f_dentry);
3400                         file_list_unlock();
3401 -                       sb->dq_op->initialize(inode, type);
3402 +                       hash->dqh_qop->initialize(inode, type);
3403                         dput(dentry);
3404                         /* As we may have blocked we had better restart... */
3405                         goto restart;
3406 @@ -757,13 +768,13 @@ static void put_dquot_list(struct list_h
3407  }
3408  
3409  /* Gather all references from inodes and drop them */
3410 -static void drop_dquot_ref(struct super_block *sb, int type)
3411 +static void drop_dquot_ref(struct dqhash *hash, int type)
3412  {
3413         LIST_HEAD(tofree_head);
3414  
3415 -       down_write(&sb_dqopt(sb)->dqptr_sem);
3416 -       remove_dquot_ref(sb, type, &tofree_head);
3417 -       up_write(&sb_dqopt(sb)->dqptr_sem);
3418 +       down_write(&dqh_dqopt(hash)->dqptr_sem);
3419 +       remove_dquot_ref(hash, type, &tofree_head);
3420 +       up_write(&dqh_dqopt(hash)->dqptr_sem);
3421         put_dquot_list(&tofree_head);
3422  }
3423  
3424 @@ -837,7 +848,7 @@ static void print_warning(struct dquot *
3425         mutex_lock(&tty_mutex);
3426         if (!current->signal->tty)
3427                 goto out_lock;
3428 -       tty_write_message(current->signal->tty, dquot->dq_sb->s_id);
3429 +       tty_write_message(current->signal->tty, dquot->dq_dqh->dqh_sb->s_id);
3430         if (warntype == ISOFTWARN || warntype == BSOFTWARN)
3431                 tty_write_message(current->signal->tty, ": warning, ");
3432         else
3433 @@ -879,7 +890,7 @@ static inline void flush_warnings(struct
3434  
3435  static inline char ignore_hardlimit(struct dquot *dquot)
3436  {
3437 -       struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
3438 +       struct mem_dqinfo *info = &dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type];
3439  
3440         return capable(CAP_SYS_RESOURCE) &&
3441             (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || !(info->dqi_flags & V1_DQF_RSQUASH));
3442 @@ -911,7 +922,7 @@ static int check_idq(struct dquot *dquot
3443            (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
3444             dquot->dq_dqb.dqb_itime == 0) {
3445                 *warntype = ISOFTWARN;
3446 -               dquot->dq_dqb.dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
3447 +               dquot->dq_dqb.dqb_itime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_igrace;
3448         }
3449  
3450         return QUOTA_OK;
3451 @@ -946,7 +957,7 @@ static int check_bdq(struct dquot *dquot
3452             dquot->dq_dqb.dqb_btime == 0) {
3453                 if (!prealloc) {
3454                         *warntype = BSOFTWARN;
3455 -                       dquot->dq_dqb.dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
3456 +                       dquot->dq_dqb.dqb_btime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_bgrace;
3457                 }
3458                 else
3459                         /*
3460 @@ -972,7 +983,7 @@ int dquot_initialize(struct inode *inode
3461           * re-enter the quota code and are already holding the mutex */
3462         if (IS_NOQUOTA(inode))
3463                 return 0;
3464 -       down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3465 +       down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3466         /* Having dqptr_sem we know NOQUOTA flags can't be altered... */
3467         if (IS_NOQUOTA(inode))
3468                 goto out_err;
3469 @@ -988,11 +999,11 @@ int dquot_initialize(struct inode *inode
3470                                         id = inode->i_gid;
3471                                         break;
3472                         }
3473 -                       inode->i_dquot[cnt] = dqget(inode->i_sb, id, cnt);
3474 +                       inode->i_dquot[cnt] = dqget(inode->i_dqh, id, cnt);
3475                 }
3476         }
3477  out_err:
3478 -       up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3479 +       up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3480         return ret;
3481  }
3482  
3483 @@ -1004,14 +1015,14 @@ int dquot_drop(struct inode *inode)
3484  {
3485         int cnt;
3486  
3487 -       down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3488 +       down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3489         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
3490                 if (inode->i_dquot[cnt] != NODQUOT) {
3491                         dqput(inode->i_dquot[cnt]);
3492                         inode->i_dquot[cnt] = NODQUOT;
3493                 }
3494         }
3495 -       up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3496 +       up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3497         return 0;
3498  }
3499  
3500 @@ -1042,9 +1053,9 @@ out_add:
3501         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3502                 warntype[cnt] = NOWARN;
3503  
3504 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3505 +       down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3506         if (IS_NOQUOTA(inode)) {        /* Now we can do reliable test... */
3507 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3508 +               up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3509                 goto out_add;
3510         }
3511         spin_lock(&dq_data_lock);
3512 @@ -1069,7 +1080,7 @@ warn_put_all:
3513                         if (inode->i_dquot[cnt])
3514                                 mark_dquot_dirty(inode->i_dquot[cnt]);
3515         flush_warnings(inode->i_dquot, warntype);
3516 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3517 +       up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3518         return ret;
3519  }
3520  
3521 @@ -1087,9 +1098,9 @@ int dquot_alloc_inode(const struct inode
3522                 return QUOTA_OK;
3523         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3524                 warntype[cnt] = NOWARN;
3525 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3526 +       down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3527         if (IS_NOQUOTA(inode)) {
3528 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3529 +               up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3530                 return QUOTA_OK;
3531         }
3532         spin_lock(&dq_data_lock);
3533 @@ -1114,7 +1125,7 @@ warn_put_all:
3534                         if (inode->i_dquot[cnt])
3535                                 mark_dquot_dirty(inode->i_dquot[cnt]);
3536         flush_warnings((struct dquot **)inode->i_dquot, warntype);
3537 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3538 +       up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3539         return ret;
3540  }
3541  
3542 @@ -1132,10 +1143,10 @@ out_sub:
3543                 inode_sub_bytes(inode, number);
3544                 return QUOTA_OK;
3545         }
3546 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3547 +       down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3548         /* Now recheck reliably when holding dqptr_sem */
3549         if (IS_NOQUOTA(inode)) {
3550 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3551 +               up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3552                 goto out_sub;
3553         }
3554         spin_lock(&dq_data_lock);
3555 @@ -1150,7 +1161,7 @@ out_sub:
3556         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3557                 if (inode->i_dquot[cnt])
3558                         mark_dquot_dirty(inode->i_dquot[cnt]);
3559 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3560 +       up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3561         return QUOTA_OK;
3562  }
3563  
3564 @@ -1165,10 +1176,10 @@ int dquot_free_inode(const struct inode 
3565           * re-enter the quota code and are already holding the mutex */
3566         if (IS_NOQUOTA(inode))
3567                 return QUOTA_OK;
3568 -       down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3569 +       down_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3570         /* Now recheck reliably when holding dqptr_sem */
3571         if (IS_NOQUOTA(inode)) {
3572 -               up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3573 +               up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3574                 return QUOTA_OK;
3575         }
3576         spin_lock(&dq_data_lock);
3577 @@ -1182,7 +1193,7 @@ int dquot_free_inode(const struct inode 
3578         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
3579                 if (inode->i_dquot[cnt])
3580                         mark_dquot_dirty(inode->i_dquot[cnt]);
3581 -       up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
3582 +       up_read(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3583         return QUOTA_OK;
3584  }
3585  
3586 @@ -1197,6 +1208,7 @@ int dquot_transfer(struct inode *inode, 
3587         qsize_t space;
3588         struct dquot *transfer_from[MAXQUOTAS];
3589         struct dquot *transfer_to[MAXQUOTAS];
3590 +       struct dqhash *dqh = inode->i_sb->s_dqh;
3591         int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid,
3592             chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid;
3593         char warntype[MAXQUOTAS];
3594 @@ -1210,10 +1222,10 @@ int dquot_transfer(struct inode *inode, 
3595                 transfer_to[cnt] = transfer_from[cnt] = NODQUOT;
3596                 warntype[cnt] = NOWARN;
3597         }
3598 -       down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3599 +       down_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3600         /* Now recheck reliably when holding dqptr_sem */
3601         if (IS_NOQUOTA(inode)) {        /* File without quota accounting? */
3602 -               up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3603 +               up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3604                 return QUOTA_OK;
3605         }
3606         /* First build the transfer_to list - here we can block on
3607 @@ -1224,12 +1236,12 @@ int dquot_transfer(struct inode *inode, 
3608                         case USRQUOTA:
3609                                 if (!chuid)
3610                                         continue;
3611 -                               transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
3612 +                               transfer_to[cnt] = dqget(dqh, iattr->ia_uid, cnt);
3613                                 break;
3614                         case GRPQUOTA:
3615                                 if (!chgid)
3616                                         continue;
3617 -                               transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
3618 +                               transfer_to[cnt] = dqget(dqh, iattr->ia_gid, cnt);
3619                                 break;
3620                 }
3621         }
3622 @@ -1284,20 +1296,20 @@ warn_put_all:
3623                 if (ret == NO_QUOTA && transfer_to[cnt] != NODQUOT)
3624                         dqput(transfer_to[cnt]);
3625         }
3626 -       up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
3627 +       up_write(&dqh_dqopt(inode->i_dqh)->dqptr_sem);
3628         return ret;
3629  }
3630  
3631  /*
3632   * Write info of quota file to disk
3633   */
3634 -int dquot_commit_info(struct super_block *sb, int type)
3635 +int dquot_commit_info(struct dqhash *hash, int type)
3636  {
3637         int ret;
3638 -       struct quota_info *dqopt = sb_dqopt(sb);
3639 +       struct quota_info *dqopt = dqh_dqopt(hash);
3640  
3641         mutex_lock(&dqopt->dqio_mutex);
3642 -       ret = dqopt->ops[type]->write_file_info(sb, type);
3643 +       ret = dqopt->ops[type]->write_file_info(hash, type);
3644         mutex_unlock(&dqopt->dqio_mutex);
3645         return ret;
3646  }
3647 @@ -1347,10 +1359,10 @@ static inline void reset_enable_flags(st
3648  /*
3649   * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
3650   */
3651 -int vfs_quota_off(struct super_block *sb, int type)
3652 +int vfs_quota_off(struct dqhash *hash, int type)
3653  {
3654         int cnt;
3655 -       struct quota_info *dqopt = sb_dqopt(sb);
3656 +       struct quota_info *dqopt = dqh_dqopt(hash);
3657         struct inode *toputinode[MAXQUOTAS];
3658  
3659         /* We need to serialize quota_off() for device */
3660 @@ -1359,21 +1371,21 @@ int vfs_quota_off(struct super_block *sb
3661                 toputinode[cnt] = NULL;
3662                 if (type != -1 && cnt != type)
3663                         continue;
3664 -               if (!sb_has_quota_enabled(sb, cnt))
3665 +               if (!dqh_has_quota_enabled(hash, cnt))
3666                         continue;
3667                 reset_enable_flags(dqopt, cnt);
3668  
3669                 /* Note: these are blocking operations */
3670 -               drop_dquot_ref(sb, cnt);
3671 -               invalidate_dquots(sb, cnt);
3672 +               drop_dquot_ref(hash, cnt);
3673 +               invalidate_dquots(hash, cnt);
3674                 /*
3675                  * Now all dquots should be invalidated, all writes done so we should be only
3676                  * users of the info. No locks needed.
3677                  */
3678                 if (info_dirty(&dqopt->info[cnt]))
3679 -                       sb->dq_op->write_info(sb, cnt);
3680 +                       hash->dqh_qop->write_info(hash, cnt);
3681                 if (dqopt->ops[cnt]->free_file_info)
3682 -                       dqopt->ops[cnt]->free_file_info(sb, cnt);
3683 +                       dqopt->ops[cnt]->free_file_info(hash, cnt);
3684                 put_quota_format(dqopt->info[cnt].dqi_format);
3685  
3686                 toputinode[cnt] = dqopt->files[cnt];
3687 @@ -1386,9 +1398,9 @@ int vfs_quota_off(struct super_block *sb
3688         mutex_unlock(&dqopt->dqonoff_mutex);
3689         /* Sync the superblock so that buffers with quota data are written to
3690          * disk (and so userspace sees correct data afterwards). */
3691 -       if (sb->s_op->sync_fs)
3692 -               sb->s_op->sync_fs(sb, 1);
3693 -       sync_blockdev(sb->s_bdev);
3694 +       if (hash->dqh_sb->s_op->sync_fs)
3695 +               hash->dqh_sb->s_op->sync_fs(hash->dqh_sb, 1);
3696 +       sync_blockdev(hash->dqh_sb->s_bdev);
3697         /* Now the quota files are just ordinary files and we can set the
3698          * inode flags back. Moreover we discard the pagecache so that
3699          * userspace sees the writes we did bypassing the pagecache. We
3700 @@ -1399,7 +1411,7 @@ int vfs_quota_off(struct super_block *sb
3701                         mutex_lock(&dqopt->dqonoff_mutex);
3702                         /* If quota was reenabled in the meantime, we have
3703                          * nothing to do */
3704 -                       if (!sb_has_quota_enabled(sb, cnt)) {
3705 +                       if (!dqh_has_quota_enabled(hash, cnt)) {
3706                                 mutex_lock(&toputinode[cnt]->i_mutex);
3707                                 toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
3708                                   S_NOATIME | S_NOQUOTA);
3709 @@ -1410,8 +1422,8 @@ int vfs_quota_off(struct super_block *sb
3710                         }
3711                         mutex_unlock(&dqopt->dqonoff_mutex);
3712                 }
3713 -       if (sb->s_bdev)
3714 -               invalidate_bdev(sb->s_bdev, 0);
3715 +       if (hash->dqh_sb->s_bdev)
3716 +               invalidate_bdev(hash->dqh_sb->s_bdev, 0);
3717         return 0;
3718  }
3719  
3720 @@ -1424,7 +1436,8 @@ static int vfs_quota_on_inode(struct ino
3721  {
3722         struct quota_format_type *fmt = find_quota_format(format_id);
3723         struct super_block *sb = inode->i_sb;
3724 -       struct quota_info *dqopt = sb_dqopt(sb);
3725 +       struct dqhash *hash = inode->i_dqh;
3726 +       struct quota_info *dqopt = dqh_dqopt(hash);
3727         int error;
3728         int oldflags = -1;
3729  
3730 @@ -1450,7 +1463,7 @@ static int vfs_quota_on_inode(struct ino
3731         invalidate_bdev(sb->s_bdev, 0);
3732         mutex_lock(&inode->i_mutex);
3733         mutex_lock(&dqopt->dqonoff_mutex);
3734 -       if (sb_has_quota_enabled(sb, type)) {
3735 +       if (dqh_has_quota_enabled(hash, type)) {
3736                 error = -EBUSY;
3737                 goto out_lock;
3738         }
3739 @@ -1461,21 +1474,21 @@ static int vfs_quota_on_inode(struct ino
3740         oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA);
3741         inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
3742         up_write(&dqopt->dqptr_sem);
3743 -       sb->dq_op->drop(inode);
3744 +       hash->dqh_qop->drop(inode);
3745  
3746         error = -EIO;
3747         dqopt->files[type] = igrab(inode);
3748         if (!dqopt->files[type])
3749                 goto out_lock;
3750         error = -EINVAL;
3751 -       if (!fmt->qf_ops->check_quota_file(sb, type))
3752 +       if (!fmt->qf_ops->check_quota_file(hash, type))
3753                 goto out_file_init;
3754  
3755         dqopt->ops[type] = fmt->qf_ops;
3756         dqopt->info[type].dqi_format = fmt;
3757         INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
3758         mutex_lock(&dqopt->dqio_mutex);
3759 -       if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) {
3760 +       if ((error = dqopt->ops[type]->read_file_info(hash, type)) < 0) {
3761                 mutex_unlock(&dqopt->dqio_mutex);
3762                 goto out_file_init;
3763         }
3764 @@ -1483,7 +1496,7 @@ static int vfs_quota_on_inode(struct ino
3765         mutex_unlock(&inode->i_mutex);
3766         set_enable_flags(dqopt, type);
3767  
3768 -       add_dquot_ref(sb, type);
3769 +       add_dquot_ref(hash, type);
3770         mutex_unlock(&dqopt->dqonoff_mutex);
3771  
3772         return 0;
3773 @@ -1509,7 +1522,7 @@ out_fmt:
3774  }
3775  
3776  /* Actual function called from quotactl() */
3777 -int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
3778 +int vfs_quota_on(struct dqhash *hash, int type, int format_id, char *path)
3779  {
3780         struct nameidata nd;
3781         int error;
3782 @@ -1521,7 +1534,7 @@ int vfs_quota_on(struct super_block *sb,
3783         if (error)
3784                 goto out_path;
3785         /* Quota file not on the same filesystem? */
3786 -       if (nd.mnt->mnt_sb != sb)
3787 +       if (nd.mnt->mnt_sb != hash->dqh_sb)
3788                 error = -EXDEV;
3789         else
3790                 error = vfs_quota_on_inode(nd.dentry->d_inode, type, format_id);
3791 @@ -1534,13 +1547,13 @@ out_path:
3792   * This function is used when filesystem needs to initialize quotas
3793   * during mount time.
3794   */
3795 -int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
3796 +int vfs_quota_on_mount(struct dqhash *hash, char *qf_name,
3797                 int format_id, int type)
3798  {
3799         struct dentry *dentry;
3800         int error;
3801  
3802 -       dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name));
3803 +       dentry = lookup_one_len(qf_name, hash->dqh_sb->s_root, strlen(qf_name));
3804         if (IS_ERR(dentry))
3805                 return PTR_ERR(dentry);
3806  
3807 @@ -1576,18 +1589,18 @@ static void do_get_dqblk(struct dquot *d
3808         spin_unlock(&dq_data_lock);
3809  }
3810  
3811 -int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
3812 +int vfs_get_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di)
3813  {
3814         struct dquot *dquot;
3815  
3816 -       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
3817 -       if (!(dquot = dqget(sb, id, type))) {
3818 -               mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3819 +       mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
3820 +       if (!(dquot = dqget(hash, id, type))) {
3821 +               mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3822                 return -ESRCH;
3823         }
3824         do_get_dqblk(dquot, di);
3825         dqput(dquot);
3826 -       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3827 +       mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3828         return 0;
3829  }
3830  
3831 @@ -1627,7 +1640,7 @@ static void do_set_dqblk(struct dquot *d
3832                         clear_bit(DQ_BLKS_B, &dquot->dq_flags);
3833                 }
3834                 else if (!(di->dqb_valid & QIF_BTIME))  /* Set grace only if user hasn't provided his own... */
3835 -                       dm->dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
3836 +                       dm->dqb_btime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_bgrace;
3837         }
3838         if (check_ilim) {
3839                 if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) {
3840 @@ -1635,7 +1648,7 @@ static void do_set_dqblk(struct dquot *d
3841                         clear_bit(DQ_INODES_B, &dquot->dq_flags);
3842                 }
3843                 else if (!(di->dqb_valid & QIF_ITIME))  /* Set grace only if user hasn't provided his own... */
3844 -                       dm->dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
3845 +                       dm->dqb_itime = get_seconds() + dqh_dqopt(dquot->dq_dqh)->info[dquot->dq_type].dqi_igrace;
3846         }
3847         if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit)
3848                 clear_bit(DQ_FAKE_B, &dquot->dq_flags);
3849 @@ -1645,53 +1658,53 @@ static void do_set_dqblk(struct dquot *d
3850         mark_dquot_dirty(dquot);
3851  }
3852  
3853 -int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
3854 +int vfs_set_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di)
3855  {
3856         struct dquot *dquot;
3857  
3858 -       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
3859 -       if (!(dquot = dqget(sb, id, type))) {
3860 -               mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3861 +       mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
3862 +       if (!(dquot = dqget(hash, id, type))) {
3863 +               mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3864                 return -ESRCH;
3865         }
3866         do_set_dqblk(dquot, di);
3867         dqput(dquot);
3868 -       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3869 +       mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3870         return 0;
3871  }
3872  
3873  /* Generic routine for getting common part of quota file information */
3874 -int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
3875 +int vfs_get_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii)
3876  {
3877         struct mem_dqinfo *mi;
3878    
3879 -       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
3880 -       if (!sb_has_quota_enabled(sb, type)) {
3881 -               mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3882 +       mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
3883 +       if (!dqh_has_quota_enabled(hash, type)) {
3884 +               mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3885                 return -ESRCH;
3886         }
3887 -       mi = sb_dqopt(sb)->info + type;
3888 +       mi = dqh_dqopt(hash)->info + type;
3889         spin_lock(&dq_data_lock);
3890         ii->dqi_bgrace = mi->dqi_bgrace;
3891         ii->dqi_igrace = mi->dqi_igrace;
3892         ii->dqi_flags = mi->dqi_flags & DQF_MASK;
3893         ii->dqi_valid = IIF_ALL;
3894         spin_unlock(&dq_data_lock);
3895 -       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3896 +       mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3897         return 0;
3898  }
3899  
3900  /* Generic routine for setting common part of quota file information */
3901 -int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
3902 +int vfs_set_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii)
3903  {
3904         struct mem_dqinfo *mi;
3905  
3906 -       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
3907 -       if (!sb_has_quota_enabled(sb, type)) {
3908 -               mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3909 +       mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
3910 +       if (!dqh_has_quota_enabled(hash, type)) {
3911 +               mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3912                 return -ESRCH;
3913         }
3914 -       mi = sb_dqopt(sb)->info + type;
3915 +       mi = dqh_dqopt(hash)->info + type;
3916         spin_lock(&dq_data_lock);
3917         if (ii->dqi_valid & IIF_BGRACE)
3918                 mi->dqi_bgrace = ii->dqi_bgrace;
3919 @@ -1700,10 +1713,10 @@ int vfs_set_dqinfo(struct super_block *s
3920         if (ii->dqi_valid & IIF_FLAGS)
3921                 mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK);
3922         spin_unlock(&dq_data_lock);
3923 -       mark_info_dirty(sb, type);
3924 +       mark_info_dirty(hash, type);
3925         /* Force write to disk */
3926 -       sb->dq_op->write_info(sb, type);
3927 -       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
3928 +       hash->dqh_qop->write_info(hash, type);
3929 +       mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
3930         return 0;
3931  }
3932  
3933 diff -NurpP --minimal linux-2.6.19.1/fs/exec.c linux-2.6.19.1-vs2.3.0.6/fs/exec.c
3934 --- linux-2.6.19.1/fs/exec.c    2006-12-13 07:46:36 +0100
3935 +++ linux-2.6.19.1-vs2.3.0.6/fs/exec.c  2006-12-13 09:16:31 +0100
3936 @@ -49,6 +49,7 @@
3937  #include <linux/tsacct_kern.h>
3938  #include <linux/cn_proc.h>
3939  #include <linux/audit.h>
3940 +#include <linux/vs_memory.h>
3941  
3942  #include <asm/uaccess.h>
3943  #include <asm/mmu_context.h>
3944 @@ -436,7 +437,8 @@ int setup_arg_pages(struct linux_binprm 
3945                         kmem_cache_free(vm_area_cachep, mpnt);
3946                         return ret;
3947                 }
3948 -               mm->stack_vm = mm->total_vm = vma_pages(mpnt);
3949 +               vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
3950 +               mm->stack_vm = mm->total_vm;
3951         }
3952  
3953         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
3954 @@ -1306,7 +1308,7 @@ static void format_corename(char *corena
3955                         /* UNIX time of coredump */
3956                         case 't': {
3957                                 struct timeval tv;
3958 -                               do_gettimeofday(&tv);
3959 +                               vx_gettimeofday(&tv);
3960                                 rc = snprintf(out_ptr, out_end - out_ptr,
3961                                               "%lu", tv.tv_sec);
3962                                 if (rc > out_end - out_ptr)
3963 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/balloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/balloc.c
3964 --- linux-2.6.19.1/fs/ext2/balloc.c     2006-09-20 16:58:34 +0200
3965 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/balloc.c   2006-12-01 23:38:46 +0100
3966 @@ -16,6 +16,8 @@
3967  #include <linux/sched.h>
3968  #include <linux/buffer_head.h>
3969  #include <linux/capability.h>
3970 +#include <linux/vs_dlimit.h>
3971 +#include <linux/vs_tag.h>
3972  
3973  /*
3974   * balloc.c contains the blocks allocation and deallocation routines
3975 @@ -102,12 +104,13 @@ static int reserve_blocks(struct super_b
3976  {
3977         struct ext2_sb_info *sbi = EXT2_SB(sb);
3978         struct ext2_super_block *es = sbi->s_es;
3979 -       unsigned free_blocks;
3980 -       unsigned root_blocks;
3981 +       unsigned long long free_blocks, root_blocks;
3982  
3983         free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
3984         root_blocks = le32_to_cpu(es->s_r_blocks_count);
3985  
3986 +       DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
3987 +
3988         if (free_blocks < count)
3989                 count = free_blocks;
3990  
3991 @@ -258,6 +261,7 @@ do_more:
3992         }
3993  error_return:
3994         brelse(bitmap_bh);
3995 +       DLIMIT_FREE_BLOCK(inode, freed);
3996         release_blocks(sb, freed);
3997         DQUOT_FREE_BLOCK(inode, freed);
3998  }
3999 @@ -361,6 +365,10 @@ int ext2_new_block(struct inode *inode, 
4000                 *err = -ENOSPC;
4001                 goto out_dquot;
4002         }
4003 +       if (DLIMIT_ALLOC_BLOCK(inode, es_alloc)) {
4004 +               *err = -ENOSPC;
4005 +               goto out_dlimit;
4006 +       }
4007  
4008         ext2_debug ("goal=%lu.\n", goal);
4009  
4010 @@ -508,6 +516,8 @@ got_block:
4011         *err = 0;
4012  out_release:
4013         group_release_blocks(sb, group_no, desc, gdp_bh, group_alloc);
4014 +       DLIMIT_FREE_BLOCK(inode, es_alloc);
4015 +out_dlimit:
4016         release_blocks(sb, es_alloc);
4017  out_dquot:
4018         DQUOT_FREE_BLOCK(inode, dq_alloc);
4019 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/ext2.h linux-2.6.19.1-vs2.3.0.6/fs/ext2/ext2.h
4020 --- linux-2.6.19.1/fs/ext2/ext2.h       2006-11-30 21:19:19 +0100
4021 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/ext2.h     2006-11-08 04:57:46 +0100
4022 @@ -166,6 +166,7 @@ extern const struct file_operations ext2
4023  extern const struct address_space_operations ext2_aops;
4024  extern const struct address_space_operations ext2_aops_xip;
4025  extern const struct address_space_operations ext2_nobh_aops;
4026 +extern int ext2_sync_flags(struct inode *inode);
4027  
4028  /* namei.c */
4029  extern struct inode_operations ext2_dir_inode_operations;
4030 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/file.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/file.c
4031 --- linux-2.6.19.1/fs/ext2/file.c       2006-11-30 21:19:19 +0100
4032 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/file.c     2006-11-08 04:57:51 +0100
4033 @@ -54,6 +54,7 @@ const struct file_operations ext2_file_o
4034         .release        = ext2_release_file,
4035         .fsync          = ext2_sync_file,
4036         .sendfile       = generic_file_sendfile,
4037 +       .sendpage       = generic_file_sendpage,
4038         .splice_read    = generic_file_splice_read,
4039         .splice_write   = generic_file_splice_write,
4040  };
4041 @@ -85,4 +86,5 @@ struct inode_operations ext2_file_inode_
4042  #endif
4043         .setattr        = ext2_setattr,
4044         .permission     = ext2_permission,
4045 +       .sync_flags     = ext2_sync_flags,
4046  };
4047 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/ialloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/ialloc.c
4048 --- linux-2.6.19.1/fs/ext2/ialloc.c     2006-11-30 21:19:19 +0100
4049 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/ialloc.c   2006-11-08 04:57:50 +0100
4050 @@ -17,6 +17,8 @@
4051  #include <linux/backing-dev.h>
4052  #include <linux/buffer_head.h>
4053  #include <linux/random.h>
4054 +#include <linux/vs_dlimit.h>
4055 +#include <linux/vs_tag.h>
4056  #include "ext2.h"
4057  #include "xattr.h"
4058  #include "acl.h"
4059 @@ -125,6 +127,7 @@ void ext2_free_inode (struct inode * ino
4060                 ext2_xattr_delete_inode(inode);
4061                 DQUOT_FREE_INODE(inode);
4062                 DQUOT_DROP(inode);
4063 +               DLIMIT_FREE_INODE(inode);
4064         }
4065  
4066         es = EXT2_SB(sb)->s_es;
4067 @@ -464,6 +467,11 @@ struct inode *ext2_new_inode(struct inod
4068         if (!inode)
4069                 return ERR_PTR(-ENOMEM);
4070  
4071 +       inode->i_tag = dx_current_fstag(sb);
4072 +       if (DLIMIT_ALLOC_INODE(inode)) {
4073 +               err = -ENOSPC;
4074 +               goto fail_dlim;
4075 +       }
4076         ei = EXT2_I(inode);
4077         sbi = EXT2_SB(sb);
4078         es = sbi->s_es;
4079 @@ -577,7 +585,8 @@ got:
4080         inode->i_blocks = 0;
4081         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
4082         memset(ei->i_data, 0, sizeof(ei->i_data));
4083 -       ei->i_flags = EXT2_I(dir)->i_flags & ~EXT2_BTREE_FL;
4084 +       ei->i_flags = EXT2_I(dir)->i_flags &
4085 +               ~(EXT2_BTREE_FL|EXT2_IUNLINK_FL|EXT2_BARRIER_FL);
4086         if (S_ISLNK(mode))
4087                 ei->i_flags &= ~(EXT2_IMMUTABLE_FL|EXT2_APPEND_FL);
4088         /* dirsync is only applied to directories */
4089 @@ -625,12 +634,15 @@ fail_free_drop:
4090  
4091  fail_drop:
4092         DQUOT_DROP(inode);
4093 +       DLIMIT_FREE_INODE(inode);
4094         inode->i_flags |= S_NOQUOTA;
4095         inode->i_nlink = 0;
4096         iput(inode);
4097         return ERR_PTR(err);
4098  
4099  fail:
4100 +       DLIMIT_FREE_INODE(inode);
4101 +fail_dlim:
4102         make_bad_inode(inode);
4103         iput(inode);
4104         return ERR_PTR(err);
4105 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/inode.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/inode.c
4106 --- linux-2.6.19.1/fs/ext2/inode.c      2006-11-30 21:19:19 +0100
4107 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/inode.c    2006-11-30 18:53:18 +0100
4108 @@ -31,6 +31,7 @@
4109  #include <linux/writeback.h>
4110  #include <linux/buffer_head.h>
4111  #include <linux/mpage.h>
4112 +#include <linux/vs_tag.h>
4113  #include "ext2.h"
4114  #include "acl.h"
4115  #include "xip.h"
4116 @@ -913,7 +914,7 @@ void ext2_truncate (struct inode * inode
4117                 return;
4118         if (ext2_inode_is_fast_symlink(inode))
4119                 return;
4120 -       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
4121 +       if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
4122                 return;
4123  
4124         ext2_discard_prealloc(inode);
4125 @@ -1042,25 +1043,70 @@ void ext2_set_inode_flags(struct inode *
4126  {
4127         unsigned int flags = EXT2_I(inode)->i_flags;
4128  
4129 -       inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
4130 +       inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
4131 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
4132 +
4133 +       if (flags & EXT2_IMMUTABLE_FL)
4134 +               inode->i_flags |= S_IMMUTABLE;
4135 +       if (flags & EXT2_IUNLINK_FL)
4136 +               inode->i_flags |= S_IUNLINK;
4137 +       if (flags & EXT2_BARRIER_FL)
4138 +               inode->i_flags |= S_BARRIER;
4139 +
4140         if (flags & EXT2_SYNC_FL)
4141                 inode->i_flags |= S_SYNC;
4142         if (flags & EXT2_APPEND_FL)
4143                 inode->i_flags |= S_APPEND;
4144 -       if (flags & EXT2_IMMUTABLE_FL)
4145 -               inode->i_flags |= S_IMMUTABLE;
4146         if (flags & EXT2_NOATIME_FL)
4147                 inode->i_flags |= S_NOATIME;
4148         if (flags & EXT2_DIRSYNC_FL)
4149                 inode->i_flags |= S_DIRSYNC;
4150  }
4151  
4152 +int ext2_sync_flags(struct inode *inode)
4153 +{
4154 +       unsigned int oldflags, newflags;
4155 +
4156 +       oldflags = EXT2_I(inode)->i_flags;
4157 +       newflags = oldflags & ~(EXT2_APPEND_FL |
4158 +               EXT2_IMMUTABLE_FL | EXT2_IUNLINK_FL |
4159 +               EXT2_BARRIER_FL | EXT2_NOATIME_FL |
4160 +               EXT2_SYNC_FL | EXT2_DIRSYNC_FL);
4161 +
4162 +       if (IS_APPEND(inode))
4163 +               newflags |= EXT2_APPEND_FL;
4164 +       if (IS_IMMUTABLE(inode))
4165 +               newflags |= EXT2_IMMUTABLE_FL;
4166 +       if (IS_IUNLINK(inode))
4167 +               newflags |= EXT2_IUNLINK_FL;
4168 +       if (IS_BARRIER(inode))
4169 +               newflags |= EXT2_BARRIER_FL;
4170 +
4171 +       /* we do not want to copy superblock flags */
4172 +       if (inode->i_flags & S_NOATIME)
4173 +               newflags |= EXT2_NOATIME_FL;
4174 +       if (inode->i_flags & S_SYNC)
4175 +               newflags |= EXT2_SYNC_FL;
4176 +       if (inode->i_flags & S_DIRSYNC)
4177 +               newflags |= EXT2_DIRSYNC_FL;
4178 +
4179 +       if (oldflags ^ newflags) {
4180 +               EXT2_I(inode)->i_flags = newflags;
4181 +               inode->i_ctime = CURRENT_TIME;
4182 +               mark_inode_dirty(inode);
4183 +       }
4184 +
4185 +       return 0;
4186 +}
4187 +
4188  void ext2_read_inode (struct inode * inode)
4189  {
4190         struct ext2_inode_info *ei = EXT2_I(inode);
4191         ino_t ino = inode->i_ino;
4192         struct buffer_head * bh;
4193         struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
4194 +       uid_t uid;
4195 +       gid_t gid;
4196         int n;
4197  
4198  #ifdef CONFIG_EXT2_FS_POSIX_ACL
4199 @@ -1071,12 +1117,17 @@ void ext2_read_inode (struct inode * ino
4200                 goto bad_inode;
4201  
4202         inode->i_mode = le16_to_cpu(raw_inode->i_mode);
4203 -       inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4204 -       inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4205 +       uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4206 +       gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4207         if (!(test_opt (inode->i_sb, NO_UID32))) {
4208 -               inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
4209 -               inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
4210 +               uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
4211 +               gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
4212         }
4213 +       inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
4214 +       inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
4215 +       inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
4216 +               le16_to_cpu(raw_inode->i_raw_tag));
4217 +
4218         inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
4219         inode->i_size = le32_to_cpu(raw_inode->i_size);
4220         inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
4221 @@ -1173,8 +1224,8 @@ static int ext2_update_inode(struct inod
4222         struct ext2_inode_info *ei = EXT2_I(inode);
4223         struct super_block *sb = inode->i_sb;
4224         ino_t ino = inode->i_ino;
4225 -       uid_t uid = inode->i_uid;
4226 -       gid_t gid = inode->i_gid;
4227 +       uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
4228 +       gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
4229         struct buffer_head * bh;
4230         struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
4231         int n;
4232 @@ -1209,6 +1260,9 @@ static int ext2_update_inode(struct inod
4233                 raw_inode->i_uid_high = 0;
4234                 raw_inode->i_gid_high = 0;
4235         }
4236 +#ifdef CONFIG_TAGGING_INTERN
4237 +       raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
4238 +#endif
4239         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
4240         raw_inode->i_size = cpu_to_le32(inode->i_size);
4241         raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
4242 @@ -1295,7 +1349,8 @@ int ext2_setattr(struct dentry *dentry, 
4243         if (error)
4244                 return error;
4245         if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
4246 -           (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
4247 +           (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) ||
4248 +           (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) {
4249                 error = DQUOT_TRANSFER(inode, iattr) ? -EDQUOT : 0;
4250                 if (error)
4251                         return error;
4252 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/ioctl.c
4253 --- linux-2.6.19.1/fs/ext2/ioctl.c      2006-11-30 21:19:19 +0100
4254 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/ioctl.c    2006-11-08 04:57:52 +0100
4255 @@ -13,6 +13,7 @@
4256  #include <linux/sched.h>
4257  #include <linux/compat.h>
4258  #include <linux/smp_lock.h>
4259 +#include <linux/mount.h>
4260  #include <asm/current.h>
4261  #include <asm/uaccess.h>
4262  
4263 @@ -32,7 +33,8 @@ int ext2_ioctl (struct inode * inode, st
4264         case EXT2_IOC_SETFLAGS: {
4265                 unsigned int oldflags;
4266  
4267 -               if (IS_RDONLY(inode))
4268 +               if (IS_RDONLY(inode) ||
4269 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4270                         return -EROFS;
4271  
4272                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4273 @@ -52,7 +54,9 @@ int ext2_ioctl (struct inode * inode, st
4274                  *
4275                  * This test looks nicer. Thanks to Pauline Middelink
4276                  */
4277 -               if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) {
4278 +               if ((oldflags & EXT2_IMMUTABLE_FL) ||
4279 +                       ((flags ^ oldflags) & (EXT2_APPEND_FL |
4280 +                       EXT2_IMMUTABLE_FL | EXT2_IUNLINK_FL))) {
4281                         if (!capable(CAP_LINUX_IMMUTABLE))
4282                                 return -EPERM;
4283                 }
4284 @@ -71,7 +75,8 @@ int ext2_ioctl (struct inode * inode, st
4285         case EXT2_IOC_SETVERSION:
4286                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4287                         return -EPERM;
4288 -               if (IS_RDONLY(inode))
4289 +               if (IS_RDONLY(inode) ||
4290 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4291                         return -EROFS;
4292                 if (get_user(inode->i_generation, (int __user *) arg))
4293                         return -EFAULT; 
4294 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/namei.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/namei.c
4295 --- linux-2.6.19.1/fs/ext2/namei.c      2006-11-30 21:19:19 +0100
4296 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/namei.c    2006-11-30 18:53:18 +0100
4297 @@ -31,6 +31,7 @@
4298   */
4299  
4300  #include <linux/pagemap.h>
4301 +#include <linux/vs_tag.h>
4302  #include "ext2.h"
4303  #include "xattr.h"
4304  #include "acl.h"
4305 @@ -66,6 +67,7 @@ static struct dentry *ext2_lookup(struct
4306                 inode = iget(dir->i_sb, ino);
4307                 if (!inode)
4308                         return ERR_PTR(-EACCES);
4309 +               dx_propagate_tag(nd, inode);
4310         }
4311         return d_splice_alias(inode, dentry);
4312  }
4313 @@ -391,6 +393,7 @@ struct inode_operations ext2_dir_inode_o
4314  #endif
4315         .setattr        = ext2_setattr,
4316         .permission     = ext2_permission,
4317 +       .sync_flags     = ext2_sync_flags,
4318  };
4319  
4320  struct inode_operations ext2_special_inode_operations = {
4321 @@ -402,4 +405,5 @@ struct inode_operations ext2_special_ino
4322  #endif
4323         .setattr        = ext2_setattr,
4324         .permission     = ext2_permission,
4325 +       .sync_flags     = ext2_sync_flags,
4326  };
4327 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/super.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/super.c
4328 --- linux-2.6.19.1/fs/ext2/super.c      2006-11-30 21:19:19 +0100
4329 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/super.c    2006-11-08 04:57:51 +0100
4330 @@ -227,8 +227,8 @@ static int ext2_show_options(struct seq_
4331  }
4332  
4333  #ifdef CONFIG_QUOTA
4334 -static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off);
4335 -static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off);
4336 +static ssize_t ext2_quota_read(struct dqhash *hash, int type, char *data, size_t len, loff_t off);
4337 +static ssize_t ext2_quota_write(struct dqhash *hash, int type, const char *data, size_t len, loff_t off);
4338  #endif
4339  
4340  static struct super_operations ext2_sops = {
4341 @@ -324,7 +324,7 @@ enum {
4342         Opt_err_ro, Opt_nouid32, Opt_nocheck, Opt_debug,
4343         Opt_oldalloc, Opt_orlov, Opt_nobh, Opt_user_xattr, Opt_nouser_xattr,
4344         Opt_acl, Opt_noacl, Opt_xip, Opt_ignore, Opt_err, Opt_quota,
4345 -       Opt_usrquota, Opt_grpquota
4346 +       Opt_usrquota, Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid
4347  };
4348  
4349  static match_table_t tokens = {
4350 @@ -352,6 +352,10 @@ static match_table_t tokens = {
4351         {Opt_acl, "acl"},
4352         {Opt_noacl, "noacl"},
4353         {Opt_xip, "xip"},
4354 +       {Opt_tag, "tag"},
4355 +       {Opt_notag, "notag"},
4356 +       {Opt_tagid, "tagid=%u"},
4357 +       {Opt_tag, "tagxid"},
4358         {Opt_grpquota, "grpquota"},
4359         {Opt_ignore, "noquota"},
4360         {Opt_quota, "quota"},
4361 @@ -420,6 +424,20 @@ static int parse_options (char * options
4362                 case Opt_nouid32:
4363                         set_opt (sbi->s_mount_opt, NO_UID32);
4364                         break;
4365 +#ifndef CONFIG_TAGGING_NONE
4366 +               case Opt_tag:
4367 +                       set_opt (sbi->s_mount_opt, TAGGED);
4368 +                       break;
4369 +               case Opt_notag:
4370 +                       clear_opt (sbi->s_mount_opt, TAGGED);
4371 +                       break;
4372 +#endif
4373 +#ifdef CONFIG_PROPAGATE
4374 +               case Opt_tagid:
4375 +                       /* use args[0] */
4376 +                       set_opt (sbi->s_mount_opt, TAGGED);
4377 +                       break;
4378 +#endif
4379                 case Opt_nocheck:
4380                         clear_opt (sbi->s_mount_opt, CHECK);
4381                         break;
4382 @@ -728,6 +746,8 @@ static int ext2_fill_super(struct super_
4383         if (!parse_options ((char *) data, sbi))
4384                 goto failed_mount;
4385  
4386 +       if (EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_TAGGED)
4387 +               sb->s_flags |= MS_TAGGED;
4388         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
4389                 ((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
4390                  MS_POSIXACL : 0);
4391 @@ -1036,6 +1056,13 @@ static int ext2_remount (struct super_bl
4392                 goto restore_opts;
4393         }
4394  
4395 +       if ((sbi->s_mount_opt & EXT2_MOUNT_TAGGED) &&
4396 +               !(sb->s_flags & MS_TAGGED)) {
4397 +               printk("EXT2-fs: %s: tagging not permitted on remount.\n",
4398 +                      sb->s_id);
4399 +               return -EINVAL;
4400 +       }
4401 +
4402         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
4403                 ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
4404  
4405 @@ -1148,10 +1175,11 @@ static int ext2_get_sb(struct file_syste
4406   * acquiring the locks... As quota files are never truncated and quota code
4407   * itself serializes the operations (and noone else should touch the files)
4408   * we don't have to be afraid of races */
4409 -static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data,
4410 +static ssize_t ext2_quota_read(struct dqhash *hash, int type, char *data,
4411                                size_t len, loff_t off)
4412  {
4413 -       struct inode *inode = sb_dqopt(sb)->files[type];
4414 +       struct inode *inode = dqh_dqopt(hash)->files[type];
4415 +       struct super_block *sb = hash->dqh_sb;
4416         sector_t blk = off >> EXT2_BLOCK_SIZE_BITS(sb);
4417         int err = 0;
4418         int offset = off & (sb->s_blocksize - 1);
4419 @@ -1192,10 +1220,11 @@ static ssize_t ext2_quota_read(struct su
4420  }
4421  
4422  /* Write to quotafile */
4423 -static ssize_t ext2_quota_write(struct super_block *sb, int type,
4424 +static ssize_t ext2_quota_write(struct dqhash *hash, int type,
4425                                 const char *data, size_t len, loff_t off)
4426  {
4427 -       struct inode *inode = sb_dqopt(sb)->files[type];
4428 +       struct inode *inode = dqh_dqopt(hash)->files[type];
4429 +       struct super_block *sb = hash->dqh_sb;
4430         sector_t blk = off >> EXT2_BLOCK_SIZE_BITS(sb);
4431         int err = 0;
4432         int offset = off & (sb->s_blocksize - 1);
4433 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/symlink.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/symlink.c
4434 --- linux-2.6.19.1/fs/ext2/symlink.c    2005-08-29 22:25:30 +0200
4435 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/symlink.c  2006-11-08 04:57:46 +0100
4436 @@ -38,6 +38,7 @@ struct inode_operations ext2_symlink_ino
4437         .listxattr      = ext2_listxattr,
4438         .removexattr    = generic_removexattr,
4439  #endif
4440 +       .sync_flags     = ext2_sync_flags,
4441  };
4442   
4443  struct inode_operations ext2_fast_symlink_inode_operations = {
4444 @@ -49,4 +50,5 @@ struct inode_operations ext2_fast_symlin
4445         .listxattr      = ext2_listxattr,
4446         .removexattr    = generic_removexattr,
4447  #endif
4448 +       .sync_flags     = ext2_sync_flags,
4449  };
4450 diff -NurpP --minimal linux-2.6.19.1/fs/ext2/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/ext2/xattr.c
4451 --- linux-2.6.19.1/fs/ext2/xattr.c      2006-11-30 21:19:19 +0100
4452 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext2/xattr.c    2006-11-08 04:57:50 +0100
4453 @@ -60,6 +60,7 @@
4454  #include <linux/mbcache.h>
4455  #include <linux/quotaops.h>
4456  #include <linux/rwsem.h>
4457 +#include <linux/vs_dlimit.h>
4458  #include "ext2.h"
4459  #include "xattr.h"
4460  #include "acl.h"
4461 @@ -644,8 +645,12 @@ ext2_xattr_set2(struct inode *inode, str
4462                                    the inode.  */
4463                                 ea_bdebug(new_bh, "reusing block");
4464  
4465 +                               error = -ENOSPC;
4466 +                               if (DLIMIT_ALLOC_BLOCK(inode, 1))
4467 +                                       goto cleanup;
4468                                 error = -EDQUOT;
4469                                 if (DQUOT_ALLOC_BLOCK(inode, 1)) {
4470 +                                       DLIMIT_FREE_BLOCK(inode, 1);
4471                                         unlock_buffer(new_bh);
4472                                         goto cleanup;
4473                                 }
4474 @@ -739,6 +744,7 @@ ext2_xattr_set2(struct inode *inode, str
4475                                 le32_to_cpu(HDR(old_bh)->h_refcount) - 1);
4476                         if (ce)
4477                                 mb_cache_entry_release(ce);
4478 +                       DLIMIT_FREE_BLOCK(inode, 1);
4479                         DQUOT_FREE_BLOCK(inode, 1);
4480                         mark_buffer_dirty(old_bh);
4481                         ea_bdebug(old_bh, "refcount now=%d",
4482 @@ -803,6 +809,7 @@ ext2_xattr_delete_inode(struct inode *in
4483                 mark_buffer_dirty(bh);
4484                 if (IS_SYNC(inode))
4485                         sync_dirty_buffer(bh);
4486 +               DLIMIT_FREE_BLOCK(inode, 1);
4487                 DQUOT_FREE_BLOCK(inode, 1);
4488         }
4489         EXT2_I(inode)->i_file_acl = 0;
4490 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/balloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/balloc.c
4491 --- linux-2.6.19.1/fs/ext3/balloc.c     2006-11-30 21:19:19 +0100
4492 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/balloc.c   2006-12-01 23:41:10 +0100
4493 @@ -19,6 +19,8 @@
4494  #include <linux/ext3_jbd.h>
4495  #include <linux/quotaops.h>
4496  #include <linux/buffer_head.h>
4497 +#include <linux/vs_dlimit.h>
4498 +#include <linux/vs_tag.h>
4499  
4500  /*
4501   * balloc.c contains the blocks allocation and deallocation routines
4502 @@ -613,8 +615,10 @@ void ext3_free_blocks(handle_t *handle, 
4503                 return;
4504         }
4505         ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
4506 -       if (dquot_freed_blocks)
4507 +       if (dquot_freed_blocks) {
4508 +               DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks);
4509                 DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
4510 +       }
4511         return;
4512  }
4513  
4514 @@ -1349,18 +1353,33 @@ out:
4515   *
4516   * Check if filesystem has at least 1 free block available for allocation.
4517   */
4518 -static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
4519 +static int ext3_has_free_blocks(struct super_block *sb)
4520  {
4521 -       ext3_fsblk_t free_blocks, root_blocks;
4522 +       struct ext3_sb_info *sbi = EXT3_SB(sb);
4523 +       unsigned long long free_blocks, root_blocks;
4524 +       int cond;
4525  
4526         free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
4527         root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
4528 -       if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
4529 +
4530 +       vxdprintk(VXD_CBIT(dlim, 3),
4531 +               "ext3_has_free_blocks(%p): free=%llu, root=%llu",
4532 +               sb, free_blocks, root_blocks);
4533 +
4534 +       DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
4535 +
4536 +       cond = (free_blocks < root_blocks + 1 &&
4537 +               !capable(CAP_SYS_RESOURCE) &&
4538                 sbi->s_resuid != current->fsuid &&
4539 -               (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
4540 -               return 0;
4541 -       }
4542 -       return 1;
4543 +               (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
4544 +
4545 +       vxdprintk(VXD_CBIT(dlim, 3),
4546 +               "ext3_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
4547 +               sb, free_blocks, root_blocks,
4548 +               !capable(CAP_SYS_RESOURCE)?'1':'0',
4549 +               sbi->s_resuid, current->fsuid, cond?0:1);
4550 +
4551 +       return (cond ? 0 : 1);
4552  }
4553  
4554  /**
4555 @@ -1377,7 +1396,7 @@ static int ext3_has_free_blocks(struct e
4556   */
4557  int ext3_should_retry_alloc(struct super_block *sb, int *retries)
4558  {
4559 -       if (!ext3_has_free_blocks(EXT3_SB(sb)) || (*retries)++ > 3)
4560 +       if (!ext3_has_free_blocks(sb) || (*retries)++ > 3)
4561                 return 0;
4562  
4563         jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
4564 @@ -1440,6 +1459,8 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h
4565                 *errp = -EDQUOT;
4566                 return 0;
4567         }
4568 +       if (DLIMIT_ALLOC_BLOCK(inode, 1))
4569 +           goto out_dlimit;
4570  
4571         sbi = EXT3_SB(sb);
4572         es = EXT3_SB(sb)->s_es;
4573 @@ -1456,7 +1477,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *h
4574         if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
4575                 my_rsv = &block_i->rsv_window_node;
4576  
4577 -       if (!ext3_has_free_blocks(sbi)) {
4578 +       if (!ext3_has_free_blocks(sb)) {
4579                 *errp = -ENOSPC;
4580                 goto out;
4581         }
4582 @@ -1650,6 +1671,9 @@ allocated:
4583  io_error:
4584         *errp = -EIO;
4585  out:
4586 +       if (!performed_allocation)
4587 +               DLIMIT_FREE_BLOCK(inode, 1);
4588 +out_dlimit:
4589         if (fatal) {
4590                 *errp = fatal;
4591                 ext3_std_error(sb, fatal);
4592 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/file.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/file.c
4593 --- linux-2.6.19.1/fs/ext3/file.c       2006-11-30 21:19:19 +0100
4594 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/file.c     2006-11-08 04:57:51 +0100
4595 @@ -121,6 +121,7 @@ const struct file_operations ext3_file_o
4596         .release        = ext3_release_file,
4597         .fsync          = ext3_sync_file,
4598         .sendfile       = generic_file_sendfile,
4599 +       .sendpage       = generic_file_sendpage,
4600         .splice_read    = generic_file_splice_read,
4601         .splice_write   = generic_file_splice_write,
4602  };
4603 @@ -135,5 +136,6 @@ struct inode_operations ext3_file_inode_
4604         .removexattr    = generic_removexattr,
4605  #endif
4606         .permission     = ext3_permission,
4607 +       .sync_flags     = ext3_sync_flags,
4608  };
4609  
4610 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/ialloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/ialloc.c
4611 --- linux-2.6.19.1/fs/ext3/ialloc.c     2006-11-30 21:19:19 +0100
4612 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/ialloc.c   2006-11-08 04:57:50 +0100
4613 @@ -23,6 +23,8 @@
4614  #include <linux/buffer_head.h>
4615  #include <linux/random.h>
4616  #include <linux/bitops.h>
4617 +#include <linux/vs_dlimit.h>
4618 +#include <linux/vs_tag.h>
4619  
4620  #include <asm/byteorder.h>
4621  
4622 @@ -127,6 +129,7 @@ void ext3_free_inode (handle_t *handle, 
4623         ext3_xattr_delete_inode(handle, inode);
4624         DQUOT_FREE_INODE(inode);
4625         DQUOT_DROP(inode);
4626 +       DLIMIT_FREE_INODE(inode);
4627  
4628         is_directory = S_ISDIR(inode->i_mode);
4629  
4630 @@ -445,6 +448,12 @@ struct inode *ext3_new_inode(handle_t *h
4631         inode = new_inode(sb);
4632         if (!inode)
4633                 return ERR_PTR(-ENOMEM);
4634 +
4635 +       inode->i_tag = dx_current_fstag(sb);
4636 +       if (DLIMIT_ALLOC_INODE(inode)) {
4637 +               err = -ENOSPC;
4638 +               goto out_dlimit;
4639 +       }
4640         ei = EXT3_I(inode);
4641  
4642         sbi = EXT3_SB(sb);
4643 @@ -566,7 +575,8 @@ got:
4644         ei->i_dir_start_lookup = 0;
4645         ei->i_disksize = 0;
4646  
4647 -       ei->i_flags = EXT3_I(dir)->i_flags & ~EXT3_INDEX_FL;
4648 +       ei->i_flags = EXT3_I(dir)->i_flags &
4649 +               ~(EXT3_INDEX_FL|EXT3_IUNLINK_FL|EXT3_BARRIER_FL);
4650         if (S_ISLNK(mode))
4651                 ei->i_flags &= ~(EXT3_IMMUTABLE_FL|EXT3_APPEND_FL);
4652         /* dirsync only applies to directories */
4653 @@ -621,6 +631,8 @@ got:
4654  fail:
4655         ext3_std_error(sb, err);
4656  out:
4657 +       DLIMIT_FREE_INODE(inode);
4658 +out_dlimit:
4659         iput(inode);
4660         ret = ERR_PTR(err);
4661  really_out:
4662 @@ -632,6 +644,7 @@ fail_free_drop:
4663  
4664  fail_drop:
4665         DQUOT_DROP(inode);
4666 +       DLIMIT_FREE_INODE(inode);
4667         inode->i_flags |= S_NOQUOTA;
4668         inode->i_nlink = 0;
4669         iput(inode);
4670 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/inode.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/inode.c
4671 --- linux-2.6.19.1/fs/ext3/inode.c      2006-11-30 21:19:19 +0100
4672 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/inode.c    2006-11-30 19:02:16 +0100
4673 @@ -37,6 +37,7 @@
4674  #include <linux/mpage.h>
4675  #include <linux/uio.h>
4676  #include <linux/bio.h>
4677 +#include <linux/vs_tag.h>
4678  #include "xattr.h"
4679  #include "acl.h"
4680  
4681 @@ -2246,7 +2247,7 @@ void ext3_truncate(struct inode *inode)
4682                 return;
4683         if (ext3_inode_is_fast_symlink(inode))
4684                 return;
4685 -       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
4686 +       if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
4687                 return;
4688  
4689         /*
4690 @@ -2568,19 +2569,77 @@ void ext3_set_inode_flags(struct inode *
4691  {
4692         unsigned int flags = EXT3_I(inode)->i_flags;
4693  
4694 -       inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
4695 +       inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
4696 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
4697 +
4698 +       if (flags & EXT3_IMMUTABLE_FL)
4699 +               inode->i_flags |= S_IMMUTABLE;
4700 +       if (flags & EXT3_IUNLINK_FL)
4701 +               inode->i_flags |= S_IUNLINK;
4702 +       if (flags & EXT3_BARRIER_FL)
4703 +               inode->i_flags |= S_BARRIER;
4704 +
4705         if (flags & EXT3_SYNC_FL)
4706                 inode->i_flags |= S_SYNC;
4707         if (flags & EXT3_APPEND_FL)
4708                 inode->i_flags |= S_APPEND;
4709 -       if (flags & EXT3_IMMUTABLE_FL)
4710 -               inode->i_flags |= S_IMMUTABLE;
4711         if (flags & EXT3_NOATIME_FL)
4712                 inode->i_flags |= S_NOATIME;
4713         if (flags & EXT3_DIRSYNC_FL)
4714                 inode->i_flags |= S_DIRSYNC;
4715  }
4716  
4717 +int ext3_sync_flags(struct inode *inode)
4718 +{
4719 +       unsigned int oldflags, newflags;
4720 +       int err = 0;
4721 +
4722 +       oldflags = EXT3_I(inode)->i_flags;
4723 +       newflags = oldflags & ~(EXT3_APPEND_FL |
4724 +               EXT3_IMMUTABLE_FL | EXT3_IUNLINK_FL |
4725 +               EXT3_BARRIER_FL | EXT3_NOATIME_FL |
4726 +               EXT3_SYNC_FL | EXT3_DIRSYNC_FL);
4727 +
4728 +       if (IS_APPEND(inode))
4729 +               newflags |= EXT3_APPEND_FL;
4730 +       if (IS_IMMUTABLE(inode))
4731 +               newflags |= EXT3_IMMUTABLE_FL;
4732 +       if (IS_IUNLINK(inode))
4733 +               newflags |= EXT3_IUNLINK_FL;
4734 +       if (IS_BARRIER(inode))
4735 +               newflags |= EXT3_BARRIER_FL;
4736 +
4737 +       /* we do not want to copy superblock flags */
4738 +       if (inode->i_flags & S_NOATIME)
4739 +               newflags |= EXT3_NOATIME_FL;
4740 +       if (inode->i_flags & S_SYNC)
4741 +               newflags |= EXT3_SYNC_FL;
4742 +       if (inode->i_flags & S_DIRSYNC)
4743 +               newflags |= EXT3_DIRSYNC_FL;
4744 +
4745 +       if (oldflags ^ newflags) {
4746 +               handle_t *handle;
4747 +               struct ext3_iloc iloc;
4748 +
4749 +               handle = ext3_journal_start(inode, 1);
4750 +               if (IS_ERR(handle))
4751 +                       return PTR_ERR(handle);
4752 +               if (IS_SYNC(inode))
4753 +                       handle->h_sync = 1;
4754 +               err = ext3_reserve_inode_write(handle, inode, &iloc);
4755 +               if (err)
4756 +                       goto flags_err;
4757 +
4758 +               EXT3_I(inode)->i_flags = newflags;
4759 +               inode->i_ctime = CURRENT_TIME;
4760 +
4761 +               err = ext3_mark_iloc_dirty(handle, inode, &iloc);
4762 +       flags_err:
4763 +               ext3_journal_stop(handle);
4764 +       }
4765 +       return err;
4766 +}
4767 +
4768  void ext3_read_inode(struct inode * inode)
4769  {
4770         struct ext3_iloc iloc;
4771 @@ -2588,6 +2647,8 @@ void ext3_read_inode(struct inode * inod
4772         struct ext3_inode_info *ei = EXT3_I(inode);
4773         struct buffer_head *bh;
4774         int block;
4775 +       uid_t uid;
4776 +       gid_t gid;
4777  
4778  #ifdef CONFIG_EXT3_FS_POSIX_ACL
4779         ei->i_acl = EXT3_ACL_NOT_CACHED;
4780 @@ -2600,12 +2661,17 @@ void ext3_read_inode(struct inode * inod
4781         bh = iloc.bh;
4782         raw_inode = ext3_raw_inode(&iloc);
4783         inode->i_mode = le16_to_cpu(raw_inode->i_mode);
4784 -       inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4785 -       inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4786 +       uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
4787 +       gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
4788         if(!(test_opt (inode->i_sb, NO_UID32))) {
4789 -               inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
4790 -               inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
4791 +               uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
4792 +               gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
4793         }
4794 +       inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
4795 +       inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
4796 +       inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
4797 +               le16_to_cpu(raw_inode->i_raw_tag));
4798 +
4799         inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
4800         inode->i_size = le32_to_cpu(raw_inode->i_size);
4801         inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
4802 @@ -2729,6 +2795,8 @@ static int ext3_do_update_inode(handle_t
4803         struct ext3_inode *raw_inode = ext3_raw_inode(iloc);
4804         struct ext3_inode_info *ei = EXT3_I(inode);
4805         struct buffer_head *bh = iloc->bh;
4806 +       uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
4807 +       gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
4808         int err = 0, rc, block;
4809  
4810         /* For fields not not tracking in the in-memory inode,
4811 @@ -2738,29 +2806,32 @@ static int ext3_do_update_inode(handle_t
4812  
4813         raw_inode->i_mode = cpu_to_le16(inode->i_mode);
4814         if(!(test_opt(inode->i_sb, NO_UID32))) {
4815 -               raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
4816 -               raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
4817 +               raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
4818 +               raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid));
4819  /*
4820   * Fix up interoperability with old kernels. Otherwise, old inodes get
4821   * re-used with the upper 16 bits of the uid/gid intact
4822   */
4823                 if(!ei->i_dtime) {
4824                         raw_inode->i_uid_high =
4825 -                               cpu_to_le16(high_16_bits(inode->i_uid));
4826 +                               cpu_to_le16(high_16_bits(uid));
4827                         raw_inode->i_gid_high =
4828 -                               cpu_to_le16(high_16_bits(inode->i_gid));
4829 +                               cpu_to_le16(high_16_bits(gid));
4830                 } else {
4831                         raw_inode->i_uid_high = 0;
4832                         raw_inode->i_gid_high = 0;
4833                 }
4834         } else {
4835                 raw_inode->i_uid_low =
4836 -                       cpu_to_le16(fs_high2lowuid(inode->i_uid));
4837 +                       cpu_to_le16(fs_high2lowuid(uid));
4838                 raw_inode->i_gid_low =
4839 -                       cpu_to_le16(fs_high2lowgid(inode->i_gid));
4840 +                       cpu_to_le16(fs_high2lowgid(gid));
4841                 raw_inode->i_uid_high = 0;
4842                 raw_inode->i_gid_high = 0;
4843         }
4844 +#ifdef CONFIG_TAGGING_INTERN
4845 +       raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
4846 +#endif
4847         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
4848         raw_inode->i_size = cpu_to_le32(ei->i_disksize);
4849         raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
4850 @@ -2913,7 +2984,8 @@ int ext3_setattr(struct dentry *dentry, 
4851                 return error;
4852  
4853         if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
4854 -               (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
4855 +               (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
4856 +               (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
4857                 handle_t *handle;
4858  
4859                 /* (user+group)*(old+new) structure, inode write (sb,
4860 @@ -2935,6 +3007,8 @@ int ext3_setattr(struct dentry *dentry, 
4861                         inode->i_uid = attr->ia_uid;
4862                 if (attr->ia_valid & ATTR_GID)
4863                         inode->i_gid = attr->ia_gid;
4864 +               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
4865 +                       inode->i_tag = attr->ia_tag;
4866                 error = ext3_mark_inode_dirty(handle, inode);
4867                 ext3_journal_stop(handle);
4868         }
4869 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/ioctl.c
4870 --- linux-2.6.19.1/fs/ext3/ioctl.c      2006-11-30 21:19:19 +0100
4871 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/ioctl.c    2006-12-17 04:30:46 +0100
4872 @@ -8,6 +8,7 @@
4873   */
4874  
4875  #include <linux/fs.h>
4876 +#include <linux/mount.h>
4877  #include <linux/jbd.h>
4878  #include <linux/capability.h>
4879  #include <linux/ext3_fs.h>
4880 @@ -15,6 +16,7 @@
4881  #include <linux/time.h>
4882  #include <linux/compat.h>
4883  #include <linux/smp_lock.h>
4884 +#include <linux/vs_tag.h>
4885  #include <asm/uaccess.h>
4886  
4887  int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
4888 @@ -37,7 +39,8 @@ int ext3_ioctl (struct inode * inode, st
4889                 unsigned int oldflags;
4890                 unsigned int jflag;
4891  
4892 -               if (IS_RDONLY(inode))
4893 +               if (IS_RDONLY(inode) ||
4894 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4895                         return -EROFS;
4896  
4897                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4898 @@ -61,7 +64,9 @@ int ext3_ioctl (struct inode * inode, st
4899                  *
4900                  * This test looks nicer. Thanks to Pauline Middelink
4901                  */
4902 -               if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
4903 +               if ((oldflags & EXT3_IMMUTABLE_FL) ||
4904 +                       ((flags ^ oldflags) & (EXT3_APPEND_FL |
4905 +                       EXT3_IMMUTABLE_FL | EXT3_IUNLINK_FL))) {
4906                         if (!capable(CAP_LINUX_IMMUTABLE)) {
4907                                 mutex_unlock(&inode->i_mutex);
4908                                 return -EPERM;
4909 @@ -123,7 +128,8 @@ flags_err:
4910  
4911                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4912                         return -EPERM;
4913 -               if (IS_RDONLY(inode))
4914 +               if (IS_RDONLY(inode) ||
4915 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4916                         return -EROFS;
4917                 if (get_user(generation, (int __user *) arg))
4918                         return -EFAULT;
4919 @@ -177,7 +183,8 @@ flags_err:
4920                 if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
4921                         return -ENOTTY;
4922  
4923 -               if (IS_RDONLY(inode))
4924 +               if (IS_RDONLY(inode) ||
4925 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4926                         return -EROFS;
4927  
4928                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
4929 @@ -212,7 +219,8 @@ flags_err:
4930                 if (!capable(CAP_SYS_RESOURCE))
4931                         return -EPERM;
4932  
4933 -               if (IS_RDONLY(inode))
4934 +               if (IS_RDONLY(inode) ||
4935 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4936                         return -EROFS;
4937  
4938                 if (get_user(n_blocks_count, (__u32 __user *)arg))
4939 @@ -233,7 +241,8 @@ flags_err:
4940                 if (!capable(CAP_SYS_RESOURCE))
4941                         return -EPERM;
4942  
4943 -               if (IS_RDONLY(inode))
4944 +               if (IS_RDONLY(inode) ||
4945 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
4946                         return -EROFS;
4947  
4948                 if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg,
4949 @@ -247,8 +256,6 @@ flags_err:
4950  
4951                 return err;
4952         }
4953 -
4954 -
4955         default:
4956                 return -ENOTTY;
4957         }
4958 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/namei.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/namei.c
4959 --- linux-2.6.19.1/fs/ext3/namei.c      2006-11-30 21:19:19 +0100
4960 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/namei.c    2006-11-30 18:53:18 +0100
4961 @@ -37,6 +37,7 @@
4962  #include <linux/buffer_head.h>
4963  #include <linux/bio.h>
4964  #include <linux/smp_lock.h>
4965 +#include <linux/vs_tag.h>
4966  
4967  #include "namei.h"
4968  #include "xattr.h"
4969 @@ -1010,6 +1011,7 @@ static struct dentry *ext3_lookup(struct
4970  
4971                 if (!inode)
4972                         return ERR_PTR(-EACCES);
4973 +               dx_propagate_tag(nd, inode);
4974         }
4975         return d_splice_alias(inode, dentry);
4976  }
4977 @@ -2383,6 +2385,7 @@ struct inode_operations ext3_dir_inode_o
4978         .removexattr    = generic_removexattr,
4979  #endif
4980         .permission     = ext3_permission,
4981 +       .sync_flags     = ext3_sync_flags,
4982  };
4983  
4984  struct inode_operations ext3_special_inode_operations = {
4985 @@ -2394,4 +2397,5 @@ struct inode_operations ext3_special_ino
4986         .removexattr    = generic_removexattr,
4987  #endif
4988         .permission     = ext3_permission,
4989 +       .sync_flags     = ext3_sync_flags,
4990  };
4991 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/super.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/super.c
4992 --- linux-2.6.19.1/fs/ext3/super.c      2006-11-30 21:19:19 +0100
4993 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/super.c    2006-11-08 04:57:51 +0100
4994 @@ -605,12 +605,12 @@ static int ext3_write_dquot(struct dquot
4995  static int ext3_acquire_dquot(struct dquot *dquot);
4996  static int ext3_release_dquot(struct dquot *dquot);
4997  static int ext3_mark_dquot_dirty(struct dquot *dquot);
4998 -static int ext3_write_info(struct super_block *sb, int type);
4999 -static int ext3_quota_on(struct super_block *sb, int type, int format_id, char *path);
5000 -static int ext3_quota_on_mount(struct super_block *sb, int type);
5001 -static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
5002 +static int ext3_write_info(struct dqhash *hash, int type);
5003 +static int ext3_quota_on(struct dqhash *hash, int type, int format_id, char *path);
5004 +static int ext3_quota_on_mount(struct dqhash *hash, int type);
5005 +static ssize_t ext3_quota_read(struct dqhash *hash, int type, char *data,
5006                                size_t len, loff_t off);
5007 -static ssize_t ext3_quota_write(struct super_block *sb, int type,
5008 +static ssize_t ext3_quota_write(struct dqhash *hash, int type,
5009                                 const char *data, size_t len, loff_t off);
5010  
5011  static struct dquot_operations ext3_quota_operations = {
5012 @@ -677,7 +677,7 @@ enum {
5013         Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
5014         Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
5015         Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
5016 -       Opt_grpquota
5017 +       Opt_grpquota, Opt_tag, Opt_notag, Opt_tagid
5018  };
5019  
5020  static match_table_t tokens = {
5021 @@ -727,6 +727,10 @@ static match_table_t tokens = {
5022         {Opt_quota, "quota"},
5023         {Opt_usrquota, "usrquota"},
5024         {Opt_barrier, "barrier=%u"},
5025 +       {Opt_tag, "tag"},
5026 +       {Opt_notag, "notag"},
5027 +       {Opt_tagid, "tagid=%u"},
5028 +       {Opt_tag, "tagxid"},
5029         {Opt_err, NULL},
5030         {Opt_resize, "resize"},
5031  };
5032 @@ -820,6 +824,20 @@ static int parse_options (char *options,
5033                 case Opt_nouid32:
5034                         set_opt (sbi->s_mount_opt, NO_UID32);
5035                         break;
5036 +#ifndef CONFIG_TAGGING_NONE
5037 +               case Opt_tag:
5038 +                       set_opt (sbi->s_mount_opt, TAGGED);
5039 +                       break;
5040 +               case Opt_notag:
5041 +                       clear_opt (sbi->s_mount_opt, TAGGED);
5042 +                       break;
5043 +#endif
5044 +#ifdef CONFIG_PROPAGATE
5045 +               case Opt_tagid:
5046 +                       /* use args[0] */
5047 +                       set_opt (sbi->s_mount_opt, TAGGED);
5048 +                       break;
5049 +#endif
5050                 case Opt_nocheck:
5051                         clear_opt (sbi->s_mount_opt, CHECK);
5052                         break;
5053 @@ -938,7 +956,7 @@ static int parse_options (char *options,
5054                 case Opt_grpjquota:
5055                         qtype = GRPQUOTA;
5056  set_qf_name:
5057 -                       if (sb_any_quota_enabled(sb)) {
5058 +                       if (dqh_any_quota_enabled(sb->s_dqh)) {
5059                                 printk(KERN_ERR
5060                                         "EXT3-fs: Cannot change journalled "
5061                                         "quota options when quota turned on.\n");
5062 @@ -976,7 +994,7 @@ set_qf_name:
5063                 case Opt_offgrpjquota:
5064                         qtype = GRPQUOTA;
5065  clear_qf_name:
5066 -                       if (sb_any_quota_enabled(sb)) {
5067 +                       if (dqh_any_quota_enabled(sb->s_dqh)) {
5068                                 printk(KERN_ERR "EXT3-fs: Cannot change "
5069                                         "journalled quota options when "
5070                                         "quota turned on.\n");
5071 @@ -1004,7 +1022,7 @@ clear_qf_name:
5072                         set_opt(sbi->s_mount_opt, GRPQUOTA);
5073                         break;
5074                 case Opt_noquota:
5075 -                       if (sb_any_quota_enabled(sb)) {
5076 +                       if (dqh_any_quota_enabled(sb->s_dqh)) {
5077                                 printk(KERN_ERR "EXT3-fs: Cannot change quota "
5078                                         "options when quota turned on.\n");
5079                                 return 0;
5080 @@ -1284,7 +1302,7 @@ static void ext3_orphan_cleanup (struct 
5081         /* Turn on quotas so that they are updated correctly */
5082         for (i = 0; i < MAXQUOTAS; i++) {
5083                 if (EXT3_SB(sb)->s_qf_names[i]) {
5084 -                       int ret = ext3_quota_on_mount(sb, i);
5085 +                       int ret = ext3_quota_on_mount(sb->s_dqh, i);
5086                         if (ret < 0)
5087                                 printk(KERN_ERR
5088                                         "EXT3-fs: Cannot turn on journalled "
5089 @@ -1334,8 +1352,8 @@ static void ext3_orphan_cleanup (struct 
5090  #ifdef CONFIG_QUOTA
5091         /* Turn quotas off */
5092         for (i = 0; i < MAXQUOTAS; i++) {
5093 -               if (sb_dqopt(sb)->files[i])
5094 -                       vfs_quota_off(sb, i);
5095 +               if (dqh_dqopt(sb->s_dqh)->files[i])
5096 +                       vfs_quota_off(sb->s_dqh, i);
5097         }
5098  #endif
5099         sb->s_flags = s_flags; /* Restore MS_RDONLY status */
5100 @@ -1482,6 +1500,9 @@ static int ext3_fill_super (struct super
5101                             NULL, 0))
5102                 goto failed_mount;
5103  
5104 +       if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAGGED)
5105 +               sb->s_flags |= MS_TAGGED;
5106 +
5107         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
5108                 ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
5109  
5110 @@ -1687,8 +1708,8 @@ static int ext3_fill_super (struct super
5111         sb->s_export_op = &ext3_export_ops;
5112         sb->s_xattr = ext3_xattr_handlers;
5113  #ifdef CONFIG_QUOTA
5114 -       sb->s_qcop = &ext3_qctl_operations;
5115 -       sb->dq_op = &ext3_quota_operations;
5116 +       sb->s_dqh->dqh_qop = &ext3_quota_operations;
5117 +       sb->s_dqh->dqh_qcop = &ext3_qctl_operations;
5118  #endif
5119         INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
5120  
5121 @@ -2297,6 +2318,12 @@ static int ext3_remount (struct super_bl
5122  
5123         if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
5124                 ext3_abort(sb, __FUNCTION__, "Abort forced by user");
5125 +       if ((sbi->s_mount_opt & EXT3_MOUNT_TAGGED) &&
5126 +               !(sb->s_flags & MS_TAGGED)) {
5127 +               printk("EXT3-fs: %s: tagging not permitted on remount.\n",
5128 +                       sb->s_id);
5129 +               return -EINVAL;
5130 +       }
5131  
5132         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
5133                 ((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
5134 @@ -2450,7 +2477,7 @@ static int ext3_statfs (struct dentry * 
5135  
5136  static inline struct inode *dquot_to_inode(struct dquot *dquot)
5137  {
5138 -       return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
5139 +       return dqh_dqopt(dquot->dq_dqh)->files[dquot->dq_type];
5140  }
5141  
5142  static int ext3_dquot_initialize(struct inode *inode, int type)
5143 @@ -2493,7 +2520,7 @@ static int ext3_write_dquot(struct dquot
5144  
5145         inode = dquot_to_inode(dquot);
5146         handle = ext3_journal_start(inode,
5147 -                                       EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
5148 +               EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb));
5149         if (IS_ERR(handle))
5150                 return PTR_ERR(handle);
5151         ret = dquot_commit(dquot);
5152 @@ -2509,7 +2536,7 @@ static int ext3_acquire_dquot(struct dqu
5153         handle_t *handle;
5154  
5155         handle = ext3_journal_start(dquot_to_inode(dquot),
5156 -                                       EXT3_QUOTA_INIT_BLOCKS(dquot->dq_sb));
5157 +               EXT3_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb));
5158         if (IS_ERR(handle))
5159                 return PTR_ERR(handle);
5160         ret = dquot_acquire(dquot);
5161 @@ -2525,7 +2552,7 @@ static int ext3_release_dquot(struct dqu
5162         handle_t *handle;
5163  
5164         handle = ext3_journal_start(dquot_to_inode(dquot),
5165 -                                       EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb));
5166 +               EXT3_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb));
5167         if (IS_ERR(handle))
5168                 return PTR_ERR(handle);
5169         ret = dquot_release(dquot);
5170 @@ -2538,8 +2565,8 @@ static int ext3_release_dquot(struct dqu
5171  static int ext3_mark_dquot_dirty(struct dquot *dquot)
5172  {
5173         /* Are we journalling quotas? */
5174 -       if (EXT3_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
5175 -           EXT3_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
5176 +       if (EXT3_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[USRQUOTA] ||
5177 +           EXT3_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[GRPQUOTA]) {
5178                 dquot_mark_dquot_dirty(dquot);
5179                 return ext3_write_dquot(dquot);
5180         } else {
5181 @@ -2547,8 +2574,9 @@ static int ext3_mark_dquot_dirty(struct 
5182         }
5183  }
5184  
5185 -static int ext3_write_info(struct super_block *sb, int type)
5186 +static int ext3_write_info(struct dqhash *hash, int type)
5187  {
5188 +       struct super_block *sb = hash->dqh_sb;
5189         int ret, err;
5190         handle_t *handle;
5191  
5192 @@ -2556,7 +2584,7 @@ static int ext3_write_info(struct super_
5193         handle = ext3_journal_start(sb->s_root->d_inode, 2);
5194         if (IS_ERR(handle))
5195                 return PTR_ERR(handle);
5196 -       ret = dquot_commit_info(sb, type);
5197 +       ret = dquot_commit_info(hash, type);
5198         err = ext3_journal_stop(handle);
5199         if (!ret)
5200                 ret = err;
5201 @@ -2567,18 +2595,20 @@ static int ext3_write_info(struct super_
5202   * Turn on quotas during mount time - we need to find
5203   * the quota file and such...
5204   */
5205 -static int ext3_quota_on_mount(struct super_block *sb, int type)
5206 +static int ext3_quota_on_mount(struct dqhash *hash, int type)
5207  {
5208 -       return vfs_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type],
5209 -                       EXT3_SB(sb)->s_jquota_fmt, type);
5210 +       return vfs_quota_on_mount(hash,
5211 +               EXT3_SB(hash->dqh_sb)->s_qf_names[type],
5212 +               EXT3_SB(hash->dqh_sb)->s_jquota_fmt, type);
5213  }
5214  
5215  /*
5216   * Standard function to be called on quota_on
5217   */
5218 -static int ext3_quota_on(struct super_block *sb, int type, int format_id,
5219 +static int ext3_quota_on(struct dqhash *hash, int type, int format_id,
5220                          char *path)
5221  {
5222 +       struct super_block *sb = hash->dqh_sb;
5223         int err;
5224         struct nameidata nd;
5225  
5226 @@ -2587,7 +2617,7 @@ static int ext3_quota_on(struct super_bl
5227         /* Not journalling quota? */
5228         if (!EXT3_SB(sb)->s_qf_names[USRQUOTA] &&
5229             !EXT3_SB(sb)->s_qf_names[GRPQUOTA])
5230 -               return vfs_quota_on(sb, type, format_id, path);
5231 +               return vfs_quota_on(hash, type, format_id, path);
5232         err = path_lookup(path, LOOKUP_FOLLOW, &nd);
5233         if (err)
5234                 return err;
5235 @@ -2602,17 +2632,18 @@ static int ext3_quota_on(struct super_bl
5236                         "EXT3-fs: Quota file not on filesystem root. "
5237                         "Journalled quota will not work.\n");
5238         path_release(&nd);
5239 -       return vfs_quota_on(sb, type, format_id, path);
5240 +       return vfs_quota_on(hash, type, format_id, path);
5241  }
5242  
5243  /* Read data from quotafile - avoid pagecache and such because we cannot afford
5244   * acquiring the locks... As quota files are never truncated and quota code
5245   * itself serializes the operations (and noone else should touch the files)
5246   * we don't have to be afraid of races */
5247 -static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
5248 +static ssize_t ext3_quota_read(struct dqhash *hash, int type, char *data,
5249                                size_t len, loff_t off)
5250  {
5251 -       struct inode *inode = sb_dqopt(sb)->files[type];
5252 +       struct inode *inode = dqh_dqopt(hash)->files[type];
5253 +       struct super_block *sb = hash->dqh_sb;
5254         sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
5255         int err = 0;
5256         int offset = off & (sb->s_blocksize - 1);
5257 @@ -2647,10 +2678,11 @@ static ssize_t ext3_quota_read(struct su
5258  
5259  /* Write to quotafile (we know the transaction is already started and has
5260   * enough credits) */
5261 -static ssize_t ext3_quota_write(struct super_block *sb, int type,
5262 +static ssize_t ext3_quota_write(struct dqhash *hash, int type,
5263                                 const char *data, size_t len, loff_t off)
5264  {
5265 -       struct inode *inode = sb_dqopt(sb)->files[type];
5266 +       struct inode *inode = dqh_dqopt(hash)->files[type];
5267 +       struct super_block *sb = hash->dqh_sb;
5268         sector_t blk = off >> EXT3_BLOCK_SIZE_BITS(sb);
5269         int err = 0;
5270         int offset = off & (sb->s_blocksize - 1);
5271 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/symlink.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/symlink.c
5272 --- linux-2.6.19.1/fs/ext3/symlink.c    2005-08-29 22:25:30 +0200
5273 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/symlink.c  2006-11-08 04:57:46 +0100
5274 @@ -40,6 +40,7 @@ struct inode_operations ext3_symlink_ino
5275         .listxattr      = ext3_listxattr,
5276         .removexattr    = generic_removexattr,
5277  #endif
5278 +       .sync_flags     = ext3_sync_flags,
5279  };
5280  
5281  struct inode_operations ext3_fast_symlink_inode_operations = {
5282 @@ -51,4 +52,5 @@ struct inode_operations ext3_fast_symlin
5283         .listxattr      = ext3_listxattr,
5284         .removexattr    = generic_removexattr,
5285  #endif
5286 +       .sync_flags     = ext3_sync_flags,
5287  };
5288 diff -NurpP --minimal linux-2.6.19.1/fs/ext3/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/ext3/xattr.c
5289 --- linux-2.6.19.1/fs/ext3/xattr.c      2006-11-30 21:19:19 +0100
5290 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext3/xattr.c    2006-11-08 04:57:50 +0100
5291 @@ -58,6 +58,7 @@
5292  #include <linux/mbcache.h>
5293  #include <linux/quotaops.h>
5294  #include <linux/rwsem.h>
5295 +#include <linux/vs_dlimit.h>
5296  #include "xattr.h"
5297  #include "acl.h"
5298  
5299 @@ -495,6 +496,7 @@ ext3_xattr_release_block(handle_t *handl
5300                         ext3_journal_dirty_metadata(handle, bh);
5301                         if (IS_SYNC(inode))
5302                                 handle->h_sync = 1;
5303 +                       DLIMIT_FREE_BLOCK(inode, 1);
5304                         DQUOT_FREE_BLOCK(inode, 1);
5305                         unlock_buffer(bh);
5306                         ea_bdebug(bh, "refcount now=%d; releasing",
5307 @@ -763,11 +765,14 @@ inserted:
5308                         if (new_bh == bs->bh)
5309                                 ea_bdebug(new_bh, "keeping");
5310                         else {
5311 +                               error = -ENOSPC;
5312 +                               if (DLIMIT_ALLOC_BLOCK(inode, 1))
5313 +                                       goto cleanup;
5314                                 /* The old block is released after updating
5315                                    the inode. */
5316                                 error = -EDQUOT;
5317                                 if (DQUOT_ALLOC_BLOCK(inode, 1))
5318 -                                       goto cleanup;
5319 +                                       goto cleanup_dlimit;
5320                                 error = ext3_journal_get_write_access(handle,
5321                                                                       new_bh);
5322                                 if (error)
5323 @@ -844,6 +849,8 @@ cleanup:
5324  
5325  cleanup_dquot:
5326         DQUOT_FREE_BLOCK(inode, 1);
5327 +cleanup_dlimit:
5328 +       DLIMIT_FREE_BLOCK(inode, 1);
5329         goto cleanup;
5330  
5331  bad_block:
5332 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/balloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/balloc.c
5333 --- linux-2.6.19.1/fs/ext4/balloc.c     2006-11-30 21:19:19 +0100
5334 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/balloc.c   2006-12-02 01:51:51 +0100
5335 @@ -19,6 +19,8 @@
5336  #include <linux/ext4_jbd2.h>
5337  #include <linux/quotaops.h>
5338  #include <linux/buffer_head.h>
5339 +#include <linux/vs_dlimit.h>
5340 +#include <linux/vs_tag.h>
5341  
5342  /*
5343   * balloc.c contains the blocks allocation and deallocation routines
5344 @@ -630,8 +632,10 @@ void ext4_free_blocks(handle_t *handle, 
5345                 return;
5346         }
5347         ext4_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
5348 -       if (dquot_freed_blocks)
5349 +       if (dquot_freed_blocks) {
5350 +               DLIMIT_FREE_BLOCK(inode, dquot_freed_blocks);
5351                 DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
5352 +       }
5353         return;
5354  }
5355  
5356 @@ -1366,18 +1370,33 @@ out:
5357   *
5358   * Check if filesystem has at least 1 free block available for allocation.
5359   */
5360 -static int ext4_has_free_blocks(struct ext4_sb_info *sbi)
5361 +static int ext4_has_free_blocks(struct super_block *sb)
5362  {
5363 -       ext4_fsblk_t free_blocks, root_blocks;
5364 +       struct ext4_sb_info *sbi = EXT4_SB(sb);
5365 +       ext4_fsblk_t free_blocks, root_blocks;
5366 +       int cond;
5367  
5368         free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
5369         root_blocks = ext4_r_blocks_count(sbi->s_es);
5370 -       if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
5371 +
5372 +       vxdprintk(VXD_CBIT(dlim, 3),
5373 +               "ext4_has_free_blocks(%p): free=%llu, root=%llu",
5374 +               sb, free_blocks, root_blocks);
5375 +
5376 +       DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
5377 +
5378 +       cond = (free_blocks < root_blocks + 1 &&
5379 +               !capable(CAP_SYS_RESOURCE) &&
5380                 sbi->s_resuid != current->fsuid &&
5381 -               (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
5382 -               return 0;
5383 -       }
5384 -       return 1;
5385 +               (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
5386 +
5387 +       vxdprintk(VXD_CBIT(dlim, 3),
5388 +               "ext4_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
5389 +               sb, free_blocks, root_blocks,
5390 +               !capable(CAP_SYS_RESOURCE)?'1':'0',
5391 +               sbi->s_resuid, current->fsuid, cond?0:1);
5392 +
5393 +       return (cond ? 0 : 1);
5394  }
5395  
5396  /**
5397 @@ -1394,7 +1413,7 @@ static int ext4_has_free_blocks(struct e
5398   */
5399  int ext4_should_retry_alloc(struct super_block *sb, int *retries)
5400  {
5401 -       if (!ext4_has_free_blocks(EXT4_SB(sb)) || (*retries)++ > 3)
5402 +       if (!ext4_has_free_blocks(sb) || (*retries)++ > 3)
5403                 return 0;
5404  
5405         jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);
5406 @@ -1457,6 +1476,8 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h
5407                 *errp = -EDQUOT;
5408                 return 0;
5409         }
5410 +       if (DLIMIT_ALLOC_BLOCK(inode, 1))
5411 +           goto out_dlimit;
5412  
5413         sbi = EXT4_SB(sb);
5414         es = EXT4_SB(sb)->s_es;
5415 @@ -1473,7 +1494,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *h
5416         if (block_i && ((windowsz = block_i->rsv_window_node.rsv_goal_size) > 0))
5417                 my_rsv = &block_i->rsv_window_node;
5418  
5419 -       if (!ext4_has_free_blocks(sbi)) {
5420 +       if (!ext4_has_free_blocks(sb)) {
5421                 *errp = -ENOSPC;
5422                 goto out;
5423         }
5424 @@ -1664,6 +1685,9 @@ allocated:
5425  io_error:
5426         *errp = -EIO;
5427  out:
5428 +       if (!performed_allocation)
5429 +               DLIMIT_FREE_BLOCK(inode, 1);
5430 +out_dlimit:
5431         if (fatal) {
5432                 *errp = fatal;
5433                 ext4_std_error(sb, fatal);
5434 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/file.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/file.c
5435 --- linux-2.6.19.1/fs/ext4/file.c       2006-11-30 21:19:19 +0100
5436 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/file.c     2006-12-01 23:01:47 +0100
5437 @@ -121,6 +121,7 @@ const struct file_operations ext4_file_o
5438         .release        = ext4_release_file,
5439         .fsync          = ext4_sync_file,
5440         .sendfile       = generic_file_sendfile,
5441 +       .sendpage       = generic_file_sendpage,
5442         .splice_read    = generic_file_splice_read,
5443         .splice_write   = generic_file_splice_write,
5444  };
5445 @@ -135,5 +136,6 @@ struct inode_operations ext4_file_inode_
5446         .removexattr    = generic_removexattr,
5447  #endif
5448         .permission     = ext4_permission,
5449 +       .sync_flags     = ext4_sync_flags,
5450  };
5451  
5452 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/ialloc.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/ialloc.c
5453 --- linux-2.6.19.1/fs/ext4/ialloc.c     2006-11-30 21:19:20 +0100
5454 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/ialloc.c   2006-12-01 23:07:02 +0100
5455 @@ -24,6 +24,8 @@
5456  #include <linux/random.h>
5457  #include <linux/bitops.h>
5458  #include <linux/blkdev.h>
5459 +#include <linux/vs_dlimit.h>
5460 +#include <linux/vs_tag.h>
5461  #include <asm/byteorder.h>
5462  
5463  #include "xattr.h"
5464 @@ -127,6 +129,7 @@ void ext4_free_inode (handle_t *handle, 
5465         ext4_xattr_delete_inode(handle, inode);
5466         DQUOT_FREE_INODE(inode);
5467         DQUOT_DROP(inode);
5468 +       DLIMIT_FREE_INODE(inode);
5469  
5470         is_directory = S_ISDIR(inode->i_mode);
5471  
5472 @@ -448,6 +451,12 @@ struct inode *ext4_new_inode(handle_t *h
5473         inode = new_inode(sb);
5474         if (!inode)
5475                 return ERR_PTR(-ENOMEM);
5476 +
5477 +       inode->i_tag = dx_current_fstag(sb);
5478 +       if (DLIMIT_ALLOC_INODE(inode)) {
5479 +               err = -ENOSPC;
5480 +               goto out_dlimit;
5481 +       }
5482         ei = EXT4_I(inode);
5483  
5484         sbi = EXT4_SB(sb);
5485 @@ -569,7 +578,8 @@ got:
5486         ei->i_dir_start_lookup = 0;
5487         ei->i_disksize = 0;
5488  
5489 -       ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL;
5490 +       ei->i_flags = EXT4_I(dir)->i_flags &
5491 +               ~(EXT4_INDEX_FL|EXT4_IUNLINK_FL|EXT4_BARRIER_FL);
5492         if (S_ISLNK(mode))
5493                 ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL);
5494         /* dirsync only applies to directories */
5495 @@ -635,6 +645,8 @@ got:
5496  fail:
5497         ext4_std_error(sb, err);
5498  out:
5499 +       DLIMIT_FREE_INODE(inode);
5500 +out_dlimit:
5501         iput(inode);
5502         ret = ERR_PTR(err);
5503  really_out:
5504 @@ -646,6 +658,7 @@ fail_free_drop:
5505  
5506  fail_drop:
5507         DQUOT_DROP(inode);
5508 +       DLIMIT_FREE_INODE(inode);
5509         inode->i_flags |= S_NOQUOTA;
5510         inode->i_nlink = 0;
5511         iput(inode);
5512 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/inode.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/inode.c
5513 --- linux-2.6.19.1/fs/ext4/inode.c      2006-11-30 21:19:20 +0100
5514 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/inode.c    2006-12-01 23:01:47 +0100
5515 @@ -37,6 +37,7 @@
5516  #include <linux/mpage.h>
5517  #include <linux/uio.h>
5518  #include <linux/bio.h>
5519 +#include <linux/vs_tag.h>
5520  #include "xattr.h"
5521  #include "acl.h"
5522  
5523 @@ -2245,7 +2246,7 @@ void ext4_truncate(struct inode *inode)
5524                 return;
5525         if (ext4_inode_is_fast_symlink(inode))
5526                 return;
5527 -       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
5528 +       if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
5529                 return;
5530  
5531         /*
5532 @@ -2571,19 +2572,77 @@ void ext4_set_inode_flags(struct inode *
5533  {
5534         unsigned int flags = EXT4_I(inode)->i_flags;
5535  
5536 -       inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
5537 +       inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
5538 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
5539 +
5540 +       if (flags & EXT4_IMMUTABLE_FL)
5541 +               inode->i_flags |= S_IMMUTABLE;
5542 +       if (flags & EXT4_IUNLINK_FL)
5543 +               inode->i_flags |= S_IUNLINK;
5544 +       if (flags & EXT4_BARRIER_FL)
5545 +               inode->i_flags |= S_BARRIER;
5546 +
5547         if (flags & EXT4_SYNC_FL)
5548                 inode->i_flags |= S_SYNC;
5549         if (flags & EXT4_APPEND_FL)
5550                 inode->i_flags |= S_APPEND;
5551 -       if (flags & EXT4_IMMUTABLE_FL)
5552 -               inode->i_flags |= S_IMMUTABLE;
5553         if (flags & EXT4_NOATIME_FL)
5554                 inode->i_flags |= S_NOATIME;
5555         if (flags & EXT4_DIRSYNC_FL)
5556                 inode->i_flags |= S_DIRSYNC;
5557  }
5558  
5559 +int ext4_sync_flags(struct inode *inode)
5560 +{
5561 +       unsigned int oldflags, newflags;
5562 +       int err = 0;
5563 +
5564 +       oldflags = EXT4_I(inode)->i_flags;
5565 +       newflags = oldflags & ~(EXT4_APPEND_FL |
5566 +               EXT4_IMMUTABLE_FL | EXT4_IUNLINK_FL |
5567 +               EXT4_BARRIER_FL | EXT4_NOATIME_FL |
5568 +               EXT4_SYNC_FL | EXT4_DIRSYNC_FL);
5569 +
5570 +       if (IS_APPEND(inode))
5571 +               newflags |= EXT4_APPEND_FL;
5572 +       if (IS_IMMUTABLE(inode))
5573 +               newflags |= EXT4_IMMUTABLE_FL;
5574 +       if (IS_IUNLINK(inode))
5575 +               newflags |= EXT4_IUNLINK_FL;
5576 +       if (IS_BARRIER(inode))
5577 +               newflags |= EXT4_BARRIER_FL;
5578 +
5579 +       /* we do not want to copy superblock flags */
5580 +       if (inode->i_flags & S_NOATIME)
5581 +               newflags |= EXT4_NOATIME_FL;
5582 +       if (inode->i_flags & S_SYNC)
5583 +               newflags |= EXT4_SYNC_FL;
5584 +       if (inode->i_flags & S_DIRSYNC)
5585 +               newflags |= EXT4_DIRSYNC_FL;
5586 +
5587 +       if (oldflags ^ newflags) {
5588 +               handle_t *handle;
5589 +               struct ext4_iloc iloc;
5590 +
5591 +               handle = ext4_journal_start(inode, 1);
5592 +               if (IS_ERR(handle))
5593 +                       return PTR_ERR(handle);
5594 +               if (IS_SYNC(inode))
5595 +                       handle->h_sync = 1;
5596 +               err = ext4_reserve_inode_write(handle, inode, &iloc);
5597 +               if (err)
5598 +                       goto flags_err;
5599 +
5600 +               EXT4_I(inode)->i_flags = newflags;
5601 +               inode->i_ctime = CURRENT_TIME;
5602 +
5603 +               err = ext4_mark_iloc_dirty(handle, inode, &iloc);
5604 +       flags_err:
5605 +               ext4_journal_stop(handle);
5606 +       }
5607 +       return err;
5608 +}
5609 +
5610  void ext4_read_inode(struct inode * inode)
5611  {
5612         struct ext4_iloc iloc;
5613 @@ -2591,6 +2650,8 @@ void ext4_read_inode(struct inode * inod
5614         struct ext4_inode_info *ei = EXT4_I(inode);
5615         struct buffer_head *bh;
5616         int block;
5617 +       uid_t uid;
5618 +       gid_t gid;
5619  
5620  #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
5621         ei->i_acl = EXT4_ACL_NOT_CACHED;
5622 @@ -2603,12 +2664,17 @@ void ext4_read_inode(struct inode * inod
5623         bh = iloc.bh;
5624         raw_inode = ext4_raw_inode(&iloc);
5625         inode->i_mode = le16_to_cpu(raw_inode->i_mode);
5626 -       inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
5627 -       inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
5628 +       uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
5629 +       gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
5630         if(!(test_opt (inode->i_sb, NO_UID32))) {
5631 -               inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
5632 -               inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
5633 +               uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
5634 +               gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
5635         }
5636 +       inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
5637 +       inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
5638 +       inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
5639 +               le16_to_cpu(raw_inode->i_raw_tag));
5640 +
5641         inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
5642         inode->i_size = le32_to_cpu(raw_inode->i_size);
5643         inode->i_atime.tv_sec = le32_to_cpu(raw_inode->i_atime);
5644 @@ -2736,6 +2802,8 @@ static int ext4_do_update_inode(handle_t
5645         struct ext4_inode *raw_inode = ext4_raw_inode(iloc);
5646         struct ext4_inode_info *ei = EXT4_I(inode);
5647         struct buffer_head *bh = iloc->bh;
5648 +       uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
5649 +       gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
5650         int err = 0, rc, block;
5651  
5652         /* For fields not not tracking in the in-memory inode,
5653 @@ -2745,29 +2813,32 @@ static int ext4_do_update_inode(handle_t
5654  
5655         raw_inode->i_mode = cpu_to_le16(inode->i_mode);
5656         if(!(test_opt(inode->i_sb, NO_UID32))) {
5657 -               raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
5658 -               raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid));
5659 +               raw_inode->i_uid_low = cpu_to_le16(low_16_bits(uid));
5660 +               raw_inode->i_gid_low = cpu_to_le16(low_16_bits(gid));
5661  /*
5662   * Fix up interoperability with old kernels. Otherwise, old inodes get
5663   * re-used with the upper 16 bits of the uid/gid intact
5664   */
5665                 if(!ei->i_dtime) {
5666                         raw_inode->i_uid_high =
5667 -                               cpu_to_le16(high_16_bits(inode->i_uid));
5668 +                               cpu_to_le16(high_16_bits(uid));
5669                         raw_inode->i_gid_high =
5670 -                               cpu_to_le16(high_16_bits(inode->i_gid));
5671 +                               cpu_to_le16(high_16_bits(gid));
5672                 } else {
5673                         raw_inode->i_uid_high = 0;
5674                         raw_inode->i_gid_high = 0;
5675                 }
5676         } else {
5677                 raw_inode->i_uid_low =
5678 -                       cpu_to_le16(fs_high2lowuid(inode->i_uid));
5679 +                       cpu_to_le16(fs_high2lowuid(uid));
5680                 raw_inode->i_gid_low =
5681 -                       cpu_to_le16(fs_high2lowgid(inode->i_gid));
5682 +                       cpu_to_le16(fs_high2lowgid(gid));
5683                 raw_inode->i_uid_high = 0;
5684                 raw_inode->i_gid_high = 0;
5685         }
5686 +#ifdef CONFIG_TAGGING_INTERN
5687 +       raw_inode->i_raw_tag = cpu_to_le16(inode->i_tag);
5688 +#endif
5689         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
5690         raw_inode->i_size = cpu_to_le32(ei->i_disksize);
5691         raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
5692 @@ -2924,7 +2995,8 @@ int ext4_setattr(struct dentry *dentry, 
5693                 return error;
5694  
5695         if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
5696 -               (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
5697 +               (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
5698 +               (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
5699                 handle_t *handle;
5700  
5701                 /* (user+group)*(old+new) structure, inode write (sb,
5702 @@ -2946,6 +3018,8 @@ int ext4_setattr(struct dentry *dentry, 
5703                         inode->i_uid = attr->ia_uid;
5704                 if (attr->ia_valid & ATTR_GID)
5705                         inode->i_gid = attr->ia_gid;
5706 +               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
5707 +                       inode->i_tag = attr->ia_tag;
5708                 error = ext4_mark_inode_dirty(handle, inode);
5709                 ext4_journal_stop(handle);
5710         }
5711 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/ioctl.c
5712 --- linux-2.6.19.1/fs/ext4/ioctl.c      2006-11-30 21:19:20 +0100
5713 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/ioctl.c    2006-12-17 04:31:01 +0100
5714 @@ -8,6 +8,7 @@
5715   */
5716  
5717  #include <linux/fs.h>
5718 +#include <linux/mount.h>
5719  #include <linux/jbd2.h>
5720  #include <linux/capability.h>
5721  #include <linux/ext4_fs.h>
5722 @@ -15,6 +16,7 @@
5723  #include <linux/time.h>
5724  #include <linux/compat.h>
5725  #include <linux/smp_lock.h>
5726 +#include <linux/vs_tag.h>
5727  #include <asm/uaccess.h>
5728  
5729  int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
5730 @@ -37,7 +39,8 @@ int ext4_ioctl (struct inode * inode, st
5731                 unsigned int oldflags;
5732                 unsigned int jflag;
5733  
5734 -               if (IS_RDONLY(inode))
5735 +               if (IS_RDONLY(inode) ||
5736 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5737                         return -EROFS;
5738  
5739                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
5740 @@ -61,7 +64,9 @@ int ext4_ioctl (struct inode * inode, st
5741                  *
5742                  * This test looks nicer. Thanks to Pauline Middelink
5743                  */
5744 -               if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) {
5745 +               if ((oldflags & EXT4_IMMUTABLE_FL) ||
5746 +                       ((flags ^ oldflags) & (EXT4_APPEND_FL |
5747 +                       EXT4_IMMUTABLE_FL | EXT4_IUNLINK_FL))) {
5748                         if (!capable(CAP_LINUX_IMMUTABLE)) {
5749                                 mutex_unlock(&inode->i_mutex);
5750                                 return -EPERM;
5751 @@ -123,7 +128,8 @@ flags_err:
5752  
5753                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
5754                         return -EPERM;
5755 -               if (IS_RDONLY(inode))
5756 +               if (IS_RDONLY(inode) ||
5757 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5758                         return -EROFS;
5759                 if (get_user(generation, (int __user *) arg))
5760                         return -EFAULT;
5761 @@ -177,7 +183,8 @@ flags_err:
5762                 if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
5763                         return -ENOTTY;
5764  
5765 -               if (IS_RDONLY(inode))
5766 +               if (IS_RDONLY(inode) ||
5767 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5768                         return -EROFS;
5769  
5770                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
5771 @@ -212,7 +219,8 @@ flags_err:
5772                 if (!capable(CAP_SYS_RESOURCE))
5773                         return -EPERM;
5774  
5775 -               if (IS_RDONLY(inode))
5776 +               if (IS_RDONLY(inode) ||
5777 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5778                         return -EROFS;
5779  
5780                 if (get_user(n_blocks_count, (__u32 __user *)arg))
5781 @@ -233,7 +241,8 @@ flags_err:
5782                 if (!capable(CAP_SYS_RESOURCE))
5783                         return -EPERM;
5784  
5785 -               if (IS_RDONLY(inode))
5786 +               if (IS_RDONLY(inode) ||
5787 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
5788                         return -EROFS;
5789  
5790                 if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
5791 @@ -247,7 +256,6 @@ flags_err:
5792  
5793                 return err;
5794         }
5795 -
5796         default:
5797                 return -ENOTTY;
5798         }
5799 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/namei.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/namei.c
5800 --- linux-2.6.19.1/fs/ext4/namei.c      2006-11-30 21:19:20 +0100
5801 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/namei.c    2006-12-01 23:01:47 +0100
5802 @@ -37,6 +37,7 @@
5803  #include <linux/buffer_head.h>
5804  #include <linux/bio.h>
5805  #include <linux/smp_lock.h>
5806 +#include <linux/vs_tag.h>
5807  
5808  #include "namei.h"
5809  #include "xattr.h"
5810 @@ -1008,6 +1009,7 @@ static struct dentry *ext4_lookup(struct
5811  
5812                 if (!inode)
5813                         return ERR_PTR(-EACCES);
5814 +               dx_propagate_tag(nd, inode);
5815         }
5816         return d_splice_alias(inode, dentry);
5817  }
5818 @@ -2381,6 +2383,7 @@ struct inode_operations ext4_dir_inode_o
5819         .removexattr    = generic_removexattr,
5820  #endif
5821         .permission     = ext4_permission,
5822 +       .sync_flags     = ext4_sync_flags,
5823  };
5824  
5825  struct inode_operations ext4_special_inode_operations = {
5826 @@ -2392,4 +2395,5 @@ struct inode_operations ext4_special_ino
5827         .removexattr    = generic_removexattr,
5828  #endif
5829         .permission     = ext4_permission,
5830 +       .sync_flags     = ext4_sync_flags,
5831  };
5832 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/super.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/super.c
5833 --- linux-2.6.19.1/fs/ext4/super.c      2006-11-30 21:19:20 +0100
5834 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/super.c    2006-12-01 23:17:24 +0100
5835 @@ -656,12 +656,12 @@ static int ext4_write_dquot(struct dquot
5836  static int ext4_acquire_dquot(struct dquot *dquot);
5837  static int ext4_release_dquot(struct dquot *dquot);
5838  static int ext4_mark_dquot_dirty(struct dquot *dquot);
5839 -static int ext4_write_info(struct super_block *sb, int type);
5840 -static int ext4_quota_on(struct super_block *sb, int type, int format_id, char *path);
5841 -static int ext4_quota_on_mount(struct super_block *sb, int type);
5842 -static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
5843 +static int ext4_write_info(struct dqhash *hash, int type);
5844 +static int ext4_quota_on(struct dqhash *hash, int type, int format_id, char *path);
5845 +static int ext4_quota_on_mount(struct dqhash *hash, int type);
5846 +static ssize_t ext4_quota_read(struct dqhash *hash, int type, char *data,
5847                                size_t len, loff_t off);
5848 -static ssize_t ext4_quota_write(struct super_block *sb, int type,
5849 +static ssize_t ext4_quota_write(struct dqhash *hash, int type,
5850                                 const char *data, size_t len, loff_t off);
5851  
5852  static struct dquot_operations ext4_quota_operations = {
5853 @@ -728,7 +728,7 @@ enum {
5854         Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
5855         Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
5856         Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
5857 -       Opt_grpquota, Opt_extents,
5858 +       Opt_grpquota, Opt_extents, Opt_tag, Opt_notag, Opt_tagid
5859  };
5860  
5861  static match_table_t tokens = {
5862 @@ -779,6 +779,10 @@ static match_table_t tokens = {
5863         {Opt_usrquota, "usrquota"},
5864         {Opt_barrier, "barrier=%u"},
5865         {Opt_extents, "extents"},
5866 +       {Opt_tag, "tag"},
5867 +       {Opt_notag, "notag"},
5868 +       {Opt_tagid, "tagid=%u"},
5869 +       {Opt_tag, "tagxid"},
5870         {Opt_err, NULL},
5871         {Opt_resize, "resize"},
5872  };
5873 @@ -872,6 +876,20 @@ static int parse_options (char *options,
5874                 case Opt_nouid32:
5875                         set_opt (sbi->s_mount_opt, NO_UID32);
5876                         break;
5877 +#ifndef CONFIG_TAGGING_NONE
5878 +               case Opt_tag:
5879 +                       set_opt (sbi->s_mount_opt, TAGGED);
5880 +                       break;
5881 +               case Opt_notag:
5882 +                       clear_opt (sbi->s_mount_opt, TAGGED);
5883 +                       break;
5884 +#endif
5885 +#ifdef CONFIG_PROPAGATE
5886 +               case Opt_tagid:
5887 +                       /* use args[0] */
5888 +                       set_opt (sbi->s_mount_opt, TAGGED);
5889 +                       break;
5890 +#endif
5891                 case Opt_nocheck:
5892                         clear_opt (sbi->s_mount_opt, CHECK);
5893                         break;
5894 @@ -990,7 +1008,7 @@ static int parse_options (char *options,
5895                 case Opt_grpjquota:
5896                         qtype = GRPQUOTA;
5897  set_qf_name:
5898 -                       if (sb_any_quota_enabled(sb)) {
5899 +                       if (dqh_any_quota_enabled(sb->s_dqh)) {
5900                                 printk(KERN_ERR
5901                                         "EXT4-fs: Cannot change journalled "
5902                                         "quota options when quota turned on.\n");
5903 @@ -1028,7 +1046,7 @@ set_qf_name:
5904                 case Opt_offgrpjquota:
5905                         qtype = GRPQUOTA;
5906  clear_qf_name:
5907 -                       if (sb_any_quota_enabled(sb)) {
5908 +                       if (dqh_any_quota_enabled(sb->s_dqh)) {
5909                                 printk(KERN_ERR "EXT4-fs: Cannot change "
5910                                         "journalled quota options when "
5911                                         "quota turned on.\n");
5912 @@ -1056,7 +1074,7 @@ clear_qf_name:
5913                         set_opt(sbi->s_mount_opt, GRPQUOTA);
5914                         break;
5915                 case Opt_noquota:
5916 -                       if (sb_any_quota_enabled(sb)) {
5917 +                       if (dqh_any_quota_enabled(sb->s_dqh)) {
5918                                 printk(KERN_ERR "EXT4-fs: Cannot change quota "
5919                                         "options when quota turned on.\n");
5920                                 return 0;
5921 @@ -1341,7 +1359,7 @@ static void ext4_orphan_cleanup (struct 
5922         /* Turn on quotas so that they are updated correctly */
5923         for (i = 0; i < MAXQUOTAS; i++) {
5924                 if (EXT4_SB(sb)->s_qf_names[i]) {
5925 -                       int ret = ext4_quota_on_mount(sb, i);
5926 +                       int ret = ext4_quota_on_mount(sb->s_dqh, i);
5927                         if (ret < 0)
5928                                 printk(KERN_ERR
5929                                         "EXT4-fs: Cannot turn on journalled "
5930 @@ -1391,8 +1409,8 @@ static void ext4_orphan_cleanup (struct 
5931  #ifdef CONFIG_QUOTA
5932         /* Turn quotas off */
5933         for (i = 0; i < MAXQUOTAS; i++) {
5934 -               if (sb_dqopt(sb)->files[i])
5935 -                       vfs_quota_off(sb, i);
5936 +               if (dqh_dqopt(sb->s_dqh)->files[i])
5937 +                       vfs_quota_off(sb->s_dqh, i);
5938         }
5939  #endif
5940         sb->s_flags = s_flags; /* Restore MS_RDONLY status */
5941 @@ -1539,6 +1557,9 @@ static int ext4_fill_super (struct super
5942                             NULL, 0))
5943                 goto failed_mount;
5944  
5945 +       if (EXT4_SB(sb)->s_mount_opt & EXT4_MOUNT_TAGGED)
5946 +               sb->s_flags |= MS_TAGGED;
5947 +
5948         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
5949                 ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
5950  
5951 @@ -1757,8 +1778,8 @@ static int ext4_fill_super (struct super
5952         sb->s_export_op = &ext4_export_ops;
5953         sb->s_xattr = ext4_xattr_handlers;
5954  #ifdef CONFIG_QUOTA
5955 -       sb->s_qcop = &ext4_qctl_operations;
5956 -       sb->dq_op = &ext4_quota_operations;
5957 +       sb->s_dqh->dqh_qop = &ext4_quota_operations;
5958 +       sb->s_dqh->dqh_qcop = &ext4_qctl_operations;
5959  #endif
5960         INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
5961  
5962 @@ -2370,6 +2391,12 @@ static int ext4_remount (struct super_bl
5963  
5964         if (sbi->s_mount_opt & EXT4_MOUNT_ABORT)
5965                 ext4_abort(sb, __FUNCTION__, "Abort forced by user");
5966 +       if ((sbi->s_mount_opt & EXT4_MOUNT_TAGGED) &&
5967 +               !(sb->s_flags & MS_TAGGED)) {
5968 +               printk("EXT4-fs: %s: tagging not permitted on remount.\n",
5969 +                       sb->s_id);
5970 +               return -EINVAL;
5971 +       }
5972  
5973         sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
5974                 ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
5975 @@ -2523,7 +2550,7 @@ static int ext4_statfs (struct dentry * 
5976  
5977  static inline struct inode *dquot_to_inode(struct dquot *dquot)
5978  {
5979 -       return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
5980 +       return dqh_dqopt(dquot->dq_dqh)->files[dquot->dq_type];
5981  }
5982  
5983  static int ext4_dquot_initialize(struct inode *inode, int type)
5984 @@ -2566,7 +2593,7 @@ static int ext4_write_dquot(struct dquot
5985  
5986         inode = dquot_to_inode(dquot);
5987         handle = ext4_journal_start(inode,
5988 -                                       EXT4_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
5989 +               EXT4_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb));
5990         if (IS_ERR(handle))
5991                 return PTR_ERR(handle);
5992         ret = dquot_commit(dquot);
5993 @@ -2582,7 +2609,7 @@ static int ext4_acquire_dquot(struct dqu
5994         handle_t *handle;
5995  
5996         handle = ext4_journal_start(dquot_to_inode(dquot),
5997 -                                       EXT4_QUOTA_INIT_BLOCKS(dquot->dq_sb));
5998 +               EXT4_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb));
5999         if (IS_ERR(handle))
6000                 return PTR_ERR(handle);
6001         ret = dquot_acquire(dquot);
6002 @@ -2598,7 +2625,7 @@ static int ext4_release_dquot(struct dqu
6003         handle_t *handle;
6004  
6005         handle = ext4_journal_start(dquot_to_inode(dquot),
6006 -                                       EXT4_QUOTA_DEL_BLOCKS(dquot->dq_sb));
6007 +               EXT4_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb));
6008         if (IS_ERR(handle))
6009                 return PTR_ERR(handle);
6010         ret = dquot_release(dquot);
6011 @@ -2611,8 +2638,8 @@ static int ext4_release_dquot(struct dqu
6012  static int ext4_mark_dquot_dirty(struct dquot *dquot)
6013  {
6014         /* Are we journalling quotas? */
6015 -       if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
6016 -           EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
6017 +       if (EXT4_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[USRQUOTA] ||
6018 +           EXT4_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[GRPQUOTA]) {
6019                 dquot_mark_dquot_dirty(dquot);
6020                 return ext4_write_dquot(dquot);
6021         } else {
6022 @@ -2620,8 +2647,9 @@ static int ext4_mark_dquot_dirty(struct 
6023         }
6024  }
6025  
6026 -static int ext4_write_info(struct super_block *sb, int type)
6027 +static int ext4_write_info(struct dqhash *hash, int type)
6028  {
6029 +       struct super_block *sb = hash->dqh_sb;
6030         int ret, err;
6031         handle_t *handle;
6032  
6033 @@ -2629,7 +2657,7 @@ static int ext4_write_info(struct super_
6034         handle = ext4_journal_start(sb->s_root->d_inode, 2);
6035         if (IS_ERR(handle))
6036                 return PTR_ERR(handle);
6037 -       ret = dquot_commit_info(sb, type);
6038 +       ret = dquot_commit_info(hash, type);
6039         err = ext4_journal_stop(handle);
6040         if (!ret)
6041                 ret = err;
6042 @@ -2640,18 +2668,20 @@ static int ext4_write_info(struct super_
6043   * Turn on quotas during mount time - we need to find
6044   * the quota file and such...
6045   */
6046 -static int ext4_quota_on_mount(struct super_block *sb, int type)
6047 +static int ext4_quota_on_mount(struct dqhash *hash, int type)
6048  {
6049 -       return vfs_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type],
6050 -                       EXT4_SB(sb)->s_jquota_fmt, type);
6051 +       return vfs_quota_on_mount(hash,
6052 +               EXT4_SB(hash->dqh_sb)->s_qf_names[type],
6053 +               EXT4_SB(hash->dqh_sb)->s_jquota_fmt, type);
6054  }
6055  
6056  /*
6057   * Standard function to be called on quota_on
6058   */
6059 -static int ext4_quota_on(struct super_block *sb, int type, int format_id,
6060 +static int ext4_quota_on(struct dqhash *hash, int type, int format_id,
6061                          char *path)
6062  {
6063 +       struct super_block *sb = hash->dqh_sb;
6064         int err;
6065         struct nameidata nd;
6066  
6067 @@ -2660,7 +2690,7 @@ static int ext4_quota_on(struct super_bl
6068         /* Not journalling quota? */
6069         if (!EXT4_SB(sb)->s_qf_names[USRQUOTA] &&
6070             !EXT4_SB(sb)->s_qf_names[GRPQUOTA])
6071 -               return vfs_quota_on(sb, type, format_id, path);
6072 +               return vfs_quota_on(hash, type, format_id, path);
6073         err = path_lookup(path, LOOKUP_FOLLOW, &nd);
6074         if (err)
6075                 return err;
6076 @@ -2675,17 +2705,18 @@ static int ext4_quota_on(struct super_bl
6077                         "EXT4-fs: Quota file not on filesystem root. "
6078                         "Journalled quota will not work.\n");
6079         path_release(&nd);
6080 -       return vfs_quota_on(sb, type, format_id, path);
6081 +       return vfs_quota_on(hash, type, format_id, path);
6082  }
6083  
6084  /* Read data from quotafile - avoid pagecache and such because we cannot afford
6085   * acquiring the locks... As quota files are never truncated and quota code
6086   * itself serializes the operations (and noone else should touch the files)
6087   * we don't have to be afraid of races */
6088 -static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
6089 +static ssize_t ext4_quota_read(struct dqhash *hash, int type, char *data,
6090                                size_t len, loff_t off)
6091  {
6092 -       struct inode *inode = sb_dqopt(sb)->files[type];
6093 +       struct inode *inode = dqh_dqopt(hash)->files[type];
6094 +       struct super_block *sb = hash->dqh_sb;
6095         sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
6096         int err = 0;
6097         int offset = off & (sb->s_blocksize - 1);
6098 @@ -2720,10 +2751,11 @@ static ssize_t ext4_quota_read(struct su
6099  
6100  /* Write to quotafile (we know the transaction is already started and has
6101   * enough credits) */
6102 -static ssize_t ext4_quota_write(struct super_block *sb, int type,
6103 +static ssize_t ext4_quota_write(struct dqhash *hash, int type,
6104                                 const char *data, size_t len, loff_t off)
6105  {
6106 -       struct inode *inode = sb_dqopt(sb)->files[type];
6107 +       struct inode *inode = dqh_dqopt(hash)->files[type];
6108 +       struct super_block *sb = hash->dqh_sb;
6109         sector_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb);
6110         int err = 0;
6111         int offset = off & (sb->s_blocksize - 1);
6112 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/symlink.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/symlink.c
6113 --- linux-2.6.19.1/fs/ext4/symlink.c    2006-11-30 21:19:20 +0100
6114 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/symlink.c  2006-12-01 23:01:47 +0100
6115 @@ -40,6 +40,7 @@ struct inode_operations ext4_symlink_ino
6116         .listxattr      = ext4_listxattr,
6117         .removexattr    = generic_removexattr,
6118  #endif
6119 +       .sync_flags     = ext4_sync_flags,
6120  };
6121  
6122  struct inode_operations ext4_fast_symlink_inode_operations = {
6123 @@ -51,4 +52,5 @@ struct inode_operations ext4_fast_symlin
6124         .listxattr      = ext4_listxattr,
6125         .removexattr    = generic_removexattr,
6126  #endif
6127 +       .sync_flags     = ext4_sync_flags,
6128  };
6129 diff -NurpP --minimal linux-2.6.19.1/fs/ext4/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/ext4/xattr.c
6130 --- linux-2.6.19.1/fs/ext4/xattr.c      2006-11-30 21:19:20 +0100
6131 +++ linux-2.6.19.1-vs2.3.0.6/fs/ext4/xattr.c    2006-12-01 23:01:47 +0100
6132 @@ -58,6 +58,7 @@
6133  #include <linux/mbcache.h>
6134  #include <linux/quotaops.h>
6135  #include <linux/rwsem.h>
6136 +#include <linux/vs_dlimit.h>
6137  #include "xattr.h"
6138  #include "acl.h"
6139  
6140 @@ -495,6 +496,7 @@ ext4_xattr_release_block(handle_t *handl
6141                         ext4_journal_dirty_metadata(handle, bh);
6142                         if (IS_SYNC(inode))
6143                                 handle->h_sync = 1;
6144 +                       DLIMIT_FREE_BLOCK(inode, 1);
6145                         DQUOT_FREE_BLOCK(inode, 1);
6146                         unlock_buffer(bh);
6147                         ea_bdebug(bh, "refcount now=%d; releasing",
6148 @@ -763,11 +765,14 @@ inserted:
6149                         if (new_bh == bs->bh)
6150                                 ea_bdebug(new_bh, "keeping");
6151                         else {
6152 +                               error = -ENOSPC;
6153 +                               if (DLIMIT_ALLOC_BLOCK(inode, 1))
6154 +                                       goto cleanup;
6155                                 /* The old block is released after updating
6156                                    the inode. */
6157                                 error = -EDQUOT;
6158                                 if (DQUOT_ALLOC_BLOCK(inode, 1))
6159 -                                       goto cleanup;
6160 +                                       goto cleanup_dlimit;
6161                                 error = ext4_journal_get_write_access(handle,
6162                                                                       new_bh);
6163                                 if (error)
6164 @@ -844,6 +849,8 @@ cleanup:
6165  
6166  cleanup_dquot:
6167         DQUOT_FREE_BLOCK(inode, 1);
6168 +cleanup_dlimit:
6169 +       DLIMIT_FREE_BLOCK(inode, 1);
6170         goto cleanup;
6171  
6172  bad_block:
6173 diff -NurpP --minimal linux-2.6.19.1/fs/fcntl.c linux-2.6.19.1-vs2.3.0.6/fs/fcntl.c
6174 --- linux-2.6.19.1/fs/fcntl.c   2006-11-30 21:19:23 +0100
6175 +++ linux-2.6.19.1-vs2.3.0.6/fs/fcntl.c 2006-11-08 04:57:48 +0100
6176 @@ -18,6 +18,7 @@
6177  #include <linux/ptrace.h>
6178  #include <linux/signal.h>
6179  #include <linux/rcupdate.h>
6180 +#include <linux/vs_limit.h>
6181  
6182  #include <asm/poll.h>
6183  #include <asm/siginfo.h>
6184 @@ -85,6 +86,8 @@ repeat:
6185         error = -EMFILE;
6186         if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
6187                 goto out;
6188 +       if (!vx_files_avail(1))
6189 +               goto out;
6190  
6191         error = expand_files(files, newfd);
6192         if (error < 0)
6193 @@ -125,6 +128,7 @@ static int dupfd(struct file *file, unsi
6194                 FD_SET(fd, fdt->open_fds);
6195                 FD_CLR(fd, fdt->close_on_exec);
6196                 spin_unlock(&files->file_lock);
6197 +               vx_openfd_inc(fd);
6198                 fd_install(fd, file);
6199         } else {
6200                 spin_unlock(&files->file_lock);
6201 @@ -177,6 +181,9 @@ asmlinkage long sys_dup2(unsigned int ol
6202  
6203         if (tofree)
6204                 filp_close(tofree, files);
6205 +       else
6206 +               vx_openfd_inc(newfd);   /* fd was unused */
6207 +
6208         err = newfd;
6209  out:
6210         return err;
6211 diff -NurpP --minimal linux-2.6.19.1/fs/file_table.c linux-2.6.19.1-vs2.3.0.6/fs/file_table.c
6212 --- linux-2.6.19.1/fs/file_table.c      2006-11-30 21:19:25 +0100
6213 +++ linux-2.6.19.1-vs2.3.0.6/fs/file_table.c    2006-11-08 04:57:48 +0100
6214 @@ -21,6 +21,8 @@
6215  #include <linux/fsnotify.h>
6216  #include <linux/sysctl.h>
6217  #include <linux/percpu_counter.h>
6218 +#include <linux/vs_limit.h>
6219 +#include <linux/vs_context.h>
6220  
6221  #include <asm/atomic.h>
6222  
6223 @@ -120,6 +122,8 @@ struct file *get_empty_filp(void)
6224         f->f_gid = tsk->fsgid;
6225         eventpoll_init_file(f);
6226         /* f->f_version: 0 */
6227 +       f->f_xid = vx_current_xid();
6228 +       vx_files_inc(f);
6229         return f;
6230  
6231  over:
6232 @@ -175,6 +179,8 @@ void fastcall __fput(struct file *file)
6233         if (file->f_mode & FMODE_WRITE)
6234                 put_write_access(inode);
6235         put_pid(file->f_owner.pid);
6236 +       vx_files_dec(file);
6237 +       file->f_xid = 0;
6238         file_kill(file);
6239         file->f_dentry = NULL;
6240         file->f_vfsmnt = NULL;
6241 @@ -240,6 +246,8 @@ void put_filp(struct file *file)
6242  {
6243         if (atomic_dec_and_test(&file->f_count)) {
6244                 security_file_free(file);
6245 +               vx_files_dec(file);
6246 +               file->f_xid = 0;
6247                 file_kill(file);
6248                 file_free(file);
6249         }
6250 diff -NurpP --minimal linux-2.6.19.1/fs/gfs2/log.c linux-2.6.19.1-vs2.3.0.6/fs/gfs2/log.c
6251 --- linux-2.6.19.1/fs/gfs2/log.c        2006-11-30 21:19:25 +0100
6252 +++ linux-2.6.19.1-vs2.3.0.6/fs/gfs2/log.c      2006-11-08 22:48:20 +0100
6253 @@ -319,7 +319,7 @@ static u64 log_bmap(struct gfs2_sbd *sdp
6254         bh_map.b_size = 1 << inode->i_blkbits;
6255         error = gfs2_block_map(inode, lbn, 0, &bh_map);
6256         if (error || !bh_map.b_blocknr)
6257 -               printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, bh_map.b_blocknr, lbn);
6258 +               printk(KERN_INFO "error=%d, dbn=%lu lbn=%u", error, bh_map.b_blocknr, lbn);
6259         gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr);
6260  
6261         return bh_map.b_blocknr;
6262 diff -NurpP --minimal linux-2.6.19.1/fs/hfsplus/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/hfsplus/ioctl.c
6263 --- linux-2.6.19.1/fs/hfsplus/ioctl.c   2006-11-30 21:19:25 +0100
6264 +++ linux-2.6.19.1-vs2.3.0.6/fs/hfsplus/ioctl.c 2006-11-08 04:57:52 +0100
6265 @@ -16,6 +16,7 @@
6266  #include <linux/fs.h>
6267  #include <linux/sched.h>
6268  #include <linux/xattr.h>
6269 +#include <linux/mount.h>
6270  #include <asm/uaccess.h>
6271  #include "hfsplus_fs.h"
6272  
6273 @@ -35,7 +36,8 @@ int hfsplus_ioctl(struct inode *inode, s
6274                         flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */
6275                 return put_user(flags, (int __user *)arg);
6276         case HFSPLUS_IOC_EXT2_SETFLAGS: {
6277 -               if (IS_RDONLY(inode))
6278 +               if (IS_RDONLY(inode) ||
6279 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
6280                         return -EROFS;
6281  
6282                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
6283 diff -NurpP --minimal linux-2.6.19.1/fs/inode.c linux-2.6.19.1-vs2.3.0.6/fs/inode.c
6284 --- linux-2.6.19.1/fs/inode.c   2006-11-30 21:19:25 +0100
6285 +++ linux-2.6.19.1-vs2.3.0.6/fs/inode.c 2006-11-08 04:57:53 +0100
6286 @@ -115,6 +115,9 @@ static struct inode *alloc_inode(struct 
6287                 struct address_space * const mapping = &inode->i_data;
6288  
6289                 inode->i_sb = sb;
6290 +
6291 +               /* essential because of inode slab reuse */
6292 +               inode->i_tag = 0;
6293                 inode->i_blkbits = sb->s_blocksize_bits;
6294                 inode->i_flags = 0;
6295                 atomic_set(&inode->i_count, 1);
6296 @@ -126,6 +129,9 @@ static struct inode *alloc_inode(struct 
6297                 inode->i_blocks = 0;
6298                 inode->i_bytes = 0;
6299                 inode->i_generation = 0;
6300 +#ifdef CONFIG_QUOTACTL
6301 +               inode->i_dqh = dqhget(sb->s_dqh);
6302 +#endif
6303  #ifdef CONFIG_QUOTA
6304                 memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
6305  #endif
6306 @@ -172,6 +178,8 @@ void destroy_inode(struct inode *inode) 
6307  {
6308         BUG_ON(inode_has_buffers(inode));
6309         security_inode_free(inode);
6310 +       if (dqhash_valid(inode->i_dqh))
6311 +               dqhput(inode->i_dqh);
6312         if (inode->i_sb->s_op->destroy_inode)
6313                 inode->i_sb->s_op->destroy_inode(inode);
6314         else
6315 @@ -233,6 +241,8 @@ void __iget(struct inode * inode)
6316         inodes_stat.nr_unused--;
6317  }
6318  
6319 +EXPORT_SYMBOL_GPL(__iget);
6320 +
6321  /**
6322   * clear_inode - clear an inode
6323   * @inode: inode to clear
6324 @@ -1245,12 +1255,13 @@ EXPORT_SYMBOL(inode_needs_sync);
6325  /* Function back in dquot.c */
6326  int remove_inode_dquot_ref(struct inode *, int, struct list_head *);
6327  
6328 -void remove_dquot_ref(struct super_block *sb, int type,
6329 +void remove_dquot_ref(struct dqhash *hash, int type,
6330                         struct list_head *tofree_head)
6331  {
6332         struct inode *inode;
6333 +       struct super_block *sb = hash->dqh_sb;
6334  
6335 -       if (!sb->dq_op)
6336 +       if (!hash->dqh_qop)
6337                 return; /* nothing to do */
6338         spin_lock(&inode_lock); /* This lock is for inodes code */
6339  
6340 diff -NurpP --minimal linux-2.6.19.1/fs/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/ioctl.c
6341 --- linux-2.6.19.1/fs/ioctl.c   2006-09-20 16:58:35 +0200
6342 +++ linux-2.6.19.1-vs2.3.0.6/fs/ioctl.c 2006-12-17 04:31:15 +0100
6343 @@ -12,10 +12,14 @@
6344  #include <linux/fs.h>
6345  #include <linux/security.h>
6346  #include <linux/module.h>
6347 +#include <linux/proc_fs.h>
6348 +#include <linux/vserver/inode.h>
6349 +#include <linux/vs_tag.h>
6350  
6351  #include <asm/uaccess.h>
6352  #include <asm/ioctls.h>
6353  
6354 +
6355  static long do_ioctl(struct file *filp, unsigned int cmd,
6356                 unsigned long arg)
6357  {
6358 diff -NurpP --minimal linux-2.6.19.1/fs/ioprio.c linux-2.6.19.1-vs2.3.0.6/fs/ioprio.c
6359 --- linux-2.6.19.1/fs/ioprio.c  2006-11-30 21:19:25 +0100
6360 +++ linux-2.6.19.1-vs2.3.0.6/fs/ioprio.c        2006-11-30 18:53:18 +0100
6361 @@ -25,6 +25,7 @@
6362  #include <linux/capability.h>
6363  #include <linux/syscalls.h>
6364  #include <linux/security.h>
6365 +#include <linux/vs_base.h>
6366  
6367  static int set_task_ioprio(struct task_struct *task, int ioprio)
6368  {
6369 @@ -109,7 +110,7 @@ asmlinkage long sys_ioprio_set(int which
6370                         if (!who)
6371                                 user = current->user;
6372                         else
6373 -                               user = find_user(who);
6374 +                               user = find_user(vx_current_xid(), who);
6375  
6376                         if (!user)
6377                                 break;
6378 @@ -197,7 +198,7 @@ asmlinkage long sys_ioprio_get(int which
6379                         if (!who)
6380                                 user = current->user;
6381                         else
6382 -                               user = find_user(who);
6383 +                               user = find_user(vx_current_xid(), who);
6384  
6385                         if (!user)
6386                                 break;
6387 diff -NurpP --minimal linux-2.6.19.1/fs/jffs2/dir.c linux-2.6.19.1-vs2.3.0.6/fs/jffs2/dir.c
6388 --- linux-2.6.19.1/fs/jffs2/dir.c       2006-11-30 21:19:25 +0100
6389 +++ linux-2.6.19.1-vs2.3.0.6/fs/jffs2/dir.c     2006-12-16 10:19:32 +0100
6390 @@ -37,6 +37,8 @@ static int jffs2_mknod (struct inode *,s
6391  static int jffs2_rename (struct inode *, struct dentry *,
6392                          struct inode *, struct dentry *);
6393  
6394 +extern int jffs2_sync_flags(struct inode *);
6395 +
6396  const struct file_operations jffs2_dir_operations =
6397  {
6398         .read =         generic_read_dir,
6399 @@ -59,6 +61,7 @@ struct inode_operations jffs2_dir_inode_
6400         .rename =       jffs2_rename,
6401         .permission =   jffs2_permission,
6402         .setattr =      jffs2_setattr,
6403 +       .sync_flags =   jffs2_sync_flags,
6404         .setxattr =     jffs2_setxattr,
6405         .getxattr =     jffs2_getxattr,
6406         .listxattr =    jffs2_listxattr,
6407 diff -NurpP --minimal linux-2.6.19.1/fs/jffs2/file.c linux-2.6.19.1-vs2.3.0.6/fs/jffs2/file.c
6408 --- linux-2.6.19.1/fs/jffs2/file.c      2006-11-30 21:19:25 +0100
6409 +++ linux-2.6.19.1-vs2.3.0.6/fs/jffs2/file.c    2006-12-16 10:19:32 +0100
6410 @@ -27,6 +27,9 @@ static int jffs2_prepare_write (struct f
6411                                 unsigned start, unsigned end);
6412  static int jffs2_readpage (struct file *filp, struct page *pg);
6413  
6414 +extern int jffs2_sync_flags(struct inode *);
6415 +
6416 +
6417  int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
6418  {
6419         struct inode *inode = dentry->d_inode;
6420 @@ -58,6 +61,7 @@ struct inode_operations jffs2_file_inode
6421  {
6422         .permission =   jffs2_permission,
6423         .setattr =      jffs2_setattr,
6424 +       .sync_flags =   jffs2_sync_flags,
6425         .setxattr =     jffs2_setxattr,
6426         .getxattr =     jffs2_getxattr,
6427         .listxattr =    jffs2_listxattr,
6428 @@ -165,6 +169,7 @@ static int jffs2_prepare_write (struct f
6429                 ri.dsize = cpu_to_je32(pageofs - inode->i_size);
6430                 ri.csize = cpu_to_je32(0);
6431                 ri.compr = JFFS2_COMPR_ZERO;
6432 +               ri.flags = cpu_to_je16(f->flags);
6433                 ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
6434                 ri.data_crc = cpu_to_je32(0);
6435  
6436 @@ -252,6 +257,7 @@ static int jffs2_commit_write (struct fi
6437         ri->gid = cpu_to_je16(inode->i_gid);
6438         ri->isize = cpu_to_je32((uint32_t)inode->i_size);
6439         ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds());
6440 +       ri->flags = cpu_to_je16(f->flags);
6441  
6442         /* In 2.4, it was already kmapped by generic_file_write(). Doesn't
6443            hurt to do it again. The alternative is ifdefs, which are ugly. */
6444 diff -NurpP --minimal linux-2.6.19.1/fs/jffs2/fs.c linux-2.6.19.1-vs2.3.0.6/fs/jffs2/fs.c
6445 --- linux-2.6.19.1/fs/jffs2/fs.c        2006-11-30 21:19:25 +0100
6446 +++ linux-2.6.19.1-vs2.3.0.6/fs/jffs2/fs.c      2006-12-16 10:21:01 +0100
6447 @@ -118,6 +118,9 @@ static int jffs2_do_setattr (struct inod
6448         ri->offset = cpu_to_je32(0);
6449         ri->csize = ri->dsize = cpu_to_je32(mdatalen);
6450         ri->compr = JFFS2_COMPR_NONE;
6451 +       ri->flags = cpu_to_je16(f->flags);
6452 +       printk("··· do set attr flags: %04x\n", f->flags);
6453 +
6454         if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
6455                 /* It's an extension. Make it a hole node */
6456                 ri->compr = JFFS2_COMPR_ZERO;
6457 @@ -181,6 +184,52 @@ static int jffs2_do_setattr (struct inod
6458         return 0;
6459  }
6460  
6461 +void jffs2_set_inode_flags(struct inode *inode)
6462 +{
6463 +       struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
6464 +       unsigned int flags = f->flags;
6465 +
6466 +       inode->i_flags &= ~(JFFS2_INO_FLAG_IMMUTABLE |
6467 +               JFFS2_INO_FLAG_IUNLINK | JFFS2_INO_FLAG_BARRIER);
6468 +
6469 +       if (flags & JFFS2_INO_FLAG_IMMUTABLE)
6470 +               inode->i_flags |= S_IMMUTABLE;
6471 +       if (flags & JFFS2_INO_FLAG_IUNLINK)
6472 +               inode->i_flags |= S_IUNLINK;
6473 +       if (flags & JFFS2_INO_FLAG_BARRIER)
6474 +               inode->i_flags |= S_BARRIER;
6475 +
6476 +       printk("··· set %p[#%lu] flags: %04x\n", inode, inode->i_ino, flags);
6477 +}
6478 +
6479 +int jffs2_sync_flags(struct inode *inode)
6480 +{
6481 +       struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
6482 +       unsigned int oldflags, newflags;
6483 +
6484 +       oldflags = f->flags;
6485 +       newflags = oldflags & ~(JFFS2_INO_FLAG_IMMUTABLE |
6486 +               JFFS2_INO_FLAG_IUNLINK | JFFS2_INO_FLAG_BARRIER);
6487 +
6488 +       if (IS_IMMUTABLE(inode))
6489 +               newflags |= JFFS2_INO_FLAG_IMMUTABLE;
6490 +       if (IS_IUNLINK(inode))
6491 +               newflags |= JFFS2_INO_FLAG_IUNLINK;
6492 +       if (IS_BARRIER(inode))
6493 +               newflags |= JFFS2_INO_FLAG_BARRIER;
6494 +
6495 +       if (oldflags ^ newflags) {
6496 +               f->flags = newflags;
6497 +               inode->i_ctime = CURRENT_TIME;
6498 +               /* strange requirement, see jffs2_dirty_inode() */
6499 +               inode->i_state |= I_DIRTY_DATASYNC;
6500 +               mark_inode_dirty(inode);
6501 +       }
6502 +       printk("··· sync %p[#%lu] flags: %04x ^ %04x\n",
6503 +               inode, inode->i_ino, oldflags, newflags);
6504 +       return 0;
6505 +}
6506 +
6507  int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
6508  {
6509         int rc;
6510 @@ -287,6 +336,7 @@ void jffs2_read_inode (struct inode *ino
6511  
6512                 inode->i_op = &jffs2_dir_inode_operations;
6513                 inode->i_fop = &jffs2_dir_operations;
6514 +               f->flags = je16_to_cpu(latest_node.flags);
6515                 break;
6516         }
6517         case S_IFREG:
6518 @@ -294,6 +344,7 @@ void jffs2_read_inode (struct inode *ino
6519                 inode->i_fop = &jffs2_file_operations;
6520                 inode->i_mapping->a_ops = &jffs2_file_address_operations;
6521                 inode->i_mapping->nrpages = 0;
6522 +               f->flags = je16_to_cpu(latest_node.flags);
6523                 break;
6524  
6525         case S_IFBLK:
6526 @@ -330,7 +381,7 @@ void jffs2_read_inode (struct inode *ino
6527         default:
6528                 printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
6529         }
6530 -
6531 +       jffs2_set_inode_flags(inode);
6532         up(&f->sem);
6533  
6534         D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
6535 @@ -451,6 +502,8 @@ struct inode *jffs2_new_inode (struct in
6536         inode->i_blocks = 0;
6537         inode->i_size = 0;
6538  
6539 +       f->flags = je16_to_cpu(ri->flags);
6540 +       jffs2_set_inode_flags(inode);
6541         insert_inode_hash(inode);
6542  
6543         return inode;
6544 diff -NurpP --minimal linux-2.6.19.1/fs/jffs2/readinode.c linux-2.6.19.1-vs2.3.0.6/fs/jffs2/readinode.c
6545 --- linux-2.6.19.1/fs/jffs2/readinode.c 2006-09-20 16:58:35 +0200
6546 +++ linux-2.6.19.1-vs2.3.0.6/fs/jffs2/readinode.c       2006-12-16 10:19:32 +0100
6547 @@ -759,6 +759,7 @@ static int jffs2_do_read_inode_internal(
6548                 latest_node->isize = cpu_to_je32(0);
6549                 latest_node->gid = cpu_to_je16(0);
6550                 latest_node->uid = cpu_to_je16(0);
6551 +               latest_node->flags = cpu_to_je16(0);
6552                 if (f->inocache->state == INO_STATE_READING)
6553                         jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
6554                 return 0;
6555 diff -NurpP --minimal linux-2.6.19.1/fs/jffs2/write.c linux-2.6.19.1-vs2.3.0.6/fs/jffs2/write.c
6556 --- linux-2.6.19.1/fs/jffs2/write.c     2006-09-20 16:58:35 +0200
6557 +++ linux-2.6.19.1-vs2.3.0.6/fs/jffs2/write.c   2006-12-16 10:19:32 +0100
6558 @@ -46,6 +46,7 @@ int jffs2_do_new_inode(struct jffs2_sb_i
6559         ri->totlen = cpu_to_je32(PAD(sizeof(*ri)));
6560         ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
6561         ri->mode = cpu_to_jemode(mode);
6562 +       ri->flags = cpu_to_je16(0);
6563  
6564         f->highest_version = 1;
6565         ri->version = cpu_to_je32(f->highest_version);
6566 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/acl.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/acl.c
6567 --- linux-2.6.19.1/fs/jfs/acl.c 2006-11-30 21:19:25 +0100
6568 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/acl.c       2006-11-08 04:57:46 +0100
6569 @@ -232,7 +232,8 @@ int jfs_setattr(struct dentry *dentry, s
6570                 return rc;
6571  
6572         if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
6573 -           (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
6574 +           (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) ||
6575 +           (iattr->ia_valid & ATTR_TAG && iattr->ia_tag != inode->i_tag)) {
6576                 if (DQUOT_TRANSFER(inode, iattr))
6577                         return -EDQUOT;
6578         }
6579 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/file.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/file.c
6580 --- linux-2.6.19.1/fs/jfs/file.c        2006-11-30 21:19:25 +0100
6581 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/file.c      2006-11-08 21:52:37 +0100
6582 @@ -98,6 +98,7 @@ struct inode_operations jfs_file_inode_o
6583         .setattr        = jfs_setattr,
6584         .permission     = jfs_permission,
6585  #endif
6586 +       .sync_flags     = jfs_sync_flags,
6587  };
6588  
6589  const struct file_operations jfs_file_operations = {
6590 @@ -109,6 +110,7 @@ const struct file_operations jfs_file_op
6591         .aio_write      = generic_file_aio_write,
6592         .mmap           = generic_file_mmap,
6593         .sendfile       = generic_file_sendfile,
6594 +       .sendpage       = generic_file_sendpage,
6595         .splice_read    = generic_file_splice_read,
6596         .splice_write   = generic_file_splice_write,
6597         .fsync          = jfs_fsync,
6598 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/inode.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/inode.c
6599 --- linux-2.6.19.1/fs/jfs/inode.c       2006-11-30 21:19:25 +0100
6600 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/inode.c     2006-11-08 04:57:50 +0100
6601 @@ -22,6 +22,7 @@
6602  #include <linux/buffer_head.h>
6603  #include <linux/pagemap.h>
6604  #include <linux/quotaops.h>
6605 +#include <linux/vs_dlimit.h>
6606  #include "jfs_incore.h"
6607  #include "jfs_inode.h"
6608  #include "jfs_filsys.h"
6609 @@ -144,6 +145,7 @@ void jfs_delete_inode(struct inode *inod
6610                 DQUOT_INIT(inode);
6611                 DQUOT_FREE_INODE(inode);
6612                 DQUOT_DROP(inode);
6613 +               DLIMIT_FREE_INODE(inode);
6614         }
6615  
6616         clear_inode(inode);
6617 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/ioctl.c
6618 --- linux-2.6.19.1/fs/jfs/ioctl.c       2006-11-30 21:19:25 +0100
6619 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/ioctl.c     2006-11-08 04:57:51 +0100
6620 @@ -9,6 +9,7 @@
6621  #include <linux/ctype.h>
6622  #include <linux/capability.h>
6623  #include <linux/time.h>
6624 +#include <linux/mount.h>
6625  #include <asm/current.h>
6626  #include <asm/uaccess.h>
6627  
6628 @@ -64,7 +65,8 @@ int jfs_ioctl(struct inode * inode, stru
6629         case JFS_IOC_SETFLAGS: {
6630                 unsigned int oldflags;
6631  
6632 -               if (IS_RDONLY(inode))
6633 +               if (IS_RDONLY(inode) ||
6634 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
6635                         return -EROFS;
6636  
6637                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
6638 @@ -84,8 +86,8 @@ int jfs_ioctl(struct inode * inode, stru
6639                  * the relevant capability.
6640                  */
6641                 if ((oldflags & JFS_IMMUTABLE_FL) ||
6642 -                       ((flags ^ oldflags) &
6643 -                       (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
6644 +                       ((flags ^ oldflags) & (JFS_APPEND_FL |
6645 +                       JFS_IMMUTABLE_FL | JFS_IUNLINK_FL))) {
6646                         if (!capable(CAP_LINUX_IMMUTABLE))
6647                                 return -EPERM;
6648                 }
6649 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_dinode.h linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_dinode.h
6650 --- linux-2.6.19.1/fs/jfs/jfs_dinode.h  2006-11-30 21:19:25 +0100
6651 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_dinode.h        2006-11-08 04:57:51 +0100
6652 @@ -162,9 +162,12 @@ struct dinode {
6653  #define JFS_APPEND_FL          0x01000000 /* writes to file may only append */
6654  #define JFS_IMMUTABLE_FL       0x02000000 /* Immutable file */
6655  
6656 -#define JFS_FL_USER_VISIBLE    0x03F80000
6657 +#define JFS_BARRIER_FL         0x04000000 /* Barrier for chroot() */
6658 +#define JFS_IUNLINK_FL         0x08000000 /* Immutable unlink */
6659 +
6660 +#define JFS_FL_USER_VISIBLE    0x0FF80000
6661  #define JFS_FL_USER_MODIFIABLE 0x03F80000
6662 -#define JFS_FL_INHERIT         0x03C80000
6663 +#define JFS_FL_INHERIT         0x0BC80000
6664  
6665  /* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
6666  #define JFS_IOC_GETFLAGS       _IOR('f', 1, long)
6667 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_dtree.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_dtree.c
6668 --- linux-2.6.19.1/fs/jfs/jfs_dtree.c   2006-11-30 21:19:25 +0100
6669 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_dtree.c 2006-11-08 04:57:50 +0100
6670 @@ -102,6 +102,7 @@
6671  
6672  #include <linux/fs.h>
6673  #include <linux/quotaops.h>
6674 +#include <linux/vs_dlimit.h>
6675  #include "jfs_incore.h"
6676  #include "jfs_superblock.h"
6677  #include "jfs_filsys.h"
6678 @@ -383,10 +384,10 @@ static u32 add_index(tid_t tid, struct i
6679                  */
6680                 if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage))
6681                         goto clean_up;
6682 -               if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) {
6683 -                       DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
6684 -                       goto clean_up;
6685 -               }
6686 +               if (DLIMIT_ALLOC_BLOCK(ip, sbi->nbperpage))
6687 +                       goto clean_up_dquot;
6688 +               if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
6689 +                       goto clean_up_dlimit;
6690  
6691                 /*
6692                  * Save the table, we're going to overwrite it with the
6693 @@ -479,6 +480,12 @@ static u32 add_index(tid_t tid, struct i
6694  
6695         return index;
6696  
6697 +      clean_up_dlimit:
6698 +       DLIMIT_FREE_BLOCK(ip, sbi->nbperpage);
6699 +
6700 +      clean_up_dquot:
6701 +       DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
6702 +
6703        clean_up:
6704  
6705         jfs_ip->next_index--;
6706 @@ -952,6 +959,7 @@ static int dtSplitUp(tid_t tid,
6707         struct tlock *tlck;
6708         struct lv *lv;
6709         int quota_allocation = 0;
6710 +       int dlimit_allocation = 0;
6711  
6712         /* get split page */
6713         smp = split->mp;
6714 @@ -1036,6 +1044,12 @@ static int dtSplitUp(tid_t tid,
6715                 }
6716                 quota_allocation += n;
6717  
6718 +               if (DLIMIT_ALLOC_BLOCK(ip, n)) {
6719 +                       rc = -ENOSPC;
6720 +                       goto extendOut;
6721 +               }
6722 +               dlimit_allocation += n;
6723 +
6724                 if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen,
6725                                     (s64) n, &nxaddr)))
6726                         goto extendOut;
6727 @@ -1309,6 +1323,9 @@ static int dtSplitUp(tid_t tid,
6728        freeKeyName:
6729         kfree(key.name);
6730  
6731 +       /* Rollback dlimit allocation */
6732 +       if (rc && dlimit_allocation)
6733 +               DLIMIT_FREE_BLOCK(ip, dlimit_allocation);
6734         /* Rollback quota allocation */
6735         if (rc && quota_allocation)
6736                 DQUOT_FREE_BLOCK(ip, quota_allocation);
6737 @@ -1376,6 +1393,12 @@ static int dtSplitPage(tid_t tid, struct
6738                 release_metapage(rmp);
6739                 return -EDQUOT;
6740         }
6741 +       /* Allocate blocks to dlimit. */
6742 +       if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
6743 +               DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
6744 +               release_metapage(rmp);
6745 +               return -ENOSPC;
6746 +       }
6747  
6748         jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
6749  
6750 @@ -1926,6 +1949,12 @@ static int dtSplitRoot(tid_t tid,
6751                 release_metapage(rmp);
6752                 return -EDQUOT;
6753         }
6754 +       /* Allocate blocks to dlimit. */
6755 +       if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
6756 +               DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
6757 +               release_metapage(rmp);
6758 +               return -ENOSPC;
6759 +       }
6760  
6761         BT_MARK_DIRTY(rmp, ip);
6762         /*
6763 @@ -2292,6 +2321,8 @@ static int dtDeleteUp(tid_t tid, struct 
6764  
6765         xlen = lengthPXD(&fp->header.self);
6766  
6767 +       /* Free dlimit allocation. */
6768 +       DLIMIT_FREE_BLOCK(ip, xlen);
6769         /* Free quota allocation. */
6770         DQUOT_FREE_BLOCK(ip, xlen);
6771  
6772 @@ -2368,6 +2399,8 @@ static int dtDeleteUp(tid_t tid, struct 
6773  
6774                                 xlen = lengthPXD(&p->header.self);
6775  
6776 +                               /* Free dlimit allocation */
6777 +                               DLIMIT_FREE_BLOCK(ip, xlen);
6778                                 /* Free quota allocation */
6779                                 DQUOT_FREE_BLOCK(ip, xlen);
6780  
6781 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_extent.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_extent.c
6782 --- linux-2.6.19.1/fs/jfs/jfs_extent.c  2006-11-30 21:19:25 +0100
6783 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_extent.c        2006-11-08 04:57:50 +0100
6784 @@ -18,6 +18,7 @@
6785  
6786  #include <linux/fs.h>
6787  #include <linux/quotaops.h>
6788 +#include <linux/vs_dlimit.h>
6789  #include "jfs_incore.h"
6790  #include "jfs_inode.h"
6791  #include "jfs_superblock.h"
6792 @@ -147,6 +148,14 @@ extAlloc(struct inode *ip, s64 xlen, s64
6793                 return -EDQUOT;
6794         }
6795  
6796 +       /* Allocate blocks to dlimit. */
6797 +       if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
6798 +               DQUOT_FREE_BLOCK(ip, nxlen);
6799 +               dbFree(ip, nxaddr, (s64) nxlen);
6800 +               mutex_unlock(&JFS_IP(ip)->commit_mutex);
6801 +               return -ENOSPC;
6802 +       }
6803 +
6804         /* determine the value of the extent flag */
6805         xflag = abnr ? XAD_NOTRECORDED : 0;
6806  
6807 @@ -164,6 +173,7 @@ extAlloc(struct inode *ip, s64 xlen, s64
6808          */
6809         if (rc) {
6810                 dbFree(ip, nxaddr, nxlen);
6811 +               DLIMIT_FREE_BLOCK(ip, nxlen);
6812                 DQUOT_FREE_BLOCK(ip, nxlen);
6813                 mutex_unlock(&JFS_IP(ip)->commit_mutex);
6814                 return (rc);
6815 @@ -261,6 +271,13 @@ int extRealloc(struct inode *ip, s64 nxl
6816                 mutex_unlock(&JFS_IP(ip)->commit_mutex);
6817                 return -EDQUOT;
6818         }
6819 +       /* Allocate blocks to dlimit. */
6820 +       if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
6821 +               DQUOT_FREE_BLOCK(ip, nxlen);
6822 +               dbFree(ip, nxaddr, (s64) nxlen);
6823 +               up(&JFS_IP(ip)->commit_sem);
6824 +               return -ENOSPC;
6825 +       }
6826  
6827         delta = nxlen - xlen;
6828  
6829 @@ -297,6 +314,7 @@ int extRealloc(struct inode *ip, s64 nxl
6830                 /* extend the extent */
6831                 if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
6832                         dbFree(ip, xaddr + xlen, delta);
6833 +                       DLIMIT_FREE_BLOCK(ip, nxlen);
6834                         DQUOT_FREE_BLOCK(ip, nxlen);
6835                         goto exit;
6836                 }
6837 @@ -308,6 +326,7 @@ int extRealloc(struct inode *ip, s64 nxl
6838                  */
6839                 if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
6840                         dbFree(ip, nxaddr, nxlen);
6841 +                       DLIMIT_FREE_BLOCK(ip, nxlen);
6842                         DQUOT_FREE_BLOCK(ip, nxlen);
6843                         goto exit;
6844                 }
6845 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_filsys.h linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_filsys.h
6846 --- linux-2.6.19.1/fs/jfs/jfs_filsys.h  2006-11-30 21:19:25 +0100
6847 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_filsys.h        2006-11-08 04:57:46 +0100
6848 @@ -84,6 +84,7 @@
6849  #define JFS_DIR_INDEX          0x00200000      /* Persistant index for */
6850                                                 /* directory entries    */
6851  
6852 +#define JFS_TAGGED             0x00800000      /* Context Tagging */
6853  
6854  /*
6855   *     buffer cache configuration
6856 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_imap.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_imap.c
6857 --- linux-2.6.19.1/fs/jfs/jfs_imap.c    2006-11-30 21:19:25 +0100
6858 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_imap.c  2006-11-30 18:53:18 +0100
6859 @@ -45,6 +45,7 @@
6860  #include <linux/buffer_head.h>
6861  #include <linux/pagemap.h>
6862  #include <linux/quotaops.h>
6863 +#include <linux/vs_tag.h>
6864  
6865  #include "jfs_incore.h"
6866  #include "jfs_inode.h"
6867 @@ -3075,6 +3076,8 @@ static int copy_from_dinode(struct dinod
6868  {
6869         struct jfs_inode_info *jfs_ip = JFS_IP(ip);
6870         struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
6871 +       uid_t uid;
6872 +       gid_t gid;
6873  
6874         jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
6875         jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
6876 @@ -3094,14 +3097,18 @@ static int copy_from_dinode(struct dinod
6877         }
6878         ip->i_nlink = le32_to_cpu(dip->di_nlink);
6879  
6880 -       jfs_ip->saved_uid = le32_to_cpu(dip->di_uid);
6881 +       uid = le32_to_cpu(dip->di_uid);
6882 +       gid = le32_to_cpu(dip->di_gid);
6883 +       ip->i_tag = INOTAG_TAG(DX_TAG(ip), uid, gid, 0);
6884 +
6885 +       jfs_ip->saved_uid = INOTAG_UID(DX_TAG(ip), uid, gid);
6886         if (sbi->uid == -1)
6887                 ip->i_uid = jfs_ip->saved_uid;
6888         else {
6889                 ip->i_uid = sbi->uid;
6890         }
6891  
6892 -       jfs_ip->saved_gid = le32_to_cpu(dip->di_gid);
6893 +       jfs_ip->saved_gid = INOTAG_GID(DX_TAG(ip), uid, gid);
6894         if (sbi->gid == -1)
6895                 ip->i_gid = jfs_ip->saved_gid;
6896         else {
6897 @@ -3166,14 +3173,12 @@ static void copy_to_dinode(struct dinode
6898         dip->di_size = cpu_to_le64(ip->i_size);
6899         dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
6900         dip->di_nlink = cpu_to_le32(ip->i_nlink);
6901 -       if (sbi->uid == -1)
6902 -               dip->di_uid = cpu_to_le32(ip->i_uid);
6903 -       else
6904 -               dip->di_uid = cpu_to_le32(jfs_ip->saved_uid);
6905 -       if (sbi->gid == -1)
6906 -               dip->di_gid = cpu_to_le32(ip->i_gid);
6907 -       else
6908 -               dip->di_gid = cpu_to_le32(jfs_ip->saved_gid);
6909 +
6910 +       dip->di_uid = cpu_to_le32(TAGINO_UID(DX_TAG(ip),
6911 +               (sbi->uid == -1) ? ip->i_uid : jfs_ip->saved_uid, ip->i_tag));
6912 +       dip->di_gid = cpu_to_le32(TAGINO_GID(DX_TAG(ip),
6913 +               (sbi->gid == -1) ? ip->i_gid : jfs_ip->saved_gid, ip->i_tag));
6914 +
6915         /*
6916          * mode2 is only needed for storing the higher order bits.
6917          * Trust i_mode for the lower order ones
6918 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_inode.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_inode.c
6919 --- linux-2.6.19.1/fs/jfs/jfs_inode.c   2006-11-30 21:19:25 +0100
6920 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_inode.c 2006-11-08 04:57:51 +0100
6921 @@ -18,6 +18,8 @@
6922  
6923  #include <linux/fs.h>
6924  #include <linux/quotaops.h>
6925 +#include <linux/vs_dlimit.h>
6926 +#include <linux/vs_tag.h>
6927  #include "jfs_incore.h"
6928  #include "jfs_inode.h"
6929  #include "jfs_filsys.h"
6930 @@ -30,19 +32,59 @@ void jfs_set_inode_flags(struct inode *i
6931  {
6932         unsigned int flags = JFS_IP(inode)->mode2;
6933  
6934 -       inode->i_flags &= ~(S_IMMUTABLE | S_APPEND |
6935 -               S_NOATIME | S_DIRSYNC | S_SYNC);
6936 +       inode->i_flags &= ~(S_IMMUTABLE | S_IUNLINK | S_BARRIER |
6937 +               S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
6938  
6939         if (flags & JFS_IMMUTABLE_FL)
6940                 inode->i_flags |= S_IMMUTABLE;
6941 +       if (flags & JFS_IUNLINK_FL)
6942 +               inode->i_flags |= S_IUNLINK;
6943 +       if (flags & JFS_BARRIER_FL)
6944 +               inode->i_flags |= S_BARRIER;
6945 +
6946 +       if (flags & JFS_SYNC_FL)
6947 +               inode->i_flags |= S_SYNC;
6948         if (flags & JFS_APPEND_FL)
6949                 inode->i_flags |= S_APPEND;
6950         if (flags & JFS_NOATIME_FL)
6951                 inode->i_flags |= S_NOATIME;
6952         if (flags & JFS_DIRSYNC_FL)
6953                 inode->i_flags |= S_DIRSYNC;
6954 -       if (flags & JFS_SYNC_FL)
6955 -               inode->i_flags |= S_SYNC;
6956 +}
6957 +
6958 +int jfs_sync_flags(struct inode *inode)
6959 +{
6960 +       unsigned int oldflags, newflags;
6961 +
6962 +       oldflags = JFS_IP(inode)->mode2;
6963 +       newflags = oldflags & ~(JFS_APPEND_FL |
6964 +               JFS_IMMUTABLE_FL | JFS_IUNLINK_FL |
6965 +               JFS_BARRIER_FL | JFS_NOATIME_FL |
6966 +               JFS_SYNC_FL | JFS_DIRSYNC_FL);
6967 +
6968 +       if (IS_APPEND(inode))
6969 +               newflags |= JFS_APPEND_FL;
6970 +       if (IS_IMMUTABLE(inode))
6971 +               newflags |= JFS_IMMUTABLE_FL;
6972 +       if (IS_IUNLINK(inode))
6973 +               newflags |= JFS_IUNLINK_FL;
6974 +       if (IS_BARRIER(inode))
6975 +               newflags |= JFS_BARRIER_FL;
6976 +
6977 +       /* we do not want to copy superblock flags */
6978 +       if (inode->i_flags & S_NOATIME)
6979 +               newflags |= JFS_NOATIME_FL;
6980 +       if (inode->i_flags & S_SYNC)
6981 +               newflags |= JFS_SYNC_FL;
6982 +       if (inode->i_flags & S_DIRSYNC)
6983 +               newflags |= JFS_DIRSYNC_FL;
6984 +
6985 +       if (oldflags ^ newflags) {
6986 +               JFS_IP(inode)->mode2 = newflags;
6987 +               inode->i_ctime = CURRENT_TIME;
6988 +               mark_inode_dirty(inode);
6989 +       }
6990 +       return 0;
6991  }
6992  
6993  /*
6994 @@ -90,10 +132,17 @@ struct inode *ialloc(struct inode *paren
6995         jfs_inode->saved_uid = inode->i_uid;
6996         jfs_inode->saved_gid = inode->i_gid;
6997  
6998 +       inode->i_tag = dx_current_fstag(sb);
6999 +       if (DLIMIT_ALLOC_INODE(inode)) {
7000 +               iput(inode);
7001 +               return NULL;
7002 +       }
7003 +
7004         /*
7005          * Allocate inode to quota.
7006          */
7007         if (DQUOT_ALLOC_INODE(inode)) {
7008 +               DLIMIT_FREE_INODE(inode);
7009                 DQUOT_DROP(inode);
7010                 inode->i_flags |= S_NOQUOTA;
7011                 inode->i_nlink = 0;
7012 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_inode.h linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_inode.h
7013 --- linux-2.6.19.1/fs/jfs/jfs_inode.h   2006-11-30 21:19:25 +0100
7014 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_inode.h 2006-11-08 04:57:51 +0100
7015 @@ -31,6 +31,7 @@ extern void jfs_truncate(struct inode *)
7016  extern void jfs_truncate_nolock(struct inode *, loff_t);
7017  extern void jfs_free_zero_link(struct inode *);
7018  extern struct dentry *jfs_get_parent(struct dentry *dentry);
7019 +extern int jfs_sync_flags(struct inode *);
7020  extern void jfs_set_inode_flags(struct inode *);
7021  extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
7022  
7023 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/jfs_xtree.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_xtree.c
7024 --- linux-2.6.19.1/fs/jfs/jfs_xtree.c   2006-11-30 21:19:26 +0100
7025 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/jfs_xtree.c 2006-11-08 04:57:50 +0100
7026 @@ -21,6 +21,7 @@
7027  
7028  #include <linux/fs.h>
7029  #include <linux/quotaops.h>
7030 +#include <linux/vs_dlimit.h>
7031  #include "jfs_incore.h"
7032  #include "jfs_filsys.h"
7033  #include "jfs_metapage.h"
7034 @@ -841,7 +842,12 @@ int xtInsert(tid_t tid,            /* transaction 
7035                         hint = 0;
7036                 if ((rc = DQUOT_ALLOC_BLOCK(ip, xlen)))
7037                         goto out;
7038 +               if ((rc = DLIMIT_ALLOC_BLOCK(ip, xlen))) {
7039 +                       DQUOT_FREE_BLOCK(ip, xlen);
7040 +                       goto out;
7041 +               }
7042                 if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) {
7043 +                       DLIMIT_FREE_BLOCK(ip, xlen);
7044                         DQUOT_FREE_BLOCK(ip, xlen);
7045                         goto out;
7046                 }
7047 @@ -871,6 +877,7 @@ int xtInsert(tid_t tid,             /* transaction 
7048                         /* undo data extent allocation */
7049                         if (*xaddrp == 0) {
7050                                 dbFree(ip, xaddr, (s64) xlen);
7051 +                               DLIMIT_FREE_BLOCK(ip, xlen);
7052                                 DQUOT_FREE_BLOCK(ip, xlen);
7053                         }
7054                         return rc;
7055 @@ -1231,6 +1238,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
7056         struct tlock *tlck;
7057         struct xtlock *sxtlck = NULL, *rxtlck = NULL;
7058         int quota_allocation = 0;
7059 +       int dlimit_allocation = 0;
7060  
7061         smp = split->mp;
7062         sp = XT_PAGE(ip, smp);
7063 @@ -1250,6 +1258,13 @@ xtSplitPage(tid_t tid, struct inode *ip,
7064  
7065         quota_allocation += lengthPXD(pxd);
7066  
7067 +       /* Allocate blocks to dlimit. */
7068 +       if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
7069 +              rc = -ENOSPC;
7070 +              goto clean_up;
7071 +       }
7072 +       dlimit_allocation += lengthPXD(pxd);
7073 +
7074         /*
7075          * allocate the new right page for the split
7076          */
7077 @@ -1451,6 +1466,9 @@ xtSplitPage(tid_t tid, struct inode *ip,
7078  
7079        clean_up:
7080  
7081 +       /* Rollback dlimit allocation. */
7082 +       if (dlimit_allocation)
7083 +               DLIMIT_FREE_BLOCK(ip, dlimit_allocation);
7084         /* Rollback quota allocation. */
7085         if (quota_allocation)
7086                 DQUOT_FREE_BLOCK(ip, quota_allocation);
7087 @@ -1515,6 +1533,12 @@ xtSplitRoot(tid_t tid,
7088                 release_metapage(rmp);
7089                 return -EDQUOT;
7090         }
7091 +       /* Allocate blocks to dlimit. */
7092 +       if (DLIMIT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
7093 +               DQUOT_FREE_BLOCK(ip, lengthPXD(pxd));
7094 +               release_metapage(rmp);
7095 +               return -ENOSPC;
7096 +       }
7097  
7098         jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp);
7099  
7100 @@ -3941,6 +3965,8 @@ s64 xtTruncate(tid_t tid, struct inode *
7101         else
7102                 ip->i_size = newsize;
7103  
7104 +       /* update dlimit allocation to reflect freed blocks */
7105 +       DLIMIT_FREE_BLOCK(ip, nfreed);
7106         /* update quota allocation to reflect freed blocks */
7107         DQUOT_FREE_BLOCK(ip, nfreed);
7108  
7109 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/namei.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/namei.c
7110 --- linux-2.6.19.1/fs/jfs/namei.c       2006-11-30 21:19:26 +0100
7111 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/namei.c     2006-11-30 18:53:18 +0100
7112 @@ -20,6 +20,7 @@
7113  #include <linux/fs.h>
7114  #include <linux/ctype.h>
7115  #include <linux/quotaops.h>
7116 +#include <linux/vs_tag.h>
7117  #include "jfs_incore.h"
7118  #include "jfs_superblock.h"
7119  #include "jfs_inode.h"
7120 @@ -1461,6 +1462,7 @@ static struct dentry *jfs_lookup(struct 
7121                 return ERR_PTR(-EACCES);
7122         }
7123  
7124 +       dx_propagate_tag(nd, ip);
7125         dentry = d_splice_alias(ip, dentry);
7126  
7127         if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2))
7128 @@ -1513,6 +1515,7 @@ struct inode_operations jfs_dir_inode_op
7129         .setattr        = jfs_setattr,
7130         .permission     = jfs_permission,
7131  #endif
7132 +       .sync_flags     = jfs_sync_flags,
7133  };
7134  
7135  const struct file_operations jfs_dir_operations = {
7136 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/super.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/super.c
7137 --- linux-2.6.19.1/fs/jfs/super.c       2006-11-30 21:19:26 +0100
7138 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/super.c     2006-11-08 04:57:51 +0100
7139 @@ -194,7 +194,8 @@ static void jfs_put_super(struct super_b
7140  enum {
7141         Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
7142         Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
7143 -       Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask
7144 +       Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask,
7145 +       Opt_tag, Opt_notag, Opt_tagid
7146  };
7147  
7148  static match_table_t tokens = {
7149 @@ -204,6 +205,10 @@ static match_table_t tokens = {
7150         {Opt_resize, "resize=%u"},
7151         {Opt_resize_nosize, "resize"},
7152         {Opt_errors, "errors=%s"},
7153 +       {Opt_tag, "tag"},
7154 +       {Opt_notag, "notag"},
7155 +       {Opt_tagid, "tagid=%u"},
7156 +       {Opt_tag, "tagxid"},
7157         {Opt_ignore, "noquota"},
7158         {Opt_ignore, "quota"},
7159         {Opt_usrquota, "usrquota"},
7160 @@ -338,6 +343,20 @@ static int parse_options(char *options, 
7161                         }
7162                         break;
7163                 }
7164 +#ifndef CONFIG_TAGGING_NONE
7165 +               case Opt_tag:
7166 +                       *flag |= JFS_TAGGED;
7167 +                       break;
7168 +               case Opt_notag:
7169 +                       *flag &= JFS_TAGGED;
7170 +                       break;
7171 +#endif
7172 +#ifdef CONFIG_PROPAGATE
7173 +               case Opt_tagid:
7174 +                       /* use args[0] */
7175 +                       *flag |= JFS_TAGGED;
7176 +                       break;
7177 +#endif
7178                 default:
7179                         printk("jfs: Unrecognized mount option \"%s\" "
7180                                         " or missing value\n", p);
7181 @@ -368,6 +387,13 @@ static int jfs_remount(struct super_bloc
7182         if (!parse_options(data, sb, &newLVSize, &flag)) {
7183                 return -EINVAL;
7184         }
7185 +
7186 +       if ((flag & JFS_TAGGED) && !(sb->s_flags & MS_TAGGED)) {
7187 +               printk(KERN_ERR "JFS: %s: tagging not permitted on remount.\n",
7188 +                       sb->s_id);
7189 +               return -EINVAL;
7190 +       }
7191 +
7192         if (newLVSize) {
7193                 if (sb->s_flags & MS_RDONLY) {
7194                         printk(KERN_ERR
7195 @@ -439,6 +465,9 @@ static int jfs_fill_super(struct super_b
7196  #ifdef CONFIG_JFS_POSIX_ACL
7197         sb->s_flags |= MS_POSIXACL;
7198  #endif
7199 +       /* map mount option tagxid */
7200 +       if (sbi->flag & JFS_TAGGED)
7201 +               sb->s_flags |= MS_TAGGED;
7202  
7203         if (newLVSize) {
7204                 printk(KERN_ERR "resize option for remount only\n");
7205 @@ -615,10 +644,11 @@ static int jfs_show_options(struct seq_f
7206   * acquiring the locks... As quota files are never truncated and quota code
7207   * itself serializes the operations (and noone else should touch the files)
7208   * we don't have to be afraid of races */
7209 -static ssize_t jfs_quota_read(struct super_block *sb, int type, char *data,
7210 +static ssize_t jfs_quota_read(struct dqhash *hash, int type, char *data,
7211                               size_t len, loff_t off)
7212  {
7213 -       struct inode *inode = sb_dqopt(sb)->files[type];
7214 +       struct inode *inode = dqh_dqopt(hash)->files[type];
7215 +       struct super_block *sb = hash->dqh_sb;
7216         sector_t blk = off >> sb->s_blocksize_bits;
7217         int err = 0;
7218         int offset = off & (sb->s_blocksize - 1);
7219 @@ -660,10 +690,11 @@ static ssize_t jfs_quota_read(struct sup
7220  }
7221  
7222  /* Write to quotafile */
7223 -static ssize_t jfs_quota_write(struct super_block *sb, int type,
7224 +static ssize_t jfs_quota_write(struct dqhash *hash, int type,
7225                                const char *data, size_t len, loff_t off)
7226  {
7227 -       struct inode *inode = sb_dqopt(sb)->files[type];
7228 +       struct inode *inode = dqh_dqopt(hash)->files[type];
7229 +       struct super_block *sb = hash->dqh_sb;
7230         sector_t blk = off >> sb->s_blocksize_bits;
7231         int err = 0;
7232         int offset = off & (sb->s_blocksize - 1);
7233 diff -NurpP --minimal linux-2.6.19.1/fs/jfs/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/jfs/xattr.c
7234 --- linux-2.6.19.1/fs/jfs/xattr.c       2006-11-30 21:19:26 +0100
7235 +++ linux-2.6.19.1-vs2.3.0.6/fs/jfs/xattr.c     2006-11-08 21:52:09 +0100
7236 @@ -23,6 +23,7 @@
7237  #include <linux/posix_acl_xattr.h>
7238  #include <linux/quotaops.h>
7239  #include <linux/security.h>
7240 +#include <linux/vs_dlimit.h>
7241  #include "jfs_incore.h"
7242  #include "jfs_superblock.h"
7243  #include "jfs_dmap.h"
7244 @@ -263,9 +264,16 @@ static int ea_write(struct inode *ip, st
7245         if (DQUOT_ALLOC_BLOCK(ip, nblocks)) {
7246                 return -EDQUOT;
7247         }
7248 +       /* Allocate new blocks to dlimit. */
7249 +       if (DLIMIT_ALLOC_BLOCK(ip, nblocks)) {
7250 +               DQUOT_FREE_BLOCK(ip, nblocks);
7251 +               return -ENOSPC;
7252 +       }
7253  
7254         rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno);
7255         if (rc) {
7256 +               /*Rollback dlimit allocation. */
7257 +               DLIMIT_FREE_BLOCK(ip, nblocks);
7258                 /*Rollback quota allocation. */
7259                 DQUOT_FREE_BLOCK(ip, nblocks);
7260                 return rc;
7261 @@ -332,6 +340,8 @@ static int ea_write(struct inode *ip, st
7262  
7263        failed:
7264         /* Rollback quota allocation. */
7265 +       DLIMIT_FREE_BLOCK(ip, nblocks);
7266 +       /* Rollback quota allocation. */
7267         DQUOT_FREE_BLOCK(ip, nblocks);
7268  
7269         dbFree(ip, blkno, nblocks);
7270 @@ -468,6 +478,7 @@ static int ea_get(struct inode *inode, s
7271         s64 blkno;
7272         int rc;
7273         int quota_allocation = 0;
7274 +       int dlimit_allocation = 0;
7275  
7276         /* When fsck.jfs clears a bad ea, it doesn't clear the size */
7277         if (ji->ea.flag == 0)
7278 @@ -543,6 +554,12 @@ static int ea_get(struct inode *inode, s
7279  
7280                 quota_allocation = blocks_needed;
7281  
7282 +               /* Allocate new blocks to dlimit. */
7283 +               rc = -ENOSPC;
7284 +               if (DLIMIT_ALLOC_BLOCK(inode, blocks_needed))
7285 +                       goto clean_up;
7286 +               dlimit_allocation = blocks_needed;
7287 +
7288                 rc = dbAlloc(inode, INOHINT(inode), (s64) blocks_needed,
7289                              &blkno);
7290                 if (rc)
7291 @@ -599,6 +616,9 @@ static int ea_get(struct inode *inode, s
7292         return ea_size;
7293  
7294        clean_up:
7295 +       /* Rollback dlimit allocation */
7296 +       if (dlimit_allocation)
7297 +               DLIMIT_FREE_BLOCK(inode, dlimit_allocation);
7298         /* Rollback quota allocation */
7299         if (quota_allocation)
7300                 DQUOT_FREE_BLOCK(inode, quota_allocation);
7301 @@ -675,8 +695,10 @@ static int ea_put(tid_t tid, struct inod
7302         }
7303  
7304         /* If old blocks exist, they must be removed from quota allocation. */
7305 -       if (old_blocks)
7306 +       if (old_blocks) {
7307 +               DLIMIT_FREE_BLOCK(inode, old_blocks);
7308                 DQUOT_FREE_BLOCK(inode, old_blocks);
7309 +       }
7310  
7311         inode->i_ctime = CURRENT_TIME;
7312  
7313 diff -NurpP --minimal linux-2.6.19.1/fs/libfs.c linux-2.6.19.1-vs2.3.0.6/fs/libfs.c
7314 --- linux-2.6.19.1/fs/libfs.c   2006-11-30 21:19:26 +0100
7315 +++ linux-2.6.19.1-vs2.3.0.6/fs/libfs.c 2006-11-08 04:57:43 +0100
7316 @@ -124,7 +124,8 @@ static inline unsigned char dt_type(stru
7317   * both impossible due to the lock on directory.
7318   */
7319  
7320 -int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
7321 +static inline int do_dcache_readdir_filter(struct file * filp,
7322 +       void * dirent, filldir_t filldir, int (*filter)(struct dentry *dentry))
7323  {
7324         struct dentry *dentry = filp->f_dentry;
7325         struct dentry *cursor = filp->private_data;
7326 @@ -157,6 +158,8 @@ int dcache_readdir(struct file * filp, v
7327                                 next = list_entry(p, struct dentry, d_u.d_child);
7328                                 if (d_unhashed(next) || !next->d_inode)
7329                                         continue;
7330 +                               if (filter && !filter(next))
7331 +                                       continue;
7332  
7333                                 spin_unlock(&dcache_lock);
7334                                 if (filldir(dirent, next->d_name.name, next->d_name.len, filp->f_pos, next->d_inode->i_ino, dt_type(next->d_inode)) < 0)
7335 @@ -172,6 +175,18 @@ int dcache_readdir(struct file * filp, v
7336         return 0;
7337  }
7338  
7339 +int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
7340 +{
7341 +       return do_dcache_readdir_filter(filp, dirent, filldir, NULL);
7342 +}
7343 +
7344 +int dcache_readdir_filter(struct file * filp, void * dirent, filldir_t filldir,
7345 +       int (*filter)(struct dentry *))
7346 +{
7347 +       return do_dcache_readdir_filter(filp, dirent, filldir, filter);
7348 +}
7349 +
7350 +
7351  ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos)
7352  {
7353         return -EISDIR;
7354 @@ -611,6 +626,7 @@ EXPORT_SYMBOL(dcache_dir_close);
7355  EXPORT_SYMBOL(dcache_dir_lseek);
7356  EXPORT_SYMBOL(dcache_dir_open);
7357  EXPORT_SYMBOL(dcache_readdir);
7358 +EXPORT_SYMBOL(dcache_readdir_filter);
7359  EXPORT_SYMBOL(generic_read_dir);
7360  EXPORT_SYMBOL(get_sb_pseudo);
7361  EXPORT_SYMBOL(simple_commit_write);
7362 diff -NurpP --minimal linux-2.6.19.1/fs/locks.c linux-2.6.19.1-vs2.3.0.6/fs/locks.c
7363 --- linux-2.6.19.1/fs/locks.c   2006-11-30 21:19:26 +0100
7364 +++ linux-2.6.19.1-vs2.3.0.6/fs/locks.c 2006-11-30 18:53:18 +0100
7365 @@ -125,6 +125,8 @@
7366  #include <linux/syscalls.h>
7367  #include <linux/time.h>
7368  #include <linux/rcupdate.h>
7369 +#include <linux/vs_base.h>
7370 +#include <linux/vs_limit.h>
7371  
7372  #include <asm/semaphore.h>
7373  #include <asm/uaccess.h>
7374 @@ -147,6 +149,8 @@ static kmem_cache_t *filelock_cache __re
7375  /* Allocate an empty lock structure. */
7376  static struct file_lock *locks_alloc_lock(void)
7377  {
7378 +       if (!vx_locks_avail(1))
7379 +               return NULL;
7380         return kmem_cache_alloc(filelock_cache, SLAB_KERNEL);
7381  }
7382  
7383 @@ -172,6 +176,7 @@ static void locks_free_lock(struct file_
7384         BUG_ON(!list_empty(&fl->fl_block));
7385         BUG_ON(!list_empty(&fl->fl_link));
7386  
7387 +       vx_locks_dec(fl);
7388         locks_release_private(fl);
7389         kmem_cache_free(filelock_cache, fl);
7390  }
7391 @@ -191,6 +196,7 @@ void locks_init_lock(struct file_lock *f
7392         fl->fl_start = fl->fl_end = 0;
7393         fl->fl_ops = NULL;
7394         fl->fl_lmops = NULL;
7395 +       fl->fl_xid = -1;
7396  }
7397  
7398  EXPORT_SYMBOL(locks_init_lock);
7399 @@ -248,6 +254,7 @@ void locks_copy_lock(struct file_lock *n
7400         new->fl_file = fl->fl_file;
7401         new->fl_ops = fl->fl_ops;
7402         new->fl_lmops = fl->fl_lmops;
7403 +       new->fl_xid = fl->fl_xid;
7404  
7405         locks_copy_private(new, fl);
7406  }
7407 @@ -286,6 +293,11 @@ static int flock_make_lock(struct file *
7408         fl->fl_flags = FL_FLOCK;
7409         fl->fl_type = type;
7410         fl->fl_end = OFFSET_MAX;
7411 +
7412 +       vxd_assert(filp->f_xid == vx_current_xid(),
7413 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
7414 +       fl->fl_xid = filp->f_xid;
7415 +       vx_locks_inc(fl);
7416         
7417         *lock = fl;
7418         return 0;
7419 @@ -451,6 +463,7 @@ static int lease_init(struct file *filp,
7420  
7421         fl->fl_owner = current->files;
7422         fl->fl_pid = current->tgid;
7423 +       fl->fl_xid = vx_current_xid();
7424  
7425         fl->fl_file = filp;
7426         fl->fl_flags = FL_LEASE;
7427 @@ -470,6 +483,11 @@ static int lease_alloc(struct file *filp
7428         if (fl == NULL)
7429                 goto out;
7430  
7431 +       fl->fl_xid = vx_current_xid();
7432 +       if (filp)
7433 +               vxd_assert(filp->f_xid == fl->fl_xid,
7434 +                       "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid);
7435 +       vx_locks_inc(fl);
7436         error = lease_init(filp, type, fl);
7437         if (error) {
7438                 locks_free_lock(fl);
7439 @@ -790,6 +808,7 @@ find_conflict:
7440         if (request->fl_flags & FL_ACCESS)
7441                 goto out;
7442         locks_copy_lock(new_fl, request);
7443 +       vx_locks_inc(new_fl);
7444         locks_insert_lock(&inode->i_flock, new_fl);
7445         new_fl = NULL;
7446         error = 0;
7447 @@ -801,7 +820,8 @@ out:
7448         return error;
7449  }
7450  
7451 -static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
7452 +static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request,
7453 +       struct file_lock *conflock, xid_t xid)
7454  {
7455         struct file_lock *fl;
7456         struct file_lock *new_fl = NULL;
7457 @@ -811,6 +831,8 @@ static int __posix_lock_file_conf(struct
7458         struct file_lock **before;
7459         int error, added = 0;
7460  
7461 +       vxd_assert(xid == vx_current_xid(),
7462 +               "xid(%d) == current(%d)", xid, vx_current_xid());
7463         /*
7464          * We may need two file_lock structures for this operation,
7465          * so we get them in advance to avoid races.
7466 @@ -821,7 +843,11 @@ static int __posix_lock_file_conf(struct
7467             (request->fl_type != F_UNLCK ||
7468              request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
7469                 new_fl = locks_alloc_lock();
7470 +               new_fl->fl_xid = xid;
7471 +               vx_locks_inc(new_fl);
7472                 new_fl2 = locks_alloc_lock();
7473 +               new_fl2->fl_xid = xid;
7474 +               vx_locks_inc(new_fl2);
7475         }
7476  
7477         lock_kernel();
7478 @@ -1018,7 +1044,8 @@ static int __posix_lock_file_conf(struct
7479   */
7480  int posix_lock_file(struct file *filp, struct file_lock *fl)
7481  {
7482 -       return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, NULL);
7483 +       return __posix_lock_file_conf(filp->f_dentry->d_inode,
7484 +               fl, NULL, filp->f_xid);
7485  }
7486  EXPORT_SYMBOL(posix_lock_file);
7487  
7488 @@ -1033,7 +1060,8 @@ EXPORT_SYMBOL(posix_lock_file);
7489  int posix_lock_file_conf(struct file *filp, struct file_lock *fl,
7490                         struct file_lock *conflock)
7491  {
7492 -       return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, conflock);
7493 +       return __posix_lock_file_conf(filp->f_dentry->d_inode,
7494 +               fl, conflock, filp->f_xid);
7495  }
7496  EXPORT_SYMBOL(posix_lock_file_conf);
7497  
7498 @@ -1123,7 +1151,7 @@ int locks_mandatory_area(int read_write,
7499         fl.fl_end = offset + count - 1;
7500  
7501         for (;;) {
7502 -               error = __posix_lock_file_conf(inode, &fl, NULL);
7503 +               error = __posix_lock_file_conf(inode, &fl, NULL, filp->f_xid);
7504                 if (error != -EAGAIN)
7505                         break;
7506                 if (!(fl.fl_flags & FL_SLEEP))
7507 @@ -1685,6 +1713,11 @@ int fcntl_setlk(unsigned int fd, struct 
7508         if (file_lock == NULL)
7509                 return -ENOLCK;
7510  
7511 +       vxd_assert(filp->f_xid == vx_current_xid(),
7512 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
7513 +       file_lock->fl_xid = filp->f_xid;
7514 +       vx_locks_inc(file_lock);
7515 +
7516         /*
7517          * This might block, so we do it before checking the inode.
7518          */
7519 @@ -1828,6 +1861,11 @@ int fcntl_setlk64(unsigned int fd, struc
7520         if (file_lock == NULL)
7521                 return -ENOLCK;
7522  
7523 +       vxd_assert(filp->f_xid == vx_current_xid(),
7524 +               "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid());
7525 +       file_lock->fl_xid = filp->f_xid;
7526 +       vx_locks_inc(file_lock);
7527 +
7528         /*
7529          * This might block, so we do it before checking the inode.
7530          */
7531 @@ -2123,6 +2161,10 @@ int get_locks_status(char *buffer, char 
7532         list_for_each(tmp, &file_lock_list) {
7533                 struct list_head *btmp;
7534                 struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
7535 +
7536 +               if (!vx_check(fl->fl_xid, VS_WATCH_P|VS_IDENT))
7537 +                       continue;
7538 +
7539                 lock_get_status(q, fl, ++i, "");
7540                 move_lock_status(&q, &pos, offset);
7541  
7542 diff -NurpP --minimal linux-2.6.19.1/fs/namei.c linux-2.6.19.1-vs2.3.0.6/fs/namei.c
7543 --- linux-2.6.19.1/fs/namei.c   2006-11-30 21:19:26 +0100
7544 +++ linux-2.6.19.1-vs2.3.0.6/fs/namei.c 2006-11-30 19:41:35 +0100
7545 @@ -32,6 +32,11 @@
7546  #include <linux/file.h>
7547  #include <linux/fcntl.h>
7548  #include <linux/namei.h>
7549 +#include <linux/proc_fs.h>
7550 +#include <linux/vserver/inode.h>
7551 +#include <linux/vs_base.h>
7552 +#include <linux/vs_tag.h>
7553 +#include <linux/vs_cowbl.h>
7554  #include <asm/namei.h>
7555  #include <asm/uaccess.h>
7556  
7557 @@ -225,6 +230,31 @@ int generic_permission(struct inode *ino
7558         return -EACCES;
7559  }
7560  
7561 +static inline int dx_barrier(struct inode *inode)
7562 +{
7563 +       if (IS_BARRIER(inode) && !vx_check(0, VS_ADMIN)) {
7564 +               vxwprintk(1, "xid=%d did hit the barrier.",
7565 +                       vx_current_xid());
7566 +               return 1;
7567 +       }
7568 +       return 0;
7569 +}
7570 +
7571 +static inline int dx_permission(struct inode *inode, int mask, struct nameidata *nd)
7572 +{
7573 +       if (dx_barrier(inode))
7574 +               return -EACCES;
7575 +       if (inode->i_tag == 0)
7576 +               return 0;
7577 +       if (dx_check(inode->i_tag, DX_ADMIN|DX_WATCH|DX_IDENT))
7578 +               return 0;
7579 +
7580 +       vxwprintk(1, "xid=%d denied access to %p[#%d,%lu] »%s«.",
7581 +               vx_current_xid(), inode, inode->i_tag, inode->i_ino,
7582 +               vxd_cond_path(nd));
7583 +       return -EACCES;
7584 +}
7585 +
7586  int permission(struct inode *inode, int mask, struct nameidata *nd)
7587  {
7588         umode_t mode = inode->i_mode;
7589 @@ -235,14 +265,14 @@ int permission(struct inode *inode, int 
7590                 /*
7591                  * Nobody gets write access to a read-only fs.
7592                  */
7593 -               if (IS_RDONLY(inode) &&
7594 +               if ((IS_RDONLY(inode) || (nd && MNT_IS_RDONLY(nd->mnt))) &&
7595                     (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
7596                         return -EROFS;
7597  
7598                 /*
7599                  * Nobody gets write access to an immutable file.
7600                  */
7601 -               if (IS_IMMUTABLE(inode))
7602 +               if (IS_IMMUTABLE(inode) && !IS_COW(inode))
7603                         return -EACCES;
7604         }
7605  
7606 @@ -256,6 +286,8 @@ int permission(struct inode *inode, int 
7607  
7608         /* Ordinary permission routines do not understand MAY_APPEND. */
7609         submask = mask & ~MAY_APPEND;
7610 +       if ((retval = dx_permission(inode, mask, nd)))
7611 +               return retval;
7612         if (inode->i_op && inode->i_op->permission)
7613                 retval = inode->i_op->permission(inode, submask, nd);
7614         else
7615 @@ -431,6 +463,8 @@ static int exec_permission_lite(struct i
7616  {
7617         umode_t mode = inode->i_mode;
7618  
7619 +       if (dx_barrier(inode))
7620 +               return -EACCES;
7621         if (inode->i_op && inode->i_op->permission)
7622                 return -EAGAIN;
7623  
7624 @@ -736,7 +770,8 @@ static __always_inline void follow_dotdo
7625                 if (nd->dentry == fs->root &&
7626                     nd->mnt == fs->rootmnt) {
7627                          read_unlock(&fs->lock);
7628 -                       break;
7629 +                       /* FIXME: for sane '/' avoid follow_mount() */
7630 +                       return;
7631                 }
7632                  read_unlock(&fs->lock);
7633                 spin_lock(&dcache_lock);
7634 @@ -773,16 +808,34 @@ static int do_lookup(struct nameidata *n
7635  {
7636         struct vfsmount *mnt = nd->mnt;
7637         struct dentry *dentry = __d_lookup(nd->dentry, name);
7638 +       struct inode *inode;
7639  
7640         if (!dentry)
7641                 goto need_lookup;
7642         if (dentry->d_op && dentry->d_op->d_revalidate)
7643                 goto need_revalidate;
7644 +       inode = dentry->d_inode;
7645 +       if (!inode)
7646 +               goto done;
7647 +       if (inode->i_sb->s_magic == PROC_SUPER_MAGIC) {
7648 +               struct proc_dir_entry *de = PDE(inode);
7649 +
7650 +               if (de && !vx_hide_check(0, de->vx_flags))
7651 +                       goto hidden;
7652 +       }
7653 +       if (!dx_check(inode->i_tag, DX_WATCH|DX_ADMIN|DX_HOSTID|DX_IDENT))
7654 +               goto hidden;
7655  done:
7656         path->mnt = mnt;
7657         path->dentry = dentry;
7658         __follow_mount(path);
7659         return 0;
7660 +hidden:
7661 +       vxwprintk(1, "xid=%d did lookup hidden %p[#%d,%lu] »%s«.",
7662 +               vx_current_xid(), inode, inode->i_tag, inode->i_ino,
7663 +               vxd_path(dentry, mnt));
7664 +       dput(dentry);
7665 +       return -ENOENT;
7666  
7667  need_lookup:
7668         dentry = real_lookup(nd->dentry, name, nd);
7669 @@ -1384,7 +1437,8 @@ static inline int check_sticky(struct in
7670   * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
7671   *     nfs_async_unlink().
7672   */
7673 -static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
7674 +static int may_delete(struct inode *dir, struct dentry *victim,
7675 +       int isdir, struct nameidata *nd)
7676  {
7677         int error;
7678  
7679 @@ -1394,13 +1448,13 @@ static int may_delete(struct inode *dir,
7680         BUG_ON(victim->d_parent->d_inode != dir);
7681         audit_inode_child(victim->d_name.name, victim->d_inode, dir);
7682  
7683 -       error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
7684 +       error = permission(dir,MAY_WRITE | MAY_EXEC, nd);
7685         if (error)
7686                 return error;
7687         if (IS_APPEND(dir))
7688                 return -EPERM;
7689         if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
7690 -           IS_IMMUTABLE(victim->d_inode))
7691 +               IS_IXORUNLINK(victim->d_inode))
7692                 return -EPERM;
7693         if (isdir) {
7694                 if (!S_ISDIR(victim->d_inode->i_mode))
7695 @@ -1531,6 +1585,14 @@ int may_open(struct nameidata *nd, int a
7696         if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
7697                 return -EISDIR;
7698  
7699 +#ifdef CONFIG_VSERVER_COWBL
7700 +       if (IS_COW(inode) && (flag & FMODE_WRITE)) {
7701 +               if (IS_COW_LINK(inode))
7702 +                       return -EMLINK;
7703 +               inode->i_flags &= ~(S_IUNLINK|S_IMMUTABLE);
7704 +               mark_inode_dirty(inode);
7705 +       }
7706 +#endif
7707         error = vfs_permission(nd, acc_mode);
7708         if (error)
7709                 return error;
7710 @@ -1547,7 +1609,8 @@ int may_open(struct nameidata *nd, int a
7711                         return -EACCES;
7712  
7713                 flag &= ~O_TRUNC;
7714 -       } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE))
7715 +       } else if ((IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
7716 +               && (flag & FMODE_WRITE))
7717                 return -EROFS;
7718         /*
7719          * An append-only file must be opened in append mode for writing.
7720 @@ -1635,6 +1698,11 @@ int open_namei(int dfd, const char *path
7721         struct dentry *dir;
7722         int count = 0;
7723  
7724 +#ifdef CONFIG_VSERVER_COWBL
7725 +       int rflag = flag;
7726 +       int rmode = mode;
7727 +restart:
7728 +#endif
7729         acc_mode = ACC_MODE(flag);
7730  
7731         /* O_TRUNC implies we need access checks for write permissions */
7732 @@ -1728,6 +1796,22 @@ do_last:
7733                 goto exit;
7734  ok:
7735         error = may_open(nd, acc_mode, flag);
7736 +#ifdef CONFIG_VSERVER_COWBL
7737 +       if (error == -EMLINK) {
7738 +               struct dentry *dentry;
7739 +               dentry = cow_break_link(pathname);
7740 +               if (IS_ERR(dentry)) {
7741 +                       error = PTR_ERR(dentry);
7742 +                       goto exit;
7743 +               }
7744 +               dput(dentry);
7745 +               release_open_intent(nd);
7746 +               path_release(nd);
7747 +               flag = rflag;
7748 +               mode = rmode;
7749 +               goto restart;
7750 +       }
7751 +#endif
7752         if (error)
7753                 goto exit;
7754         return 0;
7755 @@ -1839,9 +1923,10 @@ fail:
7756  }
7757  EXPORT_SYMBOL_GPL(lookup_create);
7758  
7759 -int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
7760 +int vfs_mknod(struct inode *dir, struct dentry *dentry,
7761 +       int mode, dev_t dev, struct nameidata *nd)
7762  {
7763 -       int error = may_create(dir, dentry, NULL);
7764 +       int error = may_create(dir, dentry, nd);
7765  
7766         if (error)
7767                 return error;
7768 @@ -1891,11 +1976,12 @@ asmlinkage long sys_mknodat(int dfd, con
7769                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
7770                         break;
7771                 case S_IFCHR: case S_IFBLK:
7772 -                       error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
7773 -                                       new_decode_dev(dev));
7774 +                       error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
7775 +                                       new_decode_dev(dev), &nd);
7776                         break;
7777                 case S_IFIFO: case S_IFSOCK:
7778 -                       error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
7779 +                       error = vfs_mknod(nd.dentry->d_inode, dentry, mode,
7780 +                                       0, &nd);
7781                         break;
7782                 case S_IFDIR:
7783                         error = -EPERM;
7784 @@ -1918,9 +2004,10 @@ asmlinkage long sys_mknod(const char __u
7785         return sys_mknodat(AT_FDCWD, filename, mode, dev);
7786  }
7787  
7788 -int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
7789 +int vfs_mkdir(struct inode *dir, struct dentry *dentry,
7790 +       int mode, struct nameidata *nd)
7791  {
7792 -       int error = may_create(dir, dentry, NULL);
7793 +       int error = may_create(dir, dentry, nd);
7794  
7795         if (error)
7796                 return error;
7797 @@ -1962,7 +2049,7 @@ asmlinkage long sys_mkdirat(int dfd, con
7798  
7799         if (!IS_POSIXACL(nd.dentry->d_inode))
7800                 mode &= ~current->fs->umask;
7801 -       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
7802 +       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode, &nd);
7803         dput(dentry);
7804  out_unlock:
7805         mutex_unlock(&nd.dentry->d_inode->i_mutex);
7806 @@ -2006,9 +2093,10 @@ void dentry_unhash(struct dentry *dentry
7807         spin_unlock(&dcache_lock);
7808  }
7809  
7810 -int vfs_rmdir(struct inode *dir, struct dentry *dentry)
7811 +int vfs_rmdir(struct inode *dir, struct dentry *dentry,
7812 +       struct nameidata *nd)
7813  {
7814 -       int error = may_delete(dir, dentry, 1);
7815 +       int error = may_delete(dir, dentry, 1, nd);
7816  
7817         if (error)
7818                 return error;
7819 @@ -2070,7 +2158,7 @@ static long do_rmdir(int dfd, const char
7820         error = PTR_ERR(dentry);
7821         if (IS_ERR(dentry))
7822                 goto exit2;
7823 -       error = vfs_rmdir(nd.dentry->d_inode, dentry);
7824 +       error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
7825         dput(dentry);
7826  exit2:
7827         mutex_unlock(&nd.dentry->d_inode->i_mutex);
7828 @@ -2086,9 +2174,10 @@ asmlinkage long sys_rmdir(const char __u
7829         return do_rmdir(AT_FDCWD, pathname);
7830  }
7831  
7832 -int vfs_unlink(struct inode *dir, struct dentry *dentry)
7833 +int vfs_unlink(struct inode *dir, struct dentry *dentry,
7834 +       struct nameidata *nd)
7835  {
7836 -       int error = may_delete(dir, dentry, 0);
7837 +       int error = may_delete(dir, dentry, 0, nd);
7838  
7839         if (error)
7840                 return error;
7841 @@ -2150,7 +2239,7 @@ static long do_unlinkat(int dfd, const c
7842                 inode = dentry->d_inode;
7843                 if (inode)
7844                         atomic_inc(&inode->i_count);
7845 -               error = vfs_unlink(nd.dentry->d_inode, dentry);
7846 +               error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
7847         exit2:
7848                 dput(dentry);
7849         }
7850 @@ -2185,9 +2274,10 @@ asmlinkage long sys_unlink(const char __
7851         return do_unlinkat(AT_FDCWD, pathname);
7852  }
7853  
7854 -int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
7855 +int vfs_symlink(struct inode *dir, struct dentry *dentry,
7856 +       const char *oldname, int mode, struct nameidata *nd)
7857  {
7858 -       int error = may_create(dir, dentry, NULL);
7859 +       int error = may_create(dir, dentry, nd);
7860  
7861         if (error)
7862                 return error;
7863 @@ -2231,7 +2321,7 @@ asmlinkage long sys_symlinkat(const char
7864         if (IS_ERR(dentry))
7865                 goto out_unlock;
7866  
7867 -       error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
7868 +       error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO, &nd);
7869         dput(dentry);
7870  out_unlock:
7871         mutex_unlock(&nd.dentry->d_inode->i_mutex);
7872 @@ -2248,7 +2338,8 @@ asmlinkage long sys_symlink(const char _
7873         return sys_symlinkat(oldname, AT_FDCWD, newname);
7874  }
7875  
7876 -int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
7877 +int vfs_link(struct dentry *old_dentry, struct inode *dir,
7878 +       struct dentry *new_dentry, struct nameidata *nd)
7879  {
7880         struct inode *inode = old_dentry->d_inode;
7881         int error;
7882 @@ -2256,7 +2347,7 @@ int vfs_link(struct dentry *old_dentry, 
7883         if (!inode)
7884                 return -ENOENT;
7885  
7886 -       error = may_create(dir, new_dentry, NULL);
7887 +       error = may_create(dir, new_dentry, nd);
7888         if (error)
7889                 return error;
7890  
7891 @@ -2266,7 +2357,7 @@ int vfs_link(struct dentry *old_dentry, 
7892         /*
7893          * A link to an append-only or immutable file cannot be created.
7894          */
7895 -       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
7896 +       if (IS_APPEND(inode) || IS_IXORUNLINK(inode))
7897                 return -EPERM;
7898         if (!dir->i_op || !dir->i_op->link)
7899                 return -EPERM;
7900 @@ -2326,7 +2417,7 @@ asmlinkage long sys_linkat(int olddfd, c
7901         error = PTR_ERR(new_dentry);
7902         if (IS_ERR(new_dentry))
7903                 goto out_unlock;
7904 -       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
7905 +       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry, &nd);
7906         dput(new_dentry);
7907  out_unlock:
7908         mutex_unlock(&nd.dentry->d_inode->i_mutex);
7909 @@ -2458,14 +2549,14 @@ int vfs_rename(struct inode *old_dir, st
7910         if (old_dentry->d_inode == new_dentry->d_inode)
7911                 return 0;
7912   
7913 -       error = may_delete(old_dir, old_dentry, is_dir);
7914 +       error = may_delete(old_dir, old_dentry, is_dir, NULL);
7915         if (error)
7916                 return error;
7917  
7918         if (!new_dentry->d_inode)
7919                 error = may_create(new_dir, new_dentry, NULL);
7920         else
7921 -               error = may_delete(new_dir, new_dentry, is_dir);
7922 +               error = may_delete(new_dir, new_dentry, is_dir, NULL);
7923         if (error)
7924                 return error;
7925  
7926 @@ -2543,6 +2634,9 @@ static int do_rename(int olddfd, const c
7927         error = -EINVAL;
7928         if (old_dentry == trap)
7929                 goto exit4;
7930 +       error = -EROFS;
7931 +       if (MNT_IS_RDONLY(newnd.mnt))
7932 +               goto exit4;
7933         new_dentry = lookup_hash(&newnd);
7934         error = PTR_ERR(new_dentry);
7935         if (IS_ERR(new_dentry))
7936 @@ -2636,6 +2730,126 @@ int vfs_follow_link(struct nameidata *nd
7937         return __vfs_follow_link(nd, link);
7938  }
7939  
7940 +
7941 +#ifdef CONFIG_VSERVER_COWBL
7942 +
7943 +#include <linux/file.h>
7944 +
7945 +struct dentry *cow_break_link(const char *pathname)
7946 +{
7947 +       int ret, mode, pathlen;
7948 +       struct nameidata old_nd, dir_nd;
7949 +       struct dentry *old_dentry, *new_dentry;
7950 +       struct dentry *res = ERR_PTR(-EMLINK);
7951 +       struct vfsmount *old_mnt, *new_mnt;
7952 +       struct file *old_file;
7953 +       struct file *new_file;
7954 +       char *to, *path, pad='\251';
7955 +       loff_t size;
7956 +
7957 +       vxdprintk(VXD_CBIT(misc, 1), "cow_break_link(»%s«)", pathname);
7958 +       path = kmalloc(PATH_MAX, GFP_KERNEL);
7959 +
7960 +       ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd);
7961 +       vxdprintk(VXD_CBIT(misc, 2), "path_lookup(old): %d", ret);
7962 +       old_dentry = old_nd.dentry;
7963 +       old_mnt = old_nd.mnt;
7964 +       mode = old_dentry->d_inode->i_mode;
7965 +
7966 +       to = d_path(old_dentry, old_mnt, path, PATH_MAX-2);
7967 +       pathlen = strlen(to);
7968 +       vxdprintk(VXD_CBIT(misc, 2), "old path »%s«", to);
7969 +
7970 +       to[pathlen+1] = 0;
7971 +retry:
7972 +       to[pathlen] = pad--;
7973 +       if (pad <= '\240')
7974 +               goto out_rel_old;
7975 +
7976 +       vxdprintk(VXD_CBIT(misc, 1), "temp copy »%s«", to);
7977 +       ret = path_lookup(to,
7978 +               LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, &dir_nd);
7979 +
7980 +       /* this puppy downs the inode sem */
7981 +       new_dentry = lookup_create(&dir_nd, 0);
7982 +       vxdprintk(VXD_CBIT(misc, 2),
7983 +               "lookup_create(new): %p", new_dentry);
7984 +       if (!new_dentry) {
7985 +               path_release(&dir_nd);
7986 +               goto retry;
7987 +       }
7988 +
7989 +       ret = vfs_create(dir_nd.dentry->d_inode, new_dentry, mode, &dir_nd);
7990 +       vxdprintk(VXD_CBIT(misc, 2),
7991 +               "vfs_create(new): %d", ret);
7992 +       if (ret == -EEXIST) {
7993 +
7994 +               mutex_unlock(&dir_nd.dentry->d_inode->i_mutex);
7995 +               dput(new_dentry);
7996 +               path_release(&dir_nd);
7997 +               goto retry;
7998 +       }
7999 +
8000 +       new_mnt = dir_nd.mnt;
8001 +
8002 +       dget(old_dentry);
8003 +       mntget(old_mnt);
8004 +       /* this one cleans up the dentry in case of failure */
8005 +       old_file = dentry_open(old_dentry, old_mnt, O_RDONLY);
8006 +       vxdprintk(VXD_CBIT(misc, 2),
8007 +               "dentry_open(old): %p", old_file);
8008 +       if (!old_file)
8009 +               goto out_rel_both;
8010 +
8011 +       dget(new_dentry);
8012 +       mntget(new_mnt);
8013 +       /* this one cleans up the dentry in case of failure */
8014 +       new_file = dentry_open(new_dentry, new_mnt, O_WRONLY);
8015 +       vxdprintk(VXD_CBIT(misc, 2),
8016 +               "dentry_open(new): %p", new_file);
8017 +       if (!new_file)
8018 +               goto out_fput_old;
8019 +
8020 +       size = i_size_read(old_file->f_dentry->d_inode);
8021 +       ret = vfs_sendfile(new_file, old_file, NULL, size, 0);
8022 +       vxdprintk(VXD_CBIT(misc, 2), "vfs_sendfile: %d", ret);
8023 +
8024 +       if (ret < 0)
8025 +               goto out_fput_both;
8026 +
8027 +       ret = vfs_rename(dir_nd.dentry->d_inode, new_dentry,
8028 +               old_nd.dentry->d_parent->d_inode, old_dentry);
8029 +       vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
8030 +       if (!ret) {
8031 +               res = new_dentry;
8032 +               dget(new_dentry);
8033 +       }
8034 +
8035 +out_fput_both:
8036 +       vxdprintk(VXD_CBIT(misc, 3),
8037 +               "fput(new_file=%p[#%d])", new_file,
8038 +               atomic_read(&new_file->f_count));
8039 +       fput(new_file);
8040 +
8041 +out_fput_old:
8042 +       vxdprintk(VXD_CBIT(misc, 3),
8043 +               "fput(old_file=%p[#%d])", old_file,
8044 +               atomic_read(&old_file->f_count));
8045 +       fput(old_file);
8046 +
8047 +out_rel_both:
8048 +       mutex_unlock(&dir_nd.dentry->d_inode->i_mutex);
8049 +       dput(new_dentry);
8050 +
8051 +       path_release(&dir_nd);
8052 +out_rel_old:
8053 +       path_release(&old_nd);
8054 +       kfree(path);
8055 +       return res;
8056 +}
8057 +
8058 +#endif
8059 +
8060  /* get the link contents into pagecache */
8061  static char *page_getlink(struct dentry * dentry, struct page **ppage)
8062  {
8063 diff -NurpP --minimal linux-2.6.19.1/fs/namespace.c linux-2.6.19.1-vs2.3.0.6/fs/namespace.c
8064 --- linux-2.6.19.1/fs/namespace.c       2006-11-30 21:19:26 +0100
8065 +++ linux-2.6.19.1-vs2.3.0.6/fs/namespace.c     2006-12-05 18:17:10 +0100
8066 @@ -25,6 +25,10 @@
8067  #include <linux/security.h>
8068  #include <linux/mount.h>
8069  #include <linux/ramfs.h>
8070 +#include <linux/vs_base.h>
8071 +#include <linux/vserver/space.h>
8072 +#include <linux/vs_context.h>
8073 +#include <linux/vs_tag.h>
8074  #include <asm/uaccess.h>
8075  #include <asm/unistd.h>
8076  #include "pnode.h"
8077 @@ -241,6 +245,7 @@ static struct vfsmount *clone_mnt(struct
8078                 mnt->mnt_root = dget(root);
8079                 mnt->mnt_mountpoint = mnt->mnt_root;
8080                 mnt->mnt_parent = mnt;
8081 +               mnt->mnt_tag = old->mnt_tag;
8082  
8083                 if (flag & CL_SLAVE) {
8084                         list_add(&mnt->mnt_slave, &old->mnt_slave_list);
8085 @@ -349,43 +354,85 @@ static inline void mangle(struct seq_fil
8086         seq_escape(m, s, " \t\n\\");
8087  }
8088  
8089 +static int mnt_is_reachable(struct vfsmount *mnt)
8090 +{
8091 +       struct vfsmount *root_mnt;
8092 +       struct dentry *root, *point;
8093 +       int ret;
8094 +
8095 +       if (mnt == mnt->mnt_namespace->root)
8096 +               return 1;
8097 +
8098 +       spin_lock(&dcache_lock);
8099 +       root_mnt = current->fs->rootmnt;
8100 +       root = current->fs->root;
8101 +       point = root;
8102 +
8103 +       while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) {
8104 +               point = mnt->mnt_mountpoint;
8105 +               mnt = mnt->mnt_parent;
8106 +       }
8107 +
8108 +       ret = (mnt == root_mnt) && is_subdir(point, root);
8109 +
8110 +       spin_unlock(&dcache_lock);
8111 +
8112 +       return ret;
8113 +}
8114 +
8115  static int show_vfsmnt(struct seq_file *m, void *v)
8116  {
8117         struct vfsmount *mnt = v;
8118         int err = 0;
8119         static struct proc_fs_info {
8120 -               int flag;
8121 -               char *str;
8122 +               int s_flag;
8123 +               int mnt_flag;
8124 +               char *set_str;
8125 +               char *unset_str;
8126         } fs_info[] = {
8127 -               { MS_SYNCHRONOUS, ",sync" },
8128 -               { MS_DIRSYNC, ",dirsync" },
8129 -               { MS_MANDLOCK, ",mand" },
8130 -               { 0, NULL }
8131 -       };
8132 -       static struct proc_fs_info mnt_info[] = {
8133 -               { MNT_NOSUID, ",nosuid" },
8134 -               { MNT_NODEV, ",nodev" },
8135 -               { MNT_NOEXEC, ",noexec" },
8136 -               { MNT_NOATIME, ",noatime" },
8137 -               { MNT_NODIRATIME, ",nodiratime" },
8138 -               { 0, NULL }
8139 +               { MS_RDONLY, MNT_RDONLY, "ro", "rw" },
8140 +               { MS_SYNCHRONOUS, 0, ",sync", NULL },
8141 +               { MS_DIRSYNC, 0, ",dirsync", NULL },
8142 +               { MS_MANDLOCK, 0, ",mand", NULL },
8143 +               { MS_TAGGED, 0, ",tag", NULL },
8144 +               { MS_NOATIME, MNT_NOATIME, ",noatime", NULL },
8145 +               { MS_NODIRATIME, MNT_NODIRATIME, ",nodiratime", NULL },
8146 +               { 0, MNT_NOSUID, ",nosuid", NULL },
8147 +               { 0, MNT_NODEV, ",nodev", NULL },
8148 +               { 0, MNT_NOEXEC, ",noexec", NULL },
8149 +               { 0, 0, NULL, NULL }
8150         };
8151 -       struct proc_fs_info *fs_infop;
8152 +       struct proc_fs_info *p;
8153 +       unsigned long s_flags = mnt->mnt_sb->s_flags;
8154 +       int mnt_flags = mnt->mnt_flags;
8155  
8156 -       mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
8157 -       seq_putc(m, ' ');
8158 -       seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
8159 -       seq_putc(m, ' ');
8160 -       mangle(m, mnt->mnt_sb->s_type->name);
8161 -       seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
8162 -       for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
8163 -               if (mnt->mnt_sb->s_flags & fs_infop->flag)
8164 -                       seq_puts(m, fs_infop->str);
8165 +       if (vx_flags(VXF_HIDE_MOUNT, 0))
8166 +               return 0;
8167 +       if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
8168 +               return 0;
8169 +
8170 +       if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
8171 +               mnt == current->fs->rootmnt) {
8172 +               seq_puts(m, "/dev/root / ");
8173 +       } else {
8174 +               mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
8175 +               seq_putc(m, ' ');
8176 +               seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
8177 +               seq_putc(m, ' ');
8178         }
8179 -       for (fs_infop = mnt_info; fs_infop->flag; fs_infop++) {
8180 -               if (mnt->mnt_flags & fs_infop->flag)
8181 -                       seq_puts(m, fs_infop->str);
8182 +       mangle(m, mnt->mnt_sb->s_type->name);
8183 +       seq_putc(m, ' ');
8184 +       for (p = fs_info; (p->s_flag | p->mnt_flag) ; p++) {
8185 +               if ((s_flags & p->s_flag) || (mnt_flags & p->mnt_flag)) {
8186 +                       if (p->set_str)
8187 +                               seq_puts(m, p->set_str);
8188 +               } else {
8189 +                       if (p->unset_str)
8190 +                               seq_puts(m, p->unset_str);
8191 +               }
8192         }
8193 +       if (mnt->mnt_flags & MNT_TAGID)
8194 +               seq_printf(m, ",tag=%d", mnt->mnt_tag);
8195         if (mnt->mnt_sb->s_op->show_options)
8196                 err = mnt->mnt_sb->s_op->show_options(m, mnt);
8197         seq_puts(m, " 0 0\n");
8198 @@ -404,17 +451,27 @@ static int show_vfsstat(struct seq_file 
8199         struct vfsmount *mnt = v;
8200         int err = 0;
8201  
8202 -       /* device */
8203 -       if (mnt->mnt_devname) {
8204 -               seq_puts(m, "device ");
8205 -               mangle(m, mnt->mnt_devname);
8206 -       } else
8207 -               seq_puts(m, "no device");
8208 +       if (vx_flags(VXF_HIDE_MOUNT, 0))
8209 +               return 0;
8210 +       if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P))
8211 +               return 0;
8212  
8213 -       /* mount point */
8214 -       seq_puts(m, " mounted on ");
8215 -       seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
8216 -       seq_putc(m, ' ');
8217 +       if (!vx_check(0, VS_ADMIN|VS_WATCH) &&
8218 +               mnt == current->fs->rootmnt) {
8219 +               seq_puts(m, "device /dev/root mounted on / ");
8220 +       } else {
8221 +               /* device */
8222 +               if (mnt->mnt_devname) {
8223 +                       seq_puts(m, "device ");
8224 +                       mangle(m, mnt->mnt_devname);
8225 +               } else
8226 +                       seq_puts(m, "no device");
8227 +
8228 +               /* mount point */
8229 +               seq_puts(m, " mounted on ");
8230 +               seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
8231 +               seq_putc(m, ' ');
8232 +       }
8233  
8234         /* file system type */
8235         seq_puts(m, "with fstype ");
8236 @@ -595,7 +652,7 @@ static int do_umount(struct vfsmount *mn
8237                 down_write(&sb->s_umount);
8238                 if (!(sb->s_flags & MS_RDONLY)) {
8239                         lock_kernel();
8240 -                       DQUOT_OFF(sb);
8241 +                       DQUOT_OFF(sb->s_dqh);
8242                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
8243                         unlock_kernel();
8244                 }
8245 @@ -644,7 +701,7 @@ asmlinkage long sys_umount(char __user *
8246                 goto dput_and_out;
8247  
8248         retval = -EPERM;
8249 -       if (!capable(CAP_SYS_ADMIN))
8250 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
8251                 goto dput_and_out;
8252  
8253         retval = do_umount(nd.mnt, flags);
8254 @@ -668,7 +725,7 @@ asmlinkage long sys_oldumount(char __use
8255  
8256  static int mount_is_safe(struct nameidata *nd)
8257  {
8258 -       if (capable(CAP_SYS_ADMIN))
8259 +       if (vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
8260                 return 0;
8261         return -EPERM;
8262  #ifdef notyet
8263 @@ -897,11 +954,13 @@ static int do_change_type(struct nameida
8264  /*
8265   * do loopback mount.
8266   */
8267 -static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
8268 +static int do_loopback(struct nameidata *nd, char *old_name, tag_t tag,
8269 +       unsigned long flags, int mnt_flags)
8270  {
8271         struct nameidata old_nd;
8272         struct vfsmount *mnt = NULL;
8273         int err = mount_is_safe(nd);
8274 +       int recurse = flags & MS_REC;
8275         if (err)
8276                 return err;
8277         if (!old_name || !*old_name)
8278 @@ -927,6 +986,12 @@ static int do_loopback(struct nameidata 
8279         if (!mnt)
8280                 goto out;
8281  
8282 +       mnt->mnt_flags = mnt_flags;
8283 +       if (flags & MS_TAGID) {
8284 +               mnt->mnt_tag = tag;
8285 +               mnt->mnt_flags |= MNT_TAGID;
8286 +       }
8287 +
8288         err = graft_tree(mnt, nd);
8289         if (err) {
8290                 LIST_HEAD(umount_list);
8291 @@ -935,6 +1000,7 @@ static int do_loopback(struct nameidata 
8292                 spin_unlock(&vfsmount_lock);
8293                 release_mounts(&umount_list);
8294         }
8295 +       mnt->mnt_flags = mnt_flags;
8296  
8297  out:
8298         up_write(&namespace_sem);
8299 @@ -948,12 +1014,12 @@ out:
8300   * on it - tough luck.
8301   */
8302  static int do_remount(struct nameidata *nd, int flags, int mnt_flags,
8303 -                     void *data)
8304 +                     void *data, xid_t xid)
8305  {
8306         int err;
8307         struct super_block *sb = nd->mnt->mnt_sb;
8308  
8309 -       if (!capable(CAP_SYS_ADMIN))
8310 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_REMOUNT))
8311                 return -EPERM;
8312  
8313         if (!check_mnt(nd->mnt))
8314 @@ -987,7 +1053,7 @@ static int do_move_mount(struct nameidat
8315         struct nameidata old_nd, parent_nd;
8316         struct vfsmount *p;
8317         int err = 0;
8318 -       if (!capable(CAP_SYS_ADMIN))
8319 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
8320                 return -EPERM;
8321         if (!old_name || !*old_name)
8322                 return -EINVAL;
8323 @@ -1067,7 +1133,7 @@ static int do_new_mount(struct nameidata
8324                 return -EINVAL;
8325  
8326         /* we need capabilities... */
8327 -       if (!capable(CAP_SYS_ADMIN))
8328 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT))
8329                 return -EPERM;
8330  
8331         mnt = do_kern_mount(type, flags, name, data);
8332 @@ -1379,6 +1445,7 @@ long do_mount(char *dev_name, char *dir_
8333         struct nameidata nd;
8334         int retval = 0;
8335         int mnt_flags = 0;
8336 +       tag_t tag = 0;
8337  
8338         /* Discard magic */
8339         if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
8340 @@ -1394,7 +1461,19 @@ long do_mount(char *dev_name, char *dir_
8341         if (data_page)
8342                 ((char *)data_page)[PAGE_SIZE - 1] = 0;
8343  
8344 +#ifdef CONFIG_PROPAGATE
8345 +       retval = dx_parse_tag(data_page, &tag, 1);
8346 +       if (retval) {
8347 +               mnt_flags |= MNT_TAGID;
8348 +               /* bind and re-mounts get the tag flag */
8349 +               if (flags & (MS_BIND|MS_REMOUNT))
8350 +                       flags |= MS_TAGID;
8351 +       }
8352 +#endif
8353 +
8354         /* Separate the per-mountpoint flags */
8355 +       if (flags & MS_RDONLY)
8356 +               mnt_flags |= MNT_RDONLY;
8357         if (flags & MS_NOSUID)
8358                 mnt_flags |= MNT_NOSUID;
8359         if (flags & MS_NODEV)
8360 @@ -1406,6 +1485,8 @@ long do_mount(char *dev_name, char *dir_
8361         if (flags & MS_NODIRATIME)
8362                 mnt_flags |= MNT_NODIRATIME;
8363  
8364 +       if (!capable(CAP_SYS_ADMIN))
8365 +               mnt_flags |= MNT_NODEV;
8366         flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
8367                    MS_NOATIME | MS_NODIRATIME);
8368  
8369 @@ -1420,9 +1501,9 @@ long do_mount(char *dev_name, char *dir_
8370  
8371         if (flags & MS_REMOUNT)
8372                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
8373 -                                   data_page);
8374 +                                   data_page, tag);
8375         else if (flags & MS_BIND)
8376 -               retval = do_loopback(&nd, dev_name, flags & MS_REC);
8377 +               retval = do_loopback(&nd, dev_name, tag, flags, mnt_flags);
8378         else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
8379                 retval = do_change_type(&nd, flags);
8380         else if (flags & MS_MOVE)
8381 @@ -1520,7 +1601,7 @@ int copy_namespace(int flags, struct tas
8382         if (!(flags & CLONE_NEWNS))
8383                 return 0;
8384  
8385 -       if (!capable(CAP_SYS_ADMIN)) {
8386 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) {
8387                 err = -EPERM;
8388                 goto out;
8389         }
8390 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/client.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/client.c
8391 --- linux-2.6.19.1/fs/nfs/client.c      2006-11-30 21:19:26 +0100
8392 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/client.c    2006-11-08 04:57:47 +0100
8393 @@ -520,6 +520,9 @@ static int nfs_init_server_rpcclient(str
8394         if (server->flags & NFS4_MOUNT_INTR)
8395                 server->client->cl_intr = 1;
8396  
8397 +       server->client->cl_tag = 0;
8398 +       if (server->flags & NFS_MOUNT_TAGGED)
8399 +               server->client->cl_tag = 1;
8400         return 0;
8401  }
8402  
8403 @@ -676,6 +679,10 @@ static void nfs_server_set_fsinfo(struct
8404                 server->acdirmin = server->acdirmax = 0;
8405         }
8406  
8407 +       /* FIXME: needs fsinfo
8408 +       if (server->flags & NFS_MOUNT_TAGGED)
8409 +               sb->s_flags |= MS_TAGGED;       */
8410 +
8411         server->maxfilesize = fsinfo->maxfilesize;
8412  
8413         /* We're airborne Set socket buffersize */
8414 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/dir.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/dir.c
8415 --- linux-2.6.19.1/fs/nfs/dir.c 2006-11-30 21:19:26 +0100
8416 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/dir.c       2006-11-30 19:09:28 +0100
8417 @@ -33,6 +33,7 @@
8418  #include <linux/pagevec.h>
8419  #include <linux/namei.h>
8420  #include <linux/mount.h>
8421 +#include <linux/vs_tag.h>
8422  
8423  #include "nfs4_fs.h"
8424  #include "delegation.h"
8425 @@ -933,6 +934,7 @@ static struct dentry *nfs_lookup(struct 
8426         if (IS_ERR(res))
8427                 goto out_unlock;
8428  
8429 +       dx_propagate_tag(nd, inode);
8430  no_entry:
8431         res = d_materialise_unique(dentry, inode);
8432         if (res != NULL) {
8433 @@ -975,7 +977,8 @@ static int is_atomic_open(struct inode *
8434         if (nd->flags & LOOKUP_DIRECTORY)
8435                 return 0;
8436         /* Are we trying to write to a read only partition? */
8437 -       if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
8438 +       if ((IS_RDONLY(dir) || MNT_IS_RDONLY(nd->mnt)) &&
8439 +               (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE)))
8440                 return 0;
8441         return 1;
8442  }
8443 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/inode.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/inode.c
8444 --- linux-2.6.19.1/fs/nfs/inode.c       2006-11-30 21:19:26 +0100
8445 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/inode.c     2006-11-30 18:53:18 +0100
8446 @@ -37,6 +37,7 @@
8447  #include <linux/vfs.h>
8448  #include <linux/inet.h>
8449  #include <linux/nfs_xdr.h>
8450 +#include <linux/vs_tag.h>
8451  
8452  #include <asm/system.h>
8453  #include <asm/uaccess.h>
8454 @@ -279,8 +280,10 @@ nfs_fhget(struct super_block *sb, struct
8455                         nfsi->change_attr = fattr->change_attr;
8456                 inode->i_size = nfs_size_to_loff_t(fattr->size);
8457                 inode->i_nlink = fattr->nlink;
8458 -               inode->i_uid = fattr->uid;
8459 -               inode->i_gid = fattr->gid;
8460 +               inode->i_uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
8461 +               inode->i_gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
8462 +               inode->i_tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
8463 +                                        /* maybe fattr->xid someday */
8464                 if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
8465                         /*
8466                          * report the blocks in 512byte units
8467 @@ -369,6 +372,8 @@ void nfs_setattr_update_inode(struct ino
8468                         inode->i_uid = attr->ia_uid;
8469                 if ((attr->ia_valid & ATTR_GID) != 0)
8470                         inode->i_gid = attr->ia_gid;
8471 +               if ((attr->ia_valid & ATTR_TAG) && IS_TAGGED(inode))
8472 +                       inode->i_tag = attr->ia_tag;
8473                 spin_lock(&inode->i_lock);
8474                 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
8475                 spin_unlock(&inode->i_lock);
8476 @@ -778,6 +783,9 @@ static int nfs_check_inode_attributes(st
8477         struct nfs_inode *nfsi = NFS_I(inode);
8478         loff_t cur_size, new_isize;
8479         int data_unstable;
8480 +       uid_t uid;
8481 +       gid_t gid;
8482 +       tag_t tag;
8483  
8484  
8485         /* Has the inode gone and changed behind our back? */
8486 @@ -805,10 +813,15 @@ static int nfs_check_inode_attributes(st
8487         if (cur_size != new_isize && nfsi->npages == 0)
8488                 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
8489  
8490 +       uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
8491 +       gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
8492 +       tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
8493 +
8494         /* Have any file permissions changed? */
8495         if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
8496 -                       || inode->i_uid != fattr->uid
8497 -                       || inode->i_gid != fattr->gid)
8498 +                       || inode->i_uid != uid
8499 +                       || inode->i_gid != gid
8500 +                       || inode->i_tag != tag)
8501                 nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
8502  
8503         /* Has the link count changed? */
8504 @@ -898,6 +911,9 @@ static int nfs_update_inode(struct inode
8505         loff_t cur_isize, new_isize;
8506         unsigned int    invalid = 0;
8507         int data_stable;
8508 +       uid_t uid;
8509 +       gid_t gid;
8510 +       tag_t tag;
8511  
8512         dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
8513                         __FUNCTION__, inode->i_sb->s_id, inode->i_ino,
8514 @@ -970,15 +986,21 @@ static int nfs_update_inode(struct inode
8515         }
8516         memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
8517  
8518 +       uid = INOTAG_UID(DX_TAG(inode), fattr->uid, fattr->gid);
8519 +       gid = INOTAG_GID(DX_TAG(inode), fattr->uid, fattr->gid);
8520 +       tag = INOTAG_TAG(DX_TAG(inode), fattr->uid, fattr->gid, 0);
8521 +
8522         if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
8523 -           inode->i_uid != fattr->uid ||
8524 -           inode->i_gid != fattr->gid)
8525 +           inode->i_uid != uid ||
8526 +           inode->i_gid != gid ||
8527 +           inode->i_tag != tag)
8528                 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
8529  
8530         inode->i_mode = fattr->mode;
8531         inode->i_nlink = fattr->nlink;
8532 -       inode->i_uid = fattr->uid;
8533 -       inode->i_gid = fattr->gid;
8534 +       inode->i_uid = uid;
8535 +       inode->i_gid = gid;
8536 +       inode->i_tag = tag;
8537  
8538         if (fattr->valid & (NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4)) {
8539                 /*
8540 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/nfs3xdr.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/nfs3xdr.c
8541 --- linux-2.6.19.1/fs/nfs/nfs3xdr.c     2006-11-30 21:19:26 +0100
8542 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/nfs3xdr.c   2006-11-30 18:53:18 +0100
8543 @@ -22,6 +22,7 @@
8544  #include <linux/nfs3.h>
8545  #include <linux/nfs_fs.h>
8546  #include <linux/nfsacl.h>
8547 +#include <linux/vs_tag.h>
8548  #include "internal.h"
8549  
8550  #define NFSDBG_FACILITY                NFSDBG_XDR
8551 @@ -178,7 +179,7 @@ xdr_decode_fattr(__be32 *p, struct nfs_f
8552  }
8553  
8554  static inline __be32 *
8555 -xdr_encode_sattr(__be32 *p, struct iattr *attr)
8556 +xdr_encode_sattr(__be32 *p, struct iattr *attr, int tag)
8557  {
8558         if (attr->ia_valid & ATTR_MODE) {
8559                 *p++ = xdr_one;
8560 @@ -186,15 +187,17 @@ xdr_encode_sattr(__be32 *p, struct iattr
8561         } else {
8562                 *p++ = xdr_zero;
8563         }
8564 -       if (attr->ia_valid & ATTR_UID) {
8565 +       if (attr->ia_valid & ATTR_UID ||
8566 +               (tag && (attr->ia_valid & ATTR_TAG))) {
8567                 *p++ = xdr_one;
8568 -               *p++ = htonl(attr->ia_uid);
8569 +               *p++ = htonl(TAGINO_UID(tag, attr->ia_uid, attr->ia_tag));
8570         } else {
8571                 *p++ = xdr_zero;
8572         }
8573 -       if (attr->ia_valid & ATTR_GID) {
8574 +       if (attr->ia_valid & ATTR_GID ||
8575 +               (tag && (attr->ia_valid & ATTR_TAG))) {
8576                 *p++ = xdr_one;
8577 -               *p++ = htonl(attr->ia_gid);
8578 +               *p++ = htonl(TAGINO_GID(tag, attr->ia_gid, attr->ia_tag));
8579         } else {
8580                 *p++ = xdr_zero;
8581         }
8582 @@ -279,7 +282,8 @@ static int
8583  nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
8584  {
8585         p = xdr_encode_fhandle(p, args->fh);
8586 -       p = xdr_encode_sattr(p, args->sattr);
8587 +       p = xdr_encode_sattr(p, args->sattr,
8588 +               req->rq_task->tk_client->cl_tag);
8589         *p++ = htonl(args->guard);
8590         if (args->guard)
8591                 p = xdr_encode_time3(p, &args->guardtime);
8592 @@ -370,7 +374,8 @@ nfs3_xdr_createargs(struct rpc_rqst *req
8593                 *p++ = args->verifier[0];
8594                 *p++ = args->verifier[1];
8595         } else
8596 -               p = xdr_encode_sattr(p, args->sattr);
8597 +               p = xdr_encode_sattr(p, args->sattr,
8598 +                       req->rq_task->tk_client->cl_tag);
8599  
8600         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
8601         return 0;
8602 @@ -384,7 +389,8 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req,
8603  {
8604         p = xdr_encode_fhandle(p, args->fh);
8605         p = xdr_encode_array(p, args->name, args->len);
8606 -       p = xdr_encode_sattr(p, args->sattr);
8607 +       p = xdr_encode_sattr(p, args->sattr,
8608 +               req->rq_task->tk_client->cl_tag);
8609         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
8610         return 0;
8611  }
8612 @@ -397,7 +403,8 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *re
8613  {
8614         p = xdr_encode_fhandle(p, args->fromfh);
8615         p = xdr_encode_array(p, args->fromname, args->fromlen);
8616 -       p = xdr_encode_sattr(p, args->sattr);
8617 +       p = xdr_encode_sattr(p, args->sattr,
8618 +               req->rq_task->tk_client->cl_tag);
8619         *p++ = htonl(args->pathlen);
8620         req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
8621  
8622 @@ -415,7 +422,8 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req,
8623         p = xdr_encode_fhandle(p, args->fh);
8624         p = xdr_encode_array(p, args->name, args->len);
8625         *p++ = htonl(args->type);
8626 -       p = xdr_encode_sattr(p, args->sattr);
8627 +       p = xdr_encode_sattr(p, args->sattr,
8628 +               req->rq_task->tk_client->cl_tag);
8629         if (args->type == NF3CHR || args->type == NF3BLK) {
8630                 *p++ = htonl(MAJOR(args->rdev));
8631                 *p++ = htonl(MINOR(args->rdev));
8632 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/nfsroot.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/nfsroot.c
8633 --- linux-2.6.19.1/fs/nfs/nfsroot.c     2006-11-30 21:19:26 +0100
8634 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/nfsroot.c   2006-12-02 01:37:05 +0100
8635 @@ -118,12 +118,12 @@ static int mount_port __initdata = 0;             /
8636  enum {
8637         /* Options that take integer arguments */
8638         Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin,
8639 -       Opt_acregmax, Opt_acdirmin, Opt_acdirmax,
8640 +       Opt_acregmax, Opt_acdirmin, Opt_acdirmax, Opt_tagid,
8641         /* Options that take no arguments */
8642         Opt_soft, Opt_hard, Opt_intr,
8643         Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, 
8644         Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
8645 -       Opt_acl, Opt_noacl,
8646 +       Opt_acl, Opt_noacl, Opt_tag, Opt_notag,
8647         /* Error token */
8648         Opt_err
8649  };
8650 @@ -160,6 +160,10 @@ static match_table_t __initdata tokens =
8651         {Opt_tcp, "tcp"},
8652         {Opt_acl, "acl"},
8653         {Opt_noacl, "noacl"},
8654 +       {Opt_tag, "tag"},
8655 +       {Opt_notag, "notag"},
8656 +       {Opt_tagid, "tagid=%u"},
8657 +       {Opt_tag, "tagxid"},
8658         {Opt_err, NULL}
8659         
8660  };
8661 @@ -274,6 +278,20 @@ static int __init root_nfs_parse(char *n
8662                         case Opt_noacl:
8663                                 nfs_data.flags |= NFS_MOUNT_NOACL;
8664                                 break;
8665 +#ifndef CONFIG_TAGGING_NONE
8666 +                       case Opt_tag:
8667 +                               nfs_data.flags |= NFS_MOUNT_TAGGED;
8668 +                               break;
8669 +                       case Opt_notag:
8670 +                               nfs_data.flags &= ~NFS_MOUNT_TAGGED;
8671 +                               break;
8672 +#endif
8673 +#ifdef CONFIG_PROPAGATE
8674 +                       case Opt_tagid:
8675 +                               /* use args[0] */
8676 +                               nfs_data.flags |= NFS_MOUNT_TAGGED;
8677 +                               break;
8678 +#endif
8679                         default:
8680                                 printk(KERN_WARNING "Root-NFS: unknown "
8681                                         "option: %s\n", p);
8682 diff -NurpP --minimal linux-2.6.19.1/fs/nfs/super.c linux-2.6.19.1-vs2.3.0.6/fs/nfs/super.c
8683 --- linux-2.6.19.1/fs/nfs/super.c       2006-11-30 21:19:26 +0100
8684 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfs/super.c     2006-11-30 18:53:18 +0100
8685 @@ -44,6 +44,7 @@
8686  #include <linux/vfs.h>
8687  #include <linux/inet.h>
8688  #include <linux/nfs_xdr.h>
8689 +#include <linux/vs_tag.h>
8690  
8691  #include <asm/system.h>
8692  #include <asm/uaccess.h>
8693 @@ -290,6 +291,7 @@ static void nfs_show_mount_options(struc
8694                 { NFS_MOUNT_NOAC, ",noac", "" },
8695                 { NFS_MOUNT_NONLM, ",nolock", "" },
8696                 { NFS_MOUNT_NOACL, ",noacl", "" },
8697 +               { NFS_MOUNT_TAGGED, ",tag", "" },
8698                 { 0, NULL, NULL }
8699         };
8700         const struct proc_nfs_info *nfs_infop;
8701 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/auth.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/auth.c
8702 --- linux-2.6.19.1/fs/nfsd/auth.c       2006-06-18 04:54:42 +0200
8703 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/auth.c     2006-11-30 18:53:18 +0100
8704 @@ -9,6 +9,7 @@
8705  #include <linux/sunrpc/svc.h>
8706  #include <linux/sunrpc/svcauth.h>
8707  #include <linux/nfsd/nfsd.h>
8708 +#include <linux/vs_tag.h>
8709  
8710  #define        CAP_NFSD_MASK (CAP_FS_MASK|CAP_TO_MASK(CAP_SYS_RESOURCE))
8711  
8712 @@ -41,19 +42,22 @@ int nfsd_setuser(struct svc_rqst *rqstp,
8713                 get_group_info(cred.cr_group_info);
8714  
8715         if (cred.cr_uid != (uid_t) -1)
8716 -               current->fsuid = cred.cr_uid;
8717 +               current->fsuid = INOTAG_UID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid);
8718         else
8719                 current->fsuid = exp->ex_anon_uid;
8720         if (cred.cr_gid != (gid_t) -1)
8721 -               current->fsgid = cred.cr_gid;
8722 +               current->fsgid = INOTAG_GID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid);
8723         else
8724                 current->fsgid = exp->ex_anon_gid;
8725  
8726 +       /* this desperately needs a tag :) */
8727 +       current->xid = (xid_t)INOTAG_TAG(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid, 0);
8728 +
8729         if (!cred.cr_group_info)
8730                 return -ENOMEM;
8731         ret = set_current_groups(cred.cr_group_info);
8732         put_group_info(cred.cr_group_info);
8733 -       if ((cred.cr_uid)) {
8734 +       if (INOTAG_UID(DX_TAG_NFSD, cred.cr_uid, cred.cr_gid)) {
8735                 cap_t(current->cap_effective) &= ~CAP_NFSD_MASK;
8736         } else {
8737                 cap_t(current->cap_effective) |= (CAP_NFSD_MASK &
8738 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/nfs3xdr.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs3xdr.c
8739 --- linux-2.6.19.1/fs/nfsd/nfs3xdr.c    2006-11-30 21:19:26 +0100
8740 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs3xdr.c  2006-11-30 18:53:18 +0100
8741 @@ -21,6 +21,7 @@
8742  #include <linux/sunrpc/svc.h>
8743  #include <linux/nfsd/nfsd.h>
8744  #include <linux/nfsd/xdr3.h>
8745 +#include <linux/vs_tag.h>
8746  
8747  #define NFSDDBG_FACILITY               NFSDDBG_XDR
8748  
8749 @@ -111,6 +112,8 @@ static inline __be32 *
8750  decode_sattr3(__be32 *p, struct iattr *iap)
8751  {
8752         u32     tmp;
8753 +       uid_t   uid = 0;
8754 +       gid_t   gid = 0;
8755  
8756         iap->ia_valid = 0;
8757  
8758 @@ -120,12 +123,15 @@ decode_sattr3(__be32 *p, struct iattr *i
8759         }
8760         if (*p++) {
8761                 iap->ia_valid |= ATTR_UID;
8762 -               iap->ia_uid = ntohl(*p++);
8763 +               uid = ntohl(*p++);
8764         }
8765         if (*p++) {
8766                 iap->ia_valid |= ATTR_GID;
8767 -               iap->ia_gid = ntohl(*p++);
8768 +               gid = ntohl(*p++);
8769         }
8770 +       iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid);
8771 +       iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid);
8772 +       iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0);
8773         if (*p++) {
8774                 u64     newsize;
8775  
8776 @@ -163,8 +169,10 @@ encode_fattr3(struct svc_rqst *rqstp, __
8777         *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
8778         *p++ = htonl((u32) stat->mode);
8779         *p++ = htonl((u32) stat->nlink);
8780 -       *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
8781 -       *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
8782 +       *p++ = htonl((u32) nfsd_ruid(rqstp,
8783 +               TAGINO_UID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
8784 +       *p++ = htonl((u32) nfsd_rgid(rqstp,
8785 +               TAGINO_GID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
8786         if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
8787                 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
8788         } else {
8789 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/nfs4recover.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs4recover.c
8790 --- linux-2.6.19.1/fs/nfsd/nfs4recover.c        2006-11-30 21:19:26 +0100
8791 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs4recover.c      2006-11-08 21:53:01 +0100
8792 @@ -156,7 +156,7 @@ nfsd4_create_clid_dir(struct nfs4_client
8793                 dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
8794                 goto out_put;
8795         }
8796 -       status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
8797 +       status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU, NULL);
8798  out_put:
8799         dput(dentry);
8800  out_unlock:
8801 @@ -260,7 +260,7 @@ nfsd4_remove_clid_file(struct dentry *di
8802                 return -EINVAL;
8803         }
8804         mutex_lock(&dir->d_inode->i_mutex);
8805 -       status = vfs_unlink(dir->d_inode, dentry);
8806 +       status = vfs_unlink(dir->d_inode, dentry, NULL);
8807         mutex_unlock(&dir->d_inode->i_mutex);
8808         return status;
8809  }
8810 @@ -275,7 +275,7 @@ nfsd4_clear_clid_dir(struct dentry *dir,
8811          * a kernel from the future.... */
8812         nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
8813         mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
8814 -       status = vfs_rmdir(dir->d_inode, dentry);
8815 +       status = vfs_rmdir(dir->d_inode, dentry, NULL);
8816         mutex_unlock(&dir->d_inode->i_mutex);
8817         return status;
8818  }
8819 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/nfs4xdr.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs4xdr.c
8820 --- linux-2.6.19.1/fs/nfsd/nfs4xdr.c    2006-11-30 21:19:26 +0100
8821 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfs4xdr.c  2006-11-30 18:53:18 +0100
8822 @@ -57,6 +57,7 @@
8823  #include <linux/nfsd_idmap.h>
8824  #include <linux/nfs4.h>
8825  #include <linux/nfs4_acl.h>
8826 +#include <linux/vs_tag.h>
8827  
8828  #define NFSDDBG_FACILITY               NFSDDBG_XDR
8829  
8830 @@ -1727,14 +1728,18 @@ out_acl:
8831                 WRITE32(stat.nlink);
8832         }
8833         if (bmval1 & FATTR4_WORD1_OWNER) {
8834 -               status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
8835 +               status = nfsd4_encode_user(rqstp,
8836 +                       TAGINO_UID(DX_TAG(dentry->d_inode),
8837 +                       stat.uid, stat.tag), &p, &buflen);
8838                 if (status == nfserr_resource)
8839                         goto out_resource;
8840                 if (status)
8841                         goto out;
8842         }
8843         if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
8844 -               status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
8845 +               status = nfsd4_encode_group(rqstp,
8846 +                       TAGINO_GID(DX_TAG(dentry->d_inode),
8847 +                       stat.gid, stat.tag), &p, &buflen);
8848                 if (status == nfserr_resource)
8849                         goto out_resource;
8850                 if (status)
8851 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/nfsxdr.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfsxdr.c
8852 --- linux-2.6.19.1/fs/nfsd/nfsxdr.c     2006-11-30 21:19:26 +0100
8853 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/nfsxdr.c   2006-11-30 18:53:18 +0100
8854 @@ -15,6 +15,7 @@
8855  #include <linux/nfsd/nfsd.h>
8856  #include <linux/nfsd/xdr.h>
8857  #include <linux/mm.h>
8858 +#include <linux/vs_tag.h>
8859  
8860  #define NFSDDBG_FACILITY               NFSDDBG_XDR
8861  
8862 @@ -102,6 +103,8 @@ static inline __be32 *
8863  decode_sattr(__be32 *p, struct iattr *iap)
8864  {
8865         u32     tmp, tmp1;
8866 +       uid_t   uid = 0;
8867 +       gid_t   gid = 0;
8868  
8869         iap->ia_valid = 0;
8870  
8871 @@ -115,12 +118,15 @@ decode_sattr(__be32 *p, struct iattr *ia
8872         }
8873         if ((tmp = ntohl(*p++)) != (u32)-1) {
8874                 iap->ia_valid |= ATTR_UID;
8875 -               iap->ia_uid = tmp;
8876 +               uid = tmp;
8877         }
8878         if ((tmp = ntohl(*p++)) != (u32)-1) {
8879                 iap->ia_valid |= ATTR_GID;
8880 -               iap->ia_gid = tmp;
8881 +               gid = tmp;
8882         }
8883 +       iap->ia_uid = INOTAG_UID(DX_TAG_NFSD, uid, gid);
8884 +       iap->ia_gid = INOTAG_GID(DX_TAG_NFSD, uid, gid);
8885 +       iap->ia_tag = INOTAG_TAG(DX_TAG_NFSD, uid, gid, 0);
8886         if ((tmp = ntohl(*p++)) != (u32)-1) {
8887                 iap->ia_valid |= ATTR_SIZE;
8888                 iap->ia_size = tmp;
8889 @@ -164,8 +170,10 @@ encode_fattr(struct svc_rqst *rqstp, __b
8890         *p++ = htonl(nfs_ftypes[type >> 12]);
8891         *p++ = htonl((u32) stat->mode);
8892         *p++ = htonl((u32) stat->nlink);
8893 -       *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
8894 -       *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
8895 +       *p++ = htonl((u32) nfsd_ruid(rqstp,
8896 +               TAGINO_UID(DX_TAG(dentry->d_inode), stat->uid, stat->tag)));
8897 +       *p++ = htonl((u32) nfsd_rgid(rqstp,
8898 +               TAGINO_GID(DX_TAG(dentry->d_inode), stat->gid, stat->tag)));
8899  
8900         if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
8901                 *p++ = htonl(NFS_MAXPATHLEN);
8902 diff -NurpP --minimal linux-2.6.19.1/fs/nfsd/vfs.c linux-2.6.19.1-vs2.3.0.6/fs/nfsd/vfs.c
8903 --- linux-2.6.19.1/fs/nfsd/vfs.c        2006-11-30 21:19:26 +0100
8904 +++ linux-2.6.19.1-vs2.3.0.6/fs/nfsd/vfs.c      2006-11-20 21:12:32 +0100
8905 @@ -1183,13 +1183,13 @@ nfsd_create(struct svc_rqst *rqstp, stru
8906                 host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
8907                 break;
8908         case S_IFDIR:
8909 -               host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
8910 +               host_err = vfs_mkdir(dirp, dchild, iap->ia_mode, NULL);
8911                 break;
8912         case S_IFCHR:
8913         case S_IFBLK:
8914         case S_IFIFO:
8915         case S_IFSOCK:
8916 -               host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
8917 +               host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev, NULL);
8918                 break;
8919         default:
8920                 printk("nfsd: bad file type %o in nfsd_create\n", type);
8921 @@ -1474,11 +1474,13 @@ nfsd_symlink(struct svc_rqst *rqstp, str
8922                 else {
8923                         strncpy(path_alloced, path, plen);
8924                         path_alloced[plen] = 0;
8925 -                       host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
8926 +                       host_err = vfs_symlink(dentry->d_inode, dnew,
8927 +                               path_alloced, mode, NULL);
8928                         kfree(path_alloced);
8929                 }
8930         } else
8931 -               host_err = vfs_symlink(dentry->d_inode, dnew, path, mode);
8932 +               host_err = vfs_symlink(dentry->d_inode, dnew,
8933 +                       path, mode, NULL);
8934  
8935         if (!host_err) {
8936                 if (EX_ISSYNC(fhp->fh_export))
8937 @@ -1537,7 +1539,7 @@ nfsd_link(struct svc_rqst *rqstp, struct
8938         dold = tfhp->fh_dentry;
8939         dest = dold->d_inode;
8940  
8941 -       host_err = vfs_link(dold, dirp, dnew);
8942 +       host_err = vfs_link(dold, dirp, dnew, NULL);
8943         if (!host_err) {
8944                 if (EX_ISSYNC(ffhp->fh_export)) {
8945                         err = nfserrno(nfsd_sync_dir(ddir));
8946 @@ -1702,9 +1704,9 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
8947                         host_err = -EPERM;
8948                 } else
8949  #endif
8950 -               host_err = vfs_unlink(dirp, rdentry);
8951 +               host_err = vfs_unlink(dirp, rdentry, NULL);
8952         } else { /* It's RMDIR */
8953 -               host_err = vfs_rmdir(dirp, rdentry);
8954 +               host_err = vfs_rmdir(dirp, rdentry, NULL);
8955         }
8956  
8957         dput(rdentry);
8958 @@ -1815,7 +1817,8 @@ nfsd_permission(struct svc_export *exp, 
8959          */
8960         if (!(acc & MAY_LOCAL_ACCESS))
8961                 if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
8962 -                       if (EX_RDONLY(exp) || IS_RDONLY(inode))
8963 +                       if (EX_RDONLY(exp) || IS_RDONLY(inode)
8964 +                               || MNT_IS_RDONLY(exp->ex_mnt))
8965                                 return nfserr_rofs;
8966                         if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
8967                                 return nfserr_perm;
8968 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/dlm/dlmfs.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlm/dlmfs.c
8969 --- linux-2.6.19.1/fs/ocfs2/dlm/dlmfs.c 2006-11-30 21:19:27 +0100
8970 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlm/dlmfs.c       2006-12-02 01:14:52 +0100
8971 @@ -44,6 +44,7 @@
8972  #include <linux/string.h>
8973  #include <linux/smp_lock.h>
8974  #include <linux/backing-dev.h>
8975 +#include <linux/vs_tag.h>
8976  
8977  #include <asm/uaccess.h>
8978  
8979 @@ -335,6 +336,7 @@ static struct inode *dlmfs_get_root_inod
8980                 inode->i_mode = mode;
8981                 inode->i_uid = current->fsuid;
8982                 inode->i_gid = current->fsgid;
8983 +               inode->i_tag = dx_current_fstag(sb);
8984                 inode->i_blocks = 0;
8985                 inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
8986                 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
8987 @@ -361,6 +363,7 @@ static struct inode *dlmfs_get_inode(str
8988         inode->i_mode = mode;
8989         inode->i_uid = current->fsuid;
8990         inode->i_gid = current->fsgid;
8991 +       inode->i_tag = dx_current_fstag(sb);
8992         inode->i_blocks = 0;
8993         inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
8994         inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
8995 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/dlmglue.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlmglue.c
8996 --- linux-2.6.19.1/fs/ocfs2/dlmglue.c   2006-11-30 21:19:28 +0100
8997 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlmglue.c 2006-12-02 01:19:57 +0100
8998 @@ -1326,6 +1326,7 @@ static void __ocfs2_stuff_meta_lvb(struc
8999         lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
9000         lvb->lvb_iuid      = cpu_to_be32(inode->i_uid);
9001         lvb->lvb_igid      = cpu_to_be32(inode->i_gid);
9002 +       lvb->lvb_itag      = cpu_to_be16(inode->i_tag);
9003         lvb->lvb_imode     = cpu_to_be16(inode->i_mode);
9004         lvb->lvb_inlink    = cpu_to_be16(inode->i_nlink);
9005         lvb->lvb_iatime_packed  =
9006 @@ -1379,6 +1380,7 @@ static void ocfs2_refresh_inode_from_lvb
9007  
9008         inode->i_uid     = be32_to_cpu(lvb->lvb_iuid);
9009         inode->i_gid     = be32_to_cpu(lvb->lvb_igid);
9010 +       inode->i_tag     = be16_to_cpu(lvb->lvb_itag);
9011         inode->i_mode    = be16_to_cpu(lvb->lvb_imode);
9012         inode->i_nlink   = be16_to_cpu(lvb->lvb_inlink);
9013         ocfs2_unpack_timespec(&inode->i_atime,
9014 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/dlmglue.h linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlmglue.h
9015 --- linux-2.6.19.1/fs/ocfs2/dlmglue.h   2006-11-30 21:19:28 +0100
9016 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/dlmglue.h 2006-12-02 01:14:52 +0100
9017 @@ -34,7 +34,7 @@
9018  struct ocfs2_meta_lvb {
9019         __u8         lvb_version;
9020         __u8         lvb_reserved0;
9021 -       __be16       lvb_reserved1;
9022 +       __be16       lvb_itag;
9023         __be32       lvb_iclusters;
9024         __be32       lvb_iuid;
9025         __be32       lvb_igid;
9026 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/file.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/file.c
9027 --- linux-2.6.19.1/fs/ocfs2/file.c      2006-11-30 21:19:28 +0100
9028 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/file.c    2006-11-08 04:57:52 +0100
9029 @@ -800,13 +800,15 @@ int ocfs2_setattr(struct dentry *dentry,
9030                 mlog(0, "uid change: %d\n", attr->ia_uid);
9031         if (attr->ia_valid & ATTR_GID)
9032                 mlog(0, "gid change: %d\n", attr->ia_gid);
9033 +       if (attr->ia_valid & ATTR_TAG)
9034 +               mlog(0, "tag change: %d\n", attr->ia_tag);
9035         if (attr->ia_valid & ATTR_SIZE)
9036                 mlog(0, "size change...\n");
9037         if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME))
9038                 mlog(0, "time change...\n");
9039  
9040  #define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
9041 -                          | ATTR_GID | ATTR_UID | ATTR_MODE)
9042 +                          | ATTR_GID | ATTR_UID | ATTR_TAG | ATTR_MODE)
9043         if (!(attr->ia_valid & OCFS2_VALID_ATTRS)) {
9044                 mlog(0, "can't handle attrs: 0x%x\n", attr->ia_valid);
9045                 return 0;
9046 @@ -1220,6 +1222,7 @@ bail:
9047  struct inode_operations ocfs2_file_iops = {
9048         .setattr        = ocfs2_setattr,
9049         .getattr        = ocfs2_getattr,
9050 +       .sync_flags     = ocfs2_sync_flags,
9051  };
9052  
9053  struct inode_operations ocfs2_special_file_iops = {
9054 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/inode.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/inode.c
9055 --- linux-2.6.19.1/fs/ocfs2/inode.c     2006-11-30 21:19:28 +0100
9056 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/inode.c   2006-12-02 01:35:31 +0100
9057 @@ -29,6 +29,7 @@
9058  #include <linux/highmem.h>
9059  #include <linux/pagemap.h>
9060  #include <linux/smp_lock.h>
9061 +#include <linux/vs_tag.h>
9062  
9063  #include <asm/byteorder.h>
9064  
9065 @@ -43,6 +44,7 @@
9066  #include "file.h"
9067  #include "heartbeat.h"
9068  #include "inode.h"
9069 +#include "ioctl.h"
9070  #include "journal.h"
9071  #include "namei.h"
9072  #include "suballoc.h"
9073 @@ -78,6 +80,10 @@ void ocfs2_set_inode_flags(struct inode 
9074  
9075         if (flags & OCFS2_IMMUTABLE_FL)
9076                 inode->i_flags |= S_IMMUTABLE;
9077 +       if (flags & OCFS2_IUNLINK_FL)
9078 +               inode->i_flags |= S_IUNLINK;
9079 +       if (flags & OCFS2_BARRIER_FL)
9080 +               inode->i_flags |= S_BARRIER;
9081  
9082         if (flags & OCFS2_SYNC_FL)
9083                 inode->i_flags |= S_SYNC;
9084 @@ -89,6 +95,39 @@ void ocfs2_set_inode_flags(struct inode 
9085                 inode->i_flags |= S_DIRSYNC;
9086  }
9087  
9088 +int ocfs2_sync_flags(struct inode *inode)
9089 +{
9090 +       unsigned int oldflags, newflags;
9091 +
9092 +       oldflags = OCFS2_I(inode)->ip_flags;
9093 +       newflags = oldflags & ~(OCFS2_APPEND_FL |
9094 +               OCFS2_IMMUTABLE_FL | OCFS2_IUNLINK_FL |
9095 +               OCFS2_BARRIER_FL | OCFS2_NOATIME_FL |
9096 +               OCFS2_SYNC_FL | OCFS2_DIRSYNC_FL);
9097 +
9098 +       if (IS_APPEND(inode))
9099 +               newflags |= OCFS2_APPEND_FL;
9100 +       if (IS_IMMUTABLE(inode))
9101 +               newflags |= OCFS2_IMMUTABLE_FL;
9102 +       if (IS_IUNLINK(inode))
9103 +               newflags |= OCFS2_IUNLINK_FL;
9104 +       if (IS_BARRIER(inode))
9105 +               newflags |= OCFS2_BARRIER_FL;
9106 +
9107 +       /* we do not want to copy superblock flags */
9108 +       if (inode->i_flags & S_NOATIME)
9109 +               newflags |= OCFS2_NOATIME_FL;
9110 +       if (inode->i_flags & S_SYNC)
9111 +               newflags |= OCFS2_SYNC_FL;
9112 +       if (inode->i_flags & S_DIRSYNC)
9113 +               newflags |= OCFS2_DIRSYNC_FL;
9114 +
9115 +       if (oldflags ^ newflags)
9116 +               return ocfs2_set_inode_attr(inode,
9117 +                       newflags, OCFS2_FL_MASK);
9118 +       return 0;
9119 +}
9120 +
9121  struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb,
9122                                      u64 blkno,
9123                                      int delete_vote)
9124 @@ -236,6 +275,8 @@ int ocfs2_populate_inode(struct inode *i
9125         struct super_block *sb;
9126         struct ocfs2_super *osb;
9127         int status = -EINVAL;
9128 +       uid_t uid;
9129 +       gid_t gid;
9130  
9131         mlog_entry("(0x%p, size:%llu)\n", inode,
9132                    (unsigned long long)fe->i_size);
9133 @@ -267,8 +308,12 @@ int ocfs2_populate_inode(struct inode *i
9134         inode->i_generation = le32_to_cpu(fe->i_generation);
9135         inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
9136         inode->i_mode = le16_to_cpu(fe->i_mode);
9137 -       inode->i_uid = le32_to_cpu(fe->i_uid);
9138 -       inode->i_gid = le32_to_cpu(fe->i_gid);
9139 +       uid = le32_to_cpu(fe->i_uid);
9140 +       gid = le32_to_cpu(fe->i_gid);
9141 +       inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
9142 +       inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
9143 +       inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
9144 +               /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0);
9145  
9146         /* Fast symlinks will have i_size but no allocated clusters. */
9147         if (S_ISLNK(inode->i_mode) && !fe->i_clusters)
9148 @@ -1228,8 +1273,11 @@ int ocfs2_mark_inode_dirty(struct ocfs2_
9149  
9150         fe->i_size = cpu_to_le64(i_size_read(inode));
9151         fe->i_links_count = cpu_to_le16(inode->i_nlink);
9152 -       fe->i_uid = cpu_to_le32(inode->i_uid);
9153 -       fe->i_gid = cpu_to_le32(inode->i_gid);
9154 +       fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode),
9155 +               inode->i_uid, inode->i_tag));
9156 +       fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode),
9157 +               inode->i_gid, inode->i_tag));
9158 +       /* i_tag = = cpu_to_le16(inode->i_tag); */
9159         fe->i_mode = cpu_to_le16(inode->i_mode);
9160         fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
9161         fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
9162 @@ -1257,15 +1305,24 @@ leave:
9163  void ocfs2_refresh_inode(struct inode *inode,
9164                          struct ocfs2_dinode *fe)
9165  {
9166 +       uid_t uid;
9167 +       gid_t gid;
9168 +
9169         spin_lock(&OCFS2_I(inode)->ip_lock);
9170  
9171         OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
9172         OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
9173 +       /* OCFS2_I(inode)->ip_flags &= ~OCFS2_FL_MASK;
9174 +          OCFS2_I(inode)->ip_flags |= le32_to_cpu(fe->i_flags) & OCFS2_FL_MASK; */
9175         ocfs2_set_inode_flags(inode);
9176         i_size_write(inode, le64_to_cpu(fe->i_size));
9177         inode->i_nlink = le16_to_cpu(fe->i_links_count);
9178 -       inode->i_uid = le32_to_cpu(fe->i_uid);
9179 -       inode->i_gid = le32_to_cpu(fe->i_gid);
9180 +       uid = le32_to_cpu(fe->i_uid);
9181 +       gid = le32_to_cpu(fe->i_gid);
9182 +       inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
9183 +       inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
9184 +       inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid,
9185 +               /* le16_to_cpu(raw_inode->i_raw_tag)i */ 0);
9186         inode->i_mode = le16_to_cpu(fe->i_mode);
9187         if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)
9188                 inode->i_blocks = 0;
9189 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/inode.h linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/inode.h
9190 --- linux-2.6.19.1/fs/ocfs2/inode.h     2006-11-30 21:19:28 +0100
9191 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/inode.h   2006-11-08 04:57:46 +0100
9192 @@ -150,5 +150,6 @@ int ocfs2_aio_read(struct file *file, st
9193  int ocfs2_aio_write(struct file *file, struct kiocb *req, struct iocb *iocb);
9194  
9195  void ocfs2_set_inode_flags(struct inode *inode);
9196 +int ocfs2_sync_flags(struct inode *inode);
9197  
9198  #endif /* OCFS2_INODE_H */
9199 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ioctl.c
9200 --- linux-2.6.19.1/fs/ocfs2/ioctl.c     2006-11-30 21:19:28 +0100
9201 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ioctl.c   2006-12-02 01:28:36 +0100
9202 @@ -38,7 +38,7 @@ static int ocfs2_get_inode_attr(struct i
9203         return status;
9204  }
9205  
9206 -static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
9207 +int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
9208                                 unsigned mask)
9209  {
9210         struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
9211 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/ioctl.h linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ioctl.h
9212 --- linux-2.6.19.1/fs/ocfs2/ioctl.h     2006-11-30 21:19:28 +0100
9213 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ioctl.h   2006-12-02 01:29:36 +0100
9214 @@ -10,6 +10,9 @@
9215  #ifndef OCFS2_IOCTL_H
9216  #define OCFS2_IOCTL_H
9217  
9218 +int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
9219 +                               unsigned mask);
9220 +
9221  int ocfs2_ioctl(struct inode * inode, struct file * filp,
9222         unsigned int cmd, unsigned long arg);
9223  
9224 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/namei.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/namei.c
9225 --- linux-2.6.19.1/fs/ocfs2/namei.c     2006-11-30 21:19:28 +0100
9226 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/namei.c   2006-11-08 04:57:52 +0100
9227 @@ -40,6 +40,7 @@
9228  #include <linux/types.h>
9229  #include <linux/slab.h>
9230  #include <linux/highmem.h>
9231 +#include <linux/vs_tag.h>
9232  
9233  #define MLOG_MASK_PREFIX ML_NAMEI
9234  #include <cluster/masklog.h>
9235 @@ -497,6 +498,9 @@ static int ocfs2_mknod_locked(struct ocf
9236         u64 fe_blkno = 0;
9237         u16 suballoc_bit;
9238         struct inode *inode = NULL;
9239 +       uid_t uid;
9240 +       gid_t gid;
9241 +       tag_t tag;
9242  
9243         mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
9244                    (unsigned long)dev, dentry->d_name.len,
9245 @@ -556,13 +560,19 @@ static int ocfs2_mknod_locked(struct ocf
9246         fe->i_blkno = cpu_to_le64(fe_blkno);
9247         fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
9248         fe->i_suballoc_slot = cpu_to_le16(osb->slot_num);
9249 -       fe->i_uid = cpu_to_le32(current->fsuid);
9250 +
9251 +       tag = dx_current_fstag(osb->sb);
9252 +       uid = current->fsuid;
9253         if (dir->i_mode & S_ISGID) {
9254 -               fe->i_gid = cpu_to_le32(dir->i_gid);
9255 +               gid = dir->i_gid;
9256                 if (S_ISDIR(mode))
9257                         mode |= S_ISGID;
9258         } else
9259 -               fe->i_gid = cpu_to_le32(current->fsgid);
9260 +               gid = current->fsgid;
9261 +
9262 +       fe->i_uid = cpu_to_le32(TAGINO_UID(DX_TAG(inode), uid, tag));
9263 +       fe->i_gid = cpu_to_le32(TAGINO_GID(DX_TAG(inode), gid, tag));
9264 +       inode->i_tag = tag;
9265         fe->i_mode = cpu_to_le16(mode);
9266         if (S_ISCHR(mode) || S_ISBLK(mode))
9267                 fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
9268 @@ -2300,4 +2310,5 @@ struct inode_operations ocfs2_dir_iops =
9269         .rename         = ocfs2_rename,
9270         .setattr        = ocfs2_setattr,
9271         .getattr        = ocfs2_getattr,
9272 +       .sync_flags     = ocfs2_sync_flags,
9273  };
9274 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/ocfs2.h linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ocfs2.h
9275 --- linux-2.6.19.1/fs/ocfs2/ocfs2.h     2006-09-20 16:58:35 +0200
9276 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ocfs2.h   2006-11-08 04:57:52 +0100
9277 @@ -174,6 +174,7 @@ enum ocfs2_mount_options
9278         OCFS2_MOUNT_NOINTR  = 1 << 2,   /* Don't catch signals */
9279         OCFS2_MOUNT_ERRORS_PANIC = 1 << 3, /* Panic on errors */
9280         OCFS2_MOUNT_DATA_WRITEBACK = 1 << 4, /* No data ordering */
9281 +       OCFS2_MOUNT_TAGGED = 1 << 8, /* use tagging */
9282  };
9283  
9284  #define OCFS2_OSB_SOFT_RO      0x0001
9285 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/ocfs2_fs.h linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ocfs2_fs.h
9286 --- linux-2.6.19.1/fs/ocfs2/ocfs2_fs.h  2006-11-30 21:19:28 +0100
9287 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/ocfs2_fs.h        2006-12-02 01:33:58 +0100
9288 @@ -125,8 +125,12 @@
9289  #define OCFS2_NOATIME_FL       (0x00000080)    /* do not update atime */
9290  #define OCFS2_DIRSYNC_FL       (0x00010000)    /* dirsync behaviour (directories only) */
9291  
9292 +#define OCFS2_BARRIER_FL       (0x04000000)    /* Barrier for chroot() */
9293 +#define OCFS2_IUNLINK_FL       (0x08000000)    /* Immutable unlink */
9294 +
9295  #define OCFS2_FL_VISIBLE       (0x000100FF)    /* User visible flags */
9296  #define OCFS2_FL_MODIFIABLE    (0x000100FF)    /* User modifiable flags */
9297 +#define OCFS2_FL_MASK          (0x0F0100FF)
9298  
9299  /*
9300   * ioctl commands
9301 diff -NurpP --minimal linux-2.6.19.1/fs/ocfs2/super.c linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/super.c
9302 --- linux-2.6.19.1/fs/ocfs2/super.c     2006-11-30 21:19:28 +0100
9303 +++ linux-2.6.19.1-vs2.3.0.6/fs/ocfs2/super.c   2006-11-08 04:57:52 +0100
9304 @@ -141,6 +141,7 @@ enum {
9305         Opt_hb_local,
9306         Opt_data_ordered,
9307         Opt_data_writeback,
9308 +       Opt_tag, Opt_notag, Opt_tagid,
9309         Opt_err,
9310  };
9311  
9312 @@ -154,6 +155,10 @@ static match_table_t tokens = {
9313         {Opt_hb_local, OCFS2_HB_LOCAL},
9314         {Opt_data_ordered, "data=ordered"},
9315         {Opt_data_writeback, "data=writeback"},
9316 +       {Opt_tag, "tag"},
9317 +       {Opt_tag, "tagxid"},
9318 +       {Opt_notag, "notag"},
9319 +       {Opt_tagid, "tagid=%u"},
9320         {Opt_err, NULL}
9321  };
9322  
9323 @@ -362,6 +367,14 @@ static int ocfs2_remount(struct super_bl
9324                 goto out;
9325         }
9326  
9327 +       printk("ocfs2_remount: %lx,%lx\n", osb->s_mount_opt, sb->s_flags);
9328 +       if ((parsed_options & OCFS2_MOUNT_TAGGED) &&
9329 +               !(sb->s_flags & MS_TAGGED)) {
9330 +               ret = -EINVAL;
9331 +               mlog(ML_ERROR, "Cannot change tagging on remount\n");
9332 +               goto out;
9333 +       }
9334 +
9335         if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) !=
9336             (parsed_options & OCFS2_MOUNT_HB_LOCAL)) {
9337                 ret = -EINVAL;
9338 @@ -635,6 +648,9 @@ static int ocfs2_fill_super(struct super
9339  
9340         ocfs2_complete_mount_recovery(osb);
9341  
9342 +       if (osb->s_mount_opt & OCFS2_MOUNT_TAGGED)
9343 +               sb->s_flags |= MS_TAGGED;
9344 +
9345         printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %d, slot %d) "
9346                "with %s data mode.\n",
9347                osb->dev_str, osb->node_num, osb->slot_num,
9348 @@ -747,6 +763,20 @@ static int ocfs2_parse_options(struct su
9349                 case Opt_data_writeback:
9350                         *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK;
9351                         break;
9352 +#ifndef CONFIG_TAGGING_NONE
9353 +               case Opt_tag:
9354 +                       *mount_opt |= OCFS2_MOUNT_TAGGED;
9355 +                       break;
9356 +               case Opt_notag:
9357 +                       *mount_opt &= ~OCFS2_MOUNT_TAGGED;
9358 +                       break;
9359 +#endif
9360 +#ifdef CONFIG_PROPAGATE
9361 +               case Opt_tagid:
9362 +                       /* use args[0] */
9363 +                       *mount_opt |= OCFS2_MOUNT_TAGGED;
9364 +                       break;
9365 +#endif
9366                 default:
9367                         mlog(ML_ERROR,
9368                              "Unrecognized mount option \"%s\" "
9369 diff -NurpP --minimal linux-2.6.19.1/fs/open.c linux-2.6.19.1-vs2.3.0.6/fs/open.c
9370 --- linux-2.6.19.1/fs/open.c    2006-11-30 21:19:28 +0100
9371 +++ linux-2.6.19.1-vs2.3.0.6/fs/open.c  2006-11-30 18:53:18 +0100
9372 @@ -27,22 +27,31 @@
9373  #include <linux/syscalls.h>
9374  #include <linux/rcupdate.h>
9375  #include <linux/audit.h>
9376 +#include <linux/vs_base.h>
9377 +#include <linux/vs_limit.h>
9378 +#include <linux/vs_dlimit.h>
9379 +#include <linux/vs_tag.h>
9380 +#include <linux/vs_cowbl.h>
9381  
9382  int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
9383  {
9384         int retval = -ENODEV;
9385  
9386         if (dentry) {
9387 +               struct super_block *sb = dentry->d_sb;
9388 +
9389                 retval = -ENOSYS;
9390 -               if (dentry->d_sb->s_op->statfs) {
9391 +               if (sb->s_op->statfs) {
9392                         memset(buf, 0, sizeof(*buf));
9393                         retval = security_sb_statfs(dentry);
9394                         if (retval)
9395                                 return retval;
9396 -                       retval = dentry->d_sb->s_op->statfs(dentry, buf);
9397 +                       retval = sb->s_op->statfs(dentry, buf);
9398                         if (retval == 0 && buf->f_frsize == 0)
9399                                 buf->f_frsize = buf->f_bsize;
9400                 }
9401 +               if (!vx_check(0, VS_ADMIN|VS_WATCH))
9402 +                       vx_vsi_statfs(sb, buf);
9403         }
9404         return retval;
9405  }
9406 @@ -246,7 +255,7 @@ static long do_sys_truncate(const char _
9407                 goto dput_and_out;
9408  
9409         error = -EROFS;
9410 -       if (IS_RDONLY(inode))
9411 +       if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
9412                 goto dput_and_out;
9413  
9414         error = -EPERM;
9415 @@ -395,7 +404,7 @@ asmlinkage long sys_faccessat(int dfd, c
9416            special_file(nd.dentry->d_inode->i_mode))
9417                 goto out_path_release;
9418  
9419 -       if(IS_RDONLY(nd.dentry->d_inode))
9420 +       if(IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
9421                 res = -EROFS;
9422  
9423  out_path_release:
9424 @@ -509,7 +518,7 @@ asmlinkage long sys_fchmod(unsigned int 
9425         audit_inode(NULL, inode);
9426  
9427         err = -EROFS;
9428 -       if (IS_RDONLY(inode))
9429 +       if (IS_RDONLY(inode) || MNT_IS_RDONLY(file->f_vfsmnt))
9430                 goto out_putf;
9431         err = -EPERM;
9432         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9433 @@ -539,11 +548,11 @@ asmlinkage long sys_fchmodat(int dfd, co
9434         error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
9435         if (error)
9436                 goto out;
9437 -       inode = nd.dentry->d_inode;
9438  
9439 -       error = -EROFS;
9440 -       if (IS_RDONLY(inode))
9441 +       error = cow_check_and_break(&nd);
9442 +       if (error)
9443                 goto dput_and_out;
9444 +       inode = nd.dentry->d_inode;
9445  
9446         error = -EPERM;
9447         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9448 @@ -568,7 +577,8 @@ asmlinkage long sys_chmod(const char __u
9449         return sys_fchmodat(AT_FDCWD, filename, mode);
9450  }
9451  
9452 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
9453 +static int chown_common(struct dentry *dentry, struct vfsmount *mnt,
9454 +       uid_t user, gid_t group)
9455  {
9456         struct inode * inode;
9457         int error;
9458 @@ -580,7 +590,7 @@ static int chown_common(struct dentry * 
9459                 goto out;
9460         }
9461         error = -EROFS;
9462 -       if (IS_RDONLY(inode))
9463 +       if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt))
9464                 goto out;
9465         error = -EPERM;
9466         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
9467 @@ -588,11 +598,11 @@ static int chown_common(struct dentry * 
9468         newattrs.ia_valid =  ATTR_CTIME;
9469         if (user != (uid_t) -1) {
9470                 newattrs.ia_valid |= ATTR_UID;
9471 -               newattrs.ia_uid = user;
9472 +               newattrs.ia_uid = dx_map_uid(user);
9473         }
9474         if (group != (gid_t) -1) {
9475                 newattrs.ia_valid |= ATTR_GID;
9476 -               newattrs.ia_gid = group;
9477 +               newattrs.ia_gid = dx_map_gid(group);
9478         }
9479         if (!S_ISDIR(inode->i_mode))
9480                 newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
9481 @@ -611,7 +621,11 @@ asmlinkage long sys_chown(const char __u
9482         error = user_path_walk(filename, &nd);
9483         if (error)
9484                 goto out;
9485 -       error = chown_common(nd.dentry, user, group);
9486 +#ifdef CONFIG_VSERVER_COWBL
9487 +       error = cow_check_and_break(&nd);
9488 +       if (!error)
9489 +#endif
9490 +               error = chown_common(nd.dentry, nd.mnt, user, group);
9491         path_release(&nd);
9492  out:
9493         return error;
9494 @@ -631,7 +645,11 @@ asmlinkage long sys_fchownat(int dfd, co
9495         error = __user_walk_fd(dfd, filename, follow, &nd);
9496         if (error)
9497                 goto out;
9498 -       error = chown_common(nd.dentry, user, group);
9499 +#ifdef CONFIG_VSERVER_COWBL
9500 +       error = cow_check_and_break(&nd);
9501 +       if (!error)
9502 +#endif
9503 +               error = chown_common(nd.dentry, nd.mnt, user, group);
9504         path_release(&nd);
9505  out:
9506         return error;
9507 @@ -645,7 +663,11 @@ asmlinkage long sys_lchown(const char __
9508         error = user_path_walk_link(filename, &nd);
9509         if (error)
9510                 goto out;
9511 -       error = chown_common(nd.dentry, user, group);
9512 +#ifdef CONFIG_VSERVER_COWBL
9513 +       error = cow_check_and_break(&nd);
9514 +       if (!error)
9515 +#endif
9516 +               error = chown_common(nd.dentry, nd.mnt, user, group);
9517         path_release(&nd);
9518  out:
9519         return error;
9520 @@ -664,7 +686,7 @@ asmlinkage long sys_fchown(unsigned int 
9521  
9522         dentry = file->f_dentry;
9523         audit_inode(NULL, dentry->d_inode);
9524 -       error = chown_common(dentry, user, group);
9525 +       error = chown_common(dentry, file->f_vfsmnt, user, group);
9526         fput(file);
9527  out:
9528         return error;
9529 @@ -892,6 +914,7 @@ repeat:
9530         FD_SET(fd, fdt->open_fds);
9531         FD_CLR(fd, fdt->close_on_exec);
9532         files->next_fd = fd + 1;
9533 +       vx_openfd_inc(fd);
9534  #if 1
9535         /* Sanity check */
9536         if (fdt->fd[fd] != NULL) {
9537 @@ -914,6 +937,7 @@ static void __put_unused_fd(struct files
9538         __FD_CLR(fd, fdt->open_fds);
9539         if (fd < files->next_fd)
9540                 files->next_fd = fd;
9541 +       vx_openfd_dec(fd);
9542  }
9543  
9544  void fastcall put_unused_fd(unsigned int fd)
9545 diff -NurpP --minimal linux-2.6.19.1/fs/proc/array.c linux-2.6.19.1-vs2.3.0.6/fs/proc/array.c
9546 --- linux-2.6.19.1/fs/proc/array.c      2006-11-30 21:19:28 +0100
9547 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/array.c    2006-12-17 04:32:56 +0100
9548 @@ -75,6 +75,8 @@
9549  #include <linux/cpuset.h>
9550  #include <linux/rcupdate.h>
9551  #include <linux/delayacct.h>
9552 +#include <linux/vs_context.h>
9553 +#include <linux/vs_network.h>
9554  
9555  #include <asm/uaccess.h>
9556  #include <asm/pgtable.h>
9557 @@ -134,8 +136,9 @@ static const char *task_state_array[] = 
9558         "D (disk sleep)",       /*  2 */
9559         "T (stopped)",          /*  4 */
9560         "T (tracing stop)",     /*  8 */
9561 -       "Z (zombie)",           /* 16 */
9562 -       "X (dead)"              /* 32 */
9563 +       "H (on hold)"           /* 16 */
9564 +       "Z (zombie)",           /* 32 */
9565 +       "X (dead)",             /* 64 */
9566  };
9567  
9568  static inline const char * get_task_state(struct task_struct *tsk)
9569 @@ -144,7 +147,8 @@ static inline const char * get_task_stat
9570                                             TASK_INTERRUPTIBLE |
9571                                             TASK_UNINTERRUPTIBLE |
9572                                             TASK_STOPPED |
9573 -                                           TASK_TRACED)) |
9574 +                                          TASK_TRACED |
9575 +                                          TASK_ONHOLD)) |
9576                         (tsk->exit_state & (EXIT_ZOMBIE |
9577                                             EXIT_DEAD));
9578         const char **p = &task_state_array[0];
9579 @@ -161,8 +165,16 @@ static inline char * task_state(struct t
9580         struct group_info *group_info;
9581         int g;
9582         struct fdtable *fdt = NULL;
9583 +       pid_t pid, ptgid, tppid, tgid;
9584  
9585         rcu_read_lock();
9586 +       tgid = vx_map_tgid(p->tgid);
9587 +       pid = vx_map_pid(p->pid);
9588 +       ptgid = vx_map_pid(pid_alive(p) ?
9589 +               rcu_dereference(p->real_parent)->tgid : 0);
9590 +       tppid = vx_map_pid(pid_alive(p) && p->ptrace ?
9591 +               rcu_dereference(p->parent)->pid : 0);
9592 +
9593         buffer += sprintf(buffer,
9594                 "State:\t%s\n"
9595                 "SleepAVG:\t%lu%%\n"
9596 @@ -174,9 +186,7 @@ static inline char * task_state(struct t
9597                 "Gid:\t%d\t%d\t%d\t%d\n",
9598                 get_task_state(p),
9599                 (p->sleep_avg/1024)*100/(1020000000/1024),
9600 -               p->tgid, p->pid,
9601 -               pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
9602 -               pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
9603 +               tgid, pid, (pid > 1) ? ptgid : 0, tppid,
9604                 p->uid, p->euid, p->suid, p->fsuid,
9605                 p->gid, p->egid, p->sgid, p->fsgid);
9606  
9607 @@ -283,12 +293,15 @@ static inline char * task_sig(struct tas
9608  
9609  static inline char *task_cap(struct task_struct *p, char *buffer)
9610  {
9611 -    return buffer + sprintf(buffer, "CapInh:\t%016x\n"
9612 -                           "CapPrm:\t%016x\n"
9613 -                           "CapEff:\t%016x\n",
9614 -                           cap_t(p->cap_inheritable),
9615 -                           cap_t(p->cap_permitted),
9616 -                           cap_t(p->cap_effective));
9617 +       struct vx_info *vxi = p->vx_info;
9618 +
9619 +       return buffer + sprintf(buffer,
9620 +               "CapInh:\t%016x\n"
9621 +               "CapPrm:\t%016x\n"
9622 +               "CapEff:\t%016x\n",
9623 +               (unsigned)vx_info_mbcap(vxi, p->cap_inheritable),
9624 +               (unsigned)vx_info_mbcap(vxi, p->cap_permitted),
9625 +               (unsigned)vx_info_mbcap(vxi, p->cap_effective));
9626  }
9627  
9628  int proc_pid_status(struct task_struct *task, char * buffer)
9629 @@ -306,6 +319,12 @@ int proc_pid_status(struct task_struct *
9630         buffer = task_sig(task, buffer);
9631         buffer = task_cap(task, buffer);
9632         buffer = cpuset_task_status_allowed(task, buffer);
9633 +
9634 +       if (task_vx_flags(task, VXF_HIDE_VINFO, 0))
9635 +               goto skip;
9636 +       buffer += sprintf (buffer,"VxID: %d\n", vx_task_xid(task));
9637 +       buffer += sprintf (buffer,"NxID: %d\n", nx_task_nid(task));
9638 +skip:
9639  #if defined(CONFIG_S390)
9640         buffer = task_show_regs(task, buffer);
9641  #endif
9642 @@ -320,7 +339,7 @@ static int do_task_stat(struct task_stru
9643         sigset_t sigign, sigcatch;
9644         char state;
9645         int res;
9646 -       pid_t ppid = 0, pgid = -1, sid = -1;
9647 +       pid_t pid = 0, ppid = 0, pgid = -1, sid = -1;
9648         int num_threads = 0;
9649         struct mm_struct *mm;
9650         unsigned long long start_time;
9651 @@ -389,8 +408,10 @@ static int do_task_stat(struct task_stru
9652                 }
9653  
9654                 sid = sig->session;
9655 -               pgid = process_group(task);
9656 -               ppid = rcu_dereference(task->real_parent)->tgid;
9657 +               pid = vx_info_map_pid(task->vx_info, task->pid);
9658 +               pgid = vx_info_map_pid(task->vx_info, process_group(task));
9659 +               ppid = (pid > 1) ? vx_info_map_tgid(task->vx_info,
9660 +                       rcu_dereference(task->real_parent)->tgid) : 0;
9661  
9662                 unlock_task_sighand(task, &flags);
9663         }
9664 @@ -418,10 +439,21 @@ static int do_task_stat(struct task_stru
9665         /* convert nsec -> ticks */
9666         start_time = nsec_to_clock_t(start_time);
9667  
9668 +       /* fixup start time for virt uptime */
9669 +       if (vx_flags(VXF_VIRT_UPTIME, 0)) {
9670 +               unsigned long long bias =
9671 +                       current->vx_info->cvirt.bias_clock;
9672 +
9673 +               if (start_time > bias)
9674 +                       start_time -= bias;
9675 +               else
9676 +                       start_time = 0;
9677 +       }
9678 +
9679         res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
9680  %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
9681  %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu\n",
9682 -               task->pid,
9683 +               pid,
9684                 tcomm,
9685                 state,
9686                 ppid,
9687 diff -NurpP --minimal linux-2.6.19.1/fs/proc/base.c linux-2.6.19.1-vs2.3.0.6/fs/proc/base.c
9688 --- linux-2.6.19.1/fs/proc/base.c       2006-11-30 21:19:28 +0100
9689 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/base.c     2006-12-04 06:53:21 +0100
9690 @@ -73,6 +73,9 @@
9691  #include <linux/poll.h>
9692  #include <linux/nsproxy.h>
9693  #include <linux/oom.h>
9694 +#include <linux/vs_context.h>
9695 +#include <linux/vs_network.h>
9696 +
9697  #include "internal.h"
9698  
9699  /* NOTE:
9700 @@ -971,6 +974,8 @@ static struct inode *proc_pid_make_inode
9701                 inode->i_uid = task->euid;
9702                 inode->i_gid = task->egid;
9703         }
9704 +       /* procfs is xid tagged */
9705 +       inode->i_tag = (tag_t)vx_task_xid(task);
9706         security_task_to_inode(task, inode);
9707  
9708  out:
9709 @@ -1023,7 +1028,13 @@ static int pid_revalidate(struct dentry 
9710  {
9711         struct inode *inode = dentry->d_inode;
9712         struct task_struct *task = get_proc_task(inode);
9713 +       int ret = 0;
9714 +
9715         if (task) {
9716 +               if (!vx_proc_task_visible(task))
9717 +                       goto out_put;
9718 +
9719 +               ret = 1;
9720                 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
9721                     task_dumpable(task)) {
9722                         inode->i_uid = task->euid;
9723 @@ -1034,11 +1045,11 @@ static int pid_revalidate(struct dentry 
9724                 }
9725                 inode->i_mode &= ~(S_ISUID | S_ISGID);
9726                 security_task_to_inode(task, inode);
9727 +       out_put:
9728                 put_task_struct(task);
9729 -               return 1;
9730         }
9731         d_drop(dentry);
9732 -       return 0;
9733 +       return ret;
9734  }
9735  
9736  static int pid_delete_dentry(struct dentry * dentry)
9737 @@ -1404,6 +1415,13 @@ static struct dentry *proc_pident_lookup
9738         if (!task)
9739                 goto out_no_task;
9740  
9741 +       /* FIXME: maybe we can come up with a generic approach? */
9742 +       if (task_vx_flags(task, VXF_HIDE_VINFO, 0) &&
9743 +               (dentry->d_name.len == 5) &&
9744 +               (!memcmp(dentry->d_name.name, "vinfo", 5) ||
9745 +               !memcmp(dentry->d_name.name, "ninfo", 5)))
9746 +               goto out;
9747 +
9748         /*
9749          * Yes, it does not scale. And it should not. Don't add
9750          * new entries into /proc/<tgid>/ without very good reasons.
9751 @@ -1608,14 +1626,14 @@ static int proc_self_readlink(struct den
9752                               int buflen)
9753  {
9754         char tmp[PROC_NUMBUF];
9755 -       sprintf(tmp, "%d", current->tgid);
9756 +       sprintf(tmp, "%d", vx_map_tgid(current->tgid));
9757         return vfs_readlink(dentry,buffer,buflen,tmp);
9758  }
9759  
9760  static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
9761  {
9762         char tmp[PROC_NUMBUF];
9763 -       sprintf(tmp, "%d", current->tgid);
9764 +       sprintf(tmp, "%d", vx_map_tgid(current->tgid));
9765         return ERR_PTR(vfs_follow_link(nd,tmp));
9766  }
9767  
9768 @@ -1709,7 +1727,7 @@ out_iput:
9769  static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry)
9770  {
9771         struct dentry *error;
9772 -       struct task_struct *task = get_proc_task(dir);
9773 +       struct task_struct *task = get_proc_task_real(dir);
9774         struct pid_entry *p, *last;
9775  
9776         error = ERR_PTR(-ENOENT);
9777 @@ -1749,6 +1767,9 @@ static int proc_base_fill_cache(struct f
9778  static struct file_operations proc_task_operations;
9779  static struct inode_operations proc_task_inode_operations;
9780  
9781 +extern int proc_pid_vx_info(struct task_struct *, char *);
9782 +extern int proc_pid_nx_info(struct task_struct *, char *);
9783 +
9784  static struct pid_entry tgid_base_stuff[] = {
9785         DIR("task",       S_IRUGO|S_IXUGO, task),
9786         DIR("fd",         S_IRUSR|S_IXUSR, fd),
9787 @@ -1786,6 +1807,8 @@ static struct pid_entry tgid_base_stuff[
9788  #ifdef CONFIG_CPUSETS
9789         REG("cpuset",     S_IRUGO, cpuset),
9790  #endif
9791 +       INF("vinfo",      S_IRUGO, pid_vx_info),
9792 +       INF("ninfo",      S_IRUGO, pid_nx_info),
9793         INF("oom_score",  S_IRUGO, oom_score),
9794         REG("oom_adj",    S_IRUGO|S_IWUSR, oom_adjust),
9795  #ifdef CONFIG_AUDITSYSCALL
9796 @@ -1927,7 +1950,7 @@ struct dentry *proc_pid_lookup(struct in
9797                 goto out;
9798  
9799         rcu_read_lock();
9800 -       task = find_task_by_pid(tgid);
9801 +       task = vx_find_proc_task_by_pid(tgid);
9802         if (task)
9803                 get_task_struct(task);
9804         rcu_read_unlock();
9805 @@ -1991,7 +2014,7 @@ static int proc_pid_fill_cache(struct fi
9806  int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
9807  {
9808         unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
9809 -       struct task_struct *reaper = get_proc_task(filp->f_dentry->d_inode);
9810 +       struct task_struct *reaper = get_proc_task_real(filp->f_dentry->d_inode);
9811         struct task_struct *task;
9812         int tgid;
9813  
9814 @@ -2010,7 +2033,10 @@ int proc_pid_readdir(struct file * filp,
9815              put_task_struct(task), task = next_tgid(tgid + 1)) {
9816                 tgid = task->pid;
9817                 filp->f_pos = tgid + TGID_OFFSET;
9818 -               if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
9819 +               if (!vx_proc_task_visible(task))
9820 +                       continue;
9821 +               if (proc_pid_fill_cache(filp, dirent, filldir, task,
9822 +                       vx_map_tgid(tgid)) < 0) {
9823                         put_task_struct(task);
9824                         goto out;
9825                 }
9826 @@ -2131,9 +2157,11 @@ static struct dentry *proc_task_lookup(s
9827         tid = name_to_int(dentry);
9828         if (tid == ~0U)
9829                 goto out;
9830 +       if (vx_current_initpid(tid))
9831 +               goto out;
9832  
9833         rcu_read_lock();
9834 -       task = find_task_by_pid(tid);
9835 +       task = vx_find_proc_task_by_pid(tid);
9836         if (task)
9837                 get_task_struct(task);
9838         rcu_read_unlock();
9839 @@ -2268,7 +2296,10 @@ static int proc_task_readdir(struct file
9840         for (task = first_tid(leader, tid, pos - 2);
9841              task;
9842              task = next_tid(task), pos++) {
9843 -               tid = task->pid;
9844 +               tid = vx_map_pid(task->pid);
9845 +               /* FIXME: could go away now! */
9846 +               if (!vx_proc_task_visible(task))
9847 +                       continue;
9848                 if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
9849                         /* returning this tgid failed, save it as the first
9850                          * pid for the next readir call */
9851 diff -NurpP --minimal linux-2.6.19.1/fs/proc/generic.c linux-2.6.19.1-vs2.3.0.6/fs/proc/generic.c
9852 --- linux-2.6.19.1/fs/proc/generic.c    2006-06-18 04:54:45 +0200
9853 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/generic.c  2006-11-08 04:57:41 +0100
9854 @@ -20,6 +20,7 @@
9855  #include <linux/namei.h>
9856  #include <linux/bitops.h>
9857  #include <linux/spinlock.h>
9858 +#include <linux/vserver/inode.h>
9859  #include <asm/uaccess.h>
9860  
9861  #include "internal.h"
9862 @@ -395,12 +396,16 @@ struct dentry *proc_lookup(struct inode 
9863                 for (de = de->subdir; de ; de = de->next) {
9864                         if (de->namelen != dentry->d_name.len)
9865                                 continue;
9866 +                       if (!vx_hide_check(0, de->vx_flags))
9867 +                               continue;
9868                         if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
9869                                 unsigned int ino = de->low_ino;
9870  
9871                                 spin_unlock(&proc_subdir_lock);
9872                                 error = -EINVAL;
9873                                 inode = proc_get_inode(dir->i_sb, ino, de);
9874 +                               /* generic proc entries belong to the host */
9875 +                               inode->i_tag = 0;
9876                                 spin_lock(&proc_subdir_lock);
9877                                 break;
9878                         }
9879 @@ -476,12 +481,15 @@ int proc_readdir(struct file * filp,
9880                         }
9881  
9882                         do {
9883 +                               if (!vx_hide_check(0, de->vx_flags))
9884 +                                       goto skip;
9885                                 /* filldir passes info to user space */
9886                                 spin_unlock(&proc_subdir_lock);
9887                                 if (filldir(dirent, de->name, de->namelen, filp->f_pos,
9888                                             de->low_ino, de->mode >> 12) < 0)
9889                                         goto out;
9890                                 spin_lock(&proc_subdir_lock);
9891 +                       skip:
9892                                 filp->f_pos++;
9893                                 de = de->next;
9894                         } while (de);
9895 @@ -604,6 +612,7 @@ static struct proc_dir_entry *proc_creat
9896         ent->namelen = len;
9897         ent->mode = mode;
9898         ent->nlink = nlink;
9899 +       ent->vx_flags = IATTR_PROC_DEFAULT;
9900   out:
9901         return ent;
9902  }
9903 @@ -624,7 +633,8 @@ struct proc_dir_entry *proc_symlink(cons
9904                                 kfree(ent->data);
9905                                 kfree(ent);
9906                                 ent = NULL;
9907 -                       }
9908 +                       } else
9909 +                               ent->vx_flags = IATTR_PROC_SYMLINK;
9910                 } else {
9911                         kfree(ent);
9912                         ent = NULL;
9913 diff -NurpP --minimal linux-2.6.19.1/fs/proc/inode.c linux-2.6.19.1-vs2.3.0.6/fs/proc/inode.c
9914 --- linux-2.6.19.1/fs/proc/inode.c      2006-09-20 16:58:35 +0200
9915 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/inode.c    2006-11-08 04:57:41 +0100
9916 @@ -168,6 +168,8 @@ struct inode *proc_get_inode(struct supe
9917                         inode->i_uid = de->uid;
9918                         inode->i_gid = de->gid;
9919                 }
9920 +               if (de->vx_flags)
9921 +                       PROC_I(inode)->vx_flags = de->vx_flags;
9922                 if (de->size)
9923                         inode->i_size = de->size;
9924                 if (de->nlink)
9925 diff -NurpP --minimal linux-2.6.19.1/fs/proc/internal.h linux-2.6.19.1-vs2.3.0.6/fs/proc/internal.h
9926 --- linux-2.6.19.1/fs/proc/internal.h   2006-11-30 21:19:28 +0100
9927 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/internal.h 2006-12-04 02:53:55 +0100
9928 @@ -10,6 +10,7 @@
9929   */
9930  
9931  #include <linux/proc_fs.h>
9932 +#include <linux/vs_pid.h>
9933  
9934  struct vmalloc_info {
9935         unsigned long   used;
9936 @@ -56,11 +57,16 @@ static inline struct pid *proc_pid(struc
9937         return PROC_I(inode)->pid;
9938  }
9939  
9940 -static inline struct task_struct *get_proc_task(struct inode *inode)
9941 +static inline struct task_struct *get_proc_task_real(struct inode *inode)
9942  {
9943         return get_pid_task(proc_pid(inode), PIDTYPE_PID);
9944  }
9945  
9946 +static inline struct task_struct *get_proc_task(struct inode *inode)
9947 +{
9948 +       return vx_get_proc_task(inode, proc_pid(inode));
9949 +}
9950 +
9951  static inline int proc_fd(struct inode *inode)
9952  {
9953         return PROC_I(inode)->fd;
9954 diff -NurpP --minimal linux-2.6.19.1/fs/proc/proc_misc.c linux-2.6.19.1-vs2.3.0.6/fs/proc/proc_misc.c
9955 --- linux-2.6.19.1/fs/proc/proc_misc.c  2006-11-30 21:19:28 +0100
9956 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/proc_misc.c        2006-12-06 08:48:35 +0100
9957 @@ -53,6 +53,8 @@
9958  #include <asm/div64.h>
9959  #include "internal.h"
9960  
9961 +#include <linux/vs_cvirt.h>
9962 +
9963  #define LOAD_INT(x) ((x) >> FSHIFT)
9964  #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
9965  /*
9966 @@ -82,17 +84,32 @@ static int proc_calc_metrics(char *page,
9967  static int loadavg_read_proc(char *page, char **start, off_t off,
9968                                  int count, int *eof, void *data)
9969  {
9970 +       unsigned int running, threads;
9971         int a, b, c;
9972         int len;
9973  
9974 -       a = avenrun[0] + (FIXED_1/200);
9975 -       b = avenrun[1] + (FIXED_1/200);
9976 -       c = avenrun[2] + (FIXED_1/200);
9977 -       len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
9978 +       if (vx_flags(VXF_VIRT_LOAD, 0)) {
9979 +               struct vx_info *vxi = current->vx_info;
9980 +
9981 +               a = vxi->cvirt.load[0] + (FIXED_1/200);
9982 +               b = vxi->cvirt.load[1] + (FIXED_1/200);
9983 +               c = vxi->cvirt.load[2] + (FIXED_1/200);
9984 +
9985 +               running = atomic_read(&vxi->cvirt.nr_running);
9986 +               threads = atomic_read(&vxi->cvirt.nr_threads);
9987 +       } else {
9988 +               a = avenrun[0] + (FIXED_1/200);
9989 +               b = avenrun[1] + (FIXED_1/200);
9990 +               c = avenrun[2] + (FIXED_1/200);
9991 +
9992 +               running = nr_running();
9993 +               threads = nr_threads;
9994 +       }
9995 +       len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
9996                 LOAD_INT(a), LOAD_FRAC(a),
9997                 LOAD_INT(b), LOAD_FRAC(b),
9998                 LOAD_INT(c), LOAD_FRAC(c),
9999 -               nr_running(), nr_threads, init_pspace.last_pid);
10000 +               running, threads, init_pspace.last_pid);
10001         return proc_calc_metrics(page, start, off, count, eof, len);
10002  }
10003  
10004 @@ -106,6 +123,9 @@ static int uptime_read_proc(char *page, 
10005  
10006         do_posix_clock_monotonic_gettime(&uptime);
10007         cputime_to_timespec(idletime, &idle);
10008 +       if (vx_flags(VXF_VIRT_UPTIME, 0))
10009 +               vx_vsi_uptime(&uptime, &idle);
10010 +
10011         len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
10012                         (unsigned long) uptime.tv_sec,
10013                         (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
10014 @@ -142,7 +162,7 @@ static int meminfo_read_proc(char *page,
10015  
10016         cached = global_page_state(NR_FILE_PAGES) -
10017                         total_swapcache_pages - i.bufferram;
10018 -       if (cached < 0)
10019 +       if (cached < 0 || vx_flags(VXF_VIRT_MEM, 0))
10020                 cached = 0;
10021  
10022         get_vmalloc_info(&vmi);
10023 @@ -252,8 +272,8 @@ static int version_read_proc(char *page,
10024  {
10025         int len;
10026  
10027 -       strcpy(page, linux_banner);
10028 -       len = strlen(page);
10029 +       len = sprintf(page, linux_banner,
10030 +               utsname()->release, utsname()->version);
10031         return proc_calc_metrics(page, start, off, count, eof, len);
10032  }
10033  
10034 diff -NurpP --minimal linux-2.6.19.1/fs/proc/root.c linux-2.6.19.1-vs2.3.0.6/fs/proc/root.c
10035 --- linux-2.6.19.1/fs/proc/root.c       2006-11-30 21:19:28 +0100
10036 +++ linux-2.6.19.1-vs2.3.0.6/fs/proc/root.c     2006-11-08 04:57:41 +0100
10037 @@ -25,6 +25,9 @@ struct proc_dir_entry *proc_net, *proc_n
10038  #ifdef CONFIG_SYSCTL
10039  struct proc_dir_entry *proc_sys_root;
10040  #endif
10041 +struct proc_dir_entry *proc_virtual;
10042 +
10043 +extern void proc_vx_init(void);
10044  
10045  static int proc_get_sb(struct file_system_type *fs_type,
10046         int flags, const char *dev_name, void *data, struct vfsmount *mnt)
10047 @@ -89,6 +92,7 @@ void __init proc_root_init(void)
10048         proc_device_tree_init();
10049  #endif
10050         proc_bus = proc_mkdir("bus", NULL);
10051 +       proc_vx_init();
10052  }
10053  
10054  static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
10055 diff -NurpP --minimal linux-2.6.19.1/fs/quota.c linux-2.6.19.1-vs2.3.0.6/fs/quota.c
10056 --- linux-2.6.19.1/fs/quota.c   2006-11-30 21:19:28 +0100
10057 +++ linux-2.6.19.1-vs2.3.0.6/fs/quota.c 2006-12-01 22:46:55 +0100
10058 @@ -17,47 +17,122 @@
10059  #include <linux/buffer_head.h>
10060  #include <linux/capability.h>
10061  #include <linux/quotaops.h>
10062 +#include <linux/major.h>
10063 +#include <linux/blkdev.h>
10064 +#include <linux/vs_context.h>
10065 +
10066 +
10067 +/* Dquota Hash Management Functions */
10068 +
10069 +static LIST_HEAD(dqhash_list);
10070 +
10071 +struct dqhash *new_dqhash(struct super_block *sb, unsigned int id)
10072 +{
10073 +       struct dqhash *hash;
10074 +       int err;
10075 +
10076 +       err = -ENOMEM;
10077 +       hash = kmalloc(sizeof(struct dqhash),  GFP_USER);
10078 +       if (!hash)
10079 +               goto out;
10080 +
10081 +       memset(hash, 0, sizeof(struct dqhash));
10082 +       hash->dqh_id = id;
10083 +       atomic_set(&hash->dqh_count, 1);
10084 +
10085 +       INIT_LIST_HEAD(&hash->dqh_list);
10086 +
10087 +       mutex_init(&hash->dqh_dqopt.dqio_mutex);
10088 +       mutex_init(&hash->dqh_dqopt.dqonoff_mutex);
10089 +       init_rwsem(&hash->dqh_dqopt.dqptr_sem);
10090 +       hash->dqh_qop = sb->s_qop;
10091 +       hash->dqh_qcop = sb->s_qcop;
10092 +       hash->dqh_sb = sb;
10093 +
10094 +       lock_kernel();
10095 +       list_add(&hash->dqh_list, &dqhash_list);
10096 +       unlock_kernel();
10097 +       vxdprintk(VXD_CBIT(misc, 0),
10098 +               "new_dqhash: %p [#0x%08x]", hash, hash->dqh_id);
10099 +       return hash;
10100 +
10101 +       // kfree(hash);
10102 +out:
10103 +       return ERR_PTR(err);
10104 +}
10105 +
10106 +void destroy_dqhash(struct dqhash *hash)
10107 +{
10108 +       vxdprintk(VXD_CBIT(misc, 0),
10109 +               "destroy_dqhash: %p [#0x%08x] c=%d",
10110 +               hash, hash->dqh_id, atomic_read(&hash->dqh_count));
10111 +       lock_kernel();
10112 +       list_del_init(&hash->dqh_list);
10113 +       unlock_kernel();
10114 +       kfree(hash);
10115 +}
10116 +
10117 +
10118 +struct dqhash *find_dqhash(unsigned int id)
10119 +{
10120 +       struct list_head *head;
10121 +       struct dqhash *hash;
10122 +
10123 +       lock_kernel();
10124 +       list_for_each(head, &dqhash_list) {
10125 +               hash = list_entry(head, struct dqhash, dqh_list);
10126 +               if (hash->dqh_id == id)
10127 +                       goto dqh_found;
10128 +       }
10129 +       unlock_kernel();
10130 +       return NULL;
10131 +
10132 +dqh_found:
10133 +       unlock_kernel();
10134 +       return dqhget(hash);
10135 +}
10136 +
10137  
10138  /* Check validity of generic quotactl commands */
10139 -static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
10140 +static int generic_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id)
10141  {
10142         if (type >= MAXQUOTAS)
10143                 return -EINVAL;
10144 -       if (!sb && cmd != Q_SYNC)
10145 +       if (!hash && cmd != Q_SYNC)
10146                 return -ENODEV;
10147         /* Is operation supported? */
10148 -       if (sb && !sb->s_qcop)
10149 +       if (hash && !hash->dqh_qcop)
10150                 return -ENOSYS;
10151  
10152         switch (cmd) {
10153                 case Q_GETFMT:
10154                         break;
10155                 case Q_QUOTAON:
10156 -                       if (!sb->s_qcop->quota_on)
10157 +                       if (!hash->dqh_qcop->quota_on)
10158                                 return -ENOSYS;
10159                         break;
10160                 case Q_QUOTAOFF:
10161 -                       if (!sb->s_qcop->quota_off)
10162 +                       if (!hash->dqh_qcop->quota_off)
10163                                 return -ENOSYS;
10164                         break;
10165                 case Q_SETINFO:
10166 -                       if (!sb->s_qcop->set_info)
10167 +                       if (!hash->dqh_qcop->set_info)
10168                                 return -ENOSYS;
10169                         break;
10170                 case Q_GETINFO:
10171 -                       if (!sb->s_qcop->get_info)
10172 +                       if (!hash->dqh_qcop->get_info)
10173                                 return -ENOSYS;
10174                         break;
10175                 case Q_SETQUOTA:
10176 -                       if (!sb->s_qcop->set_dqblk)
10177 +                       if (!hash->dqh_qcop->set_dqblk)
10178                                 return -ENOSYS;
10179                         break;
10180                 case Q_GETQUOTA:
10181 -                       if (!sb->s_qcop->get_dqblk)
10182 +                       if (!hash->dqh_qcop->get_dqblk)
10183                                 return -ENOSYS;
10184                         break;
10185                 case Q_SYNC:
10186 -                       if (sb && !sb->s_qcop->quota_sync)
10187 +                       if (hash && !hash->dqh_qcop->quota_sync)
10188                                 return -ENOSYS;
10189                         break;
10190                 default:
10191 @@ -73,7 +148,7 @@ static int generic_quotactl_valid(struct
10192                 case Q_SETQUOTA:
10193                 case Q_GETQUOTA:
10194                         /* This is just informative test so we are satisfied without a lock */
10195 -                       if (!sb_has_quota_enabled(sb, type))
10196 +                       if (!dqh_has_quota_enabled(hash, type))
10197                                 return -ESRCH;
10198         }
10199  
10200 @@ -81,47 +156,47 @@ static int generic_quotactl_valid(struct
10201         if (cmd == Q_GETQUOTA) {
10202                 if (((type == USRQUOTA && current->euid != id) ||
10203                      (type == GRPQUOTA && !in_egroup_p(id))) &&
10204 -                   !capable(CAP_SYS_ADMIN))
10205 +                   !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10206                         return -EPERM;
10207         }
10208         else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO)
10209 -               if (!capable(CAP_SYS_ADMIN))
10210 +               if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10211                         return -EPERM;
10212  
10213         return 0;
10214  }
10215  
10216  /* Check validity of XFS Quota Manager commands */
10217 -static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
10218 +static int xqm_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id)
10219  {
10220         if (type >= XQM_MAXQUOTAS)
10221                 return -EINVAL;
10222 -       if (!sb)
10223 +       if (!hash)
10224                 return -ENODEV;
10225 -       if (!sb->s_qcop)
10226 +       if (!hash->dqh_qcop)
10227                 return -ENOSYS;
10228  
10229         switch (cmd) {
10230                 case Q_XQUOTAON:
10231                 case Q_XQUOTAOFF:
10232                 case Q_XQUOTARM:
10233 -                       if (!sb->s_qcop->set_xstate)
10234 +                       if (!hash->dqh_qcop->set_xstate)
10235                                 return -ENOSYS;
10236                         break;
10237                 case Q_XGETQSTAT:
10238 -                       if (!sb->s_qcop->get_xstate)
10239 +                       if (!hash->dqh_qcop->get_xstate)
10240                                 return -ENOSYS;
10241                         break;
10242                 case Q_XSETQLIM:
10243 -                       if (!sb->s_qcop->set_xquota)
10244 +                       if (!hash->dqh_qcop->set_xquota)
10245                                 return -ENOSYS;
10246                         break;
10247                 case Q_XGETQUOTA:
10248 -                       if (!sb->s_qcop->get_xquota)
10249 +                       if (!hash->dqh_qcop->get_xquota)
10250                                 return -ENOSYS;
10251                         break;
10252                 case Q_XQUOTASYNC:
10253 -                       if (!sb->s_qcop->quota_sync)
10254 +                       if (!hash->dqh_qcop->quota_sync)
10255                                 return -ENOSYS;
10256                         break;
10257                 default:
10258 @@ -132,57 +207,68 @@ static int xqm_quotactl_valid(struct sup
10259         if (cmd == Q_XGETQUOTA) {
10260                 if (((type == XQM_USRQUOTA && current->euid != id) ||
10261                      (type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
10262 -                    !capable(CAP_SYS_ADMIN))
10263 +                    !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10264                         return -EPERM;
10265         } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) {
10266 -               if (!capable(CAP_SYS_ADMIN))
10267 +               if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
10268                         return -EPERM;
10269         }
10270  
10271         return 0;
10272  }
10273  
10274 -static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
10275 +static int check_quotactl_valid(struct dqhash *hash, int type, int cmd, qid_t id)
10276  {
10277         int error;
10278  
10279         if (XQM_COMMAND(cmd))
10280 -               error = xqm_quotactl_valid(sb, type, cmd, id);
10281 +               error = xqm_quotactl_valid(hash, type, cmd, id);
10282         else
10283 -               error = generic_quotactl_valid(sb, type, cmd, id);
10284 +               error = generic_quotactl_valid(hash, type, cmd, id);
10285         if (!error)
10286 -               error = security_quotactl(cmd, type, id, sb);
10287 +               error = security_quotactl(cmd, type, id, hash);
10288         return error;
10289  }
10290  
10291 -static void quota_sync_sb(struct super_block *sb, int type)
10292 +static void quota_sync_sb(struct super_block *sb)
10293  {
10294 -       int cnt;
10295 -       struct inode *discard[MAXQUOTAS];
10296 -
10297 -       sb->s_qcop->quota_sync(sb, type);
10298         /* This is not very clever (and fast) but currently I don't know about
10299          * any other simple way of getting quota data to disk and we must get
10300          * them there for userspace to be visible... */
10301         if (sb->s_op->sync_fs)
10302                 sb->s_op->sync_fs(sb, 1);
10303         sync_blockdev(sb->s_bdev);
10304 +}
10305 +
10306 +static void quota_sync_dqh(struct dqhash *hash, int type)
10307 +{
10308 +       int cnt;
10309 +       struct inode *discard[MAXQUOTAS];
10310 +
10311 +       vxdprintk(VXD_CBIT(quota, 1),
10312 +               "quota_sync_dqh(%p,%d)", hash, type);
10313 +       hash->dqh_qcop->quota_sync(hash, type);
10314 +
10315 +       quota_sync_sb(hash->dqh_sb);
10316  
10317         /* Now when everything is written we can discard the pagecache so
10318          * that userspace sees the changes. We need i_mutex and so we could
10319          * not do it inside dqonoff_mutex. Moreover we need to be carefull
10320          * about races with quotaoff() (that is the reason why we have own
10321          * reference to inode). */
10322 -       mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
10323 +       mutex_lock(&dqh_dqopt(hash)->dqonoff_mutex);
10324         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
10325                 discard[cnt] = NULL;
10326                 if (type != -1 && cnt != type)
10327                         continue;
10328 -               if (!sb_has_quota_enabled(sb, cnt))
10329 +               if (!dqh_has_quota_enabled(hash, cnt))
10330                         continue;
10331 -               discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]);
10332 +               vxdprintk(VXD_CBIT(quota, 0),
10333 +                       "quota_sync_dqh(%p,%d) discard inode %p",
10334 +                       hash, type, dqh_dqopt(hash)->files[cnt]);
10335 +               discard[cnt] = igrab(dqh_dqopt(hash)->files[cnt]);
10336         }
10337 -       mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
10338 +       mutex_unlock(&dqh_dqopt(hash)->dqonoff_mutex);
10339         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
10340                 if (discard[cnt]) {
10341                         mutex_lock(&discard[cnt]->i_mutex);
10342 @@ -193,67 +279,59 @@ static void quota_sync_sb(struct super_b
10343         }
10344  }
10345  
10346 -void sync_dquots(struct super_block *sb, int type)
10347 +void sync_dquots_dqh(struct dqhash *hash, int type)
10348  {
10349 -       int cnt, dirty;
10350 +       vxdprintk(VXD_CBIT(quota, 1),
10351 +               "sync_dquots_dqh(%p,%d)", hash, type);
10352  
10353 -       if (sb) {
10354 -               if (sb->s_qcop->quota_sync)
10355 -                       quota_sync_sb(sb, type);
10356 -               return;
10357 -       }
10358 +       if (hash->dqh_qcop->quota_sync)
10359 +               quota_sync_dqh(hash, type);
10360 +}
10361  
10362 -       spin_lock(&sb_lock);
10363 -restart:
10364 -       list_for_each_entry(sb, &super_blocks, s_list) {
10365 -               /* This test just improves performance so it needn't be reliable... */
10366 -               for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
10367 -                       if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
10368 -                           && info_any_dirty(&sb_dqopt(sb)->info[cnt]))
10369 -                               dirty = 1;
10370 -               if (!dirty)
10371 -                       continue;
10372 -               sb->s_count++;
10373 -               spin_unlock(&sb_lock);
10374 -               down_read(&sb->s_umount);
10375 -               if (sb->s_root && sb->s_qcop->quota_sync)
10376 -                       quota_sync_sb(sb, type);
10377 -               up_read(&sb->s_umount);
10378 -               spin_lock(&sb_lock);
10379 -               if (__put_super_and_need_restart(sb))
10380 -                       goto restart;
10381 +void sync_dquots(struct dqhash *hash, int type)
10382 +
10383 +{
10384 +       vxdprintk(VXD_CBIT(quota, 1),
10385 +               "sync_dquots(%p,%d)", hash, type);
10386 +
10387 +       if (hash) {
10388 +               if (hash->dqh_qcop->quota_sync)
10389 +                       quota_sync_dqh(hash, type);
10390 +               return;
10391         }
10392 -       spin_unlock(&sb_lock);
10393  }
10394  
10395  /* Copy parameters and call proper function */
10396 -static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void __user *addr)
10397 +static int do_quotactl(struct dqhash *hash, int type, int cmd, qid_t id, void __user *addr)
10398  {
10399         int ret;
10400  
10401 +       vxdprintk(VXD_CBIT(quota, 3),
10402 +               "do_quotactl(%p,%d,cmd=%d,id=%d,%p)", hash, type, cmd, id, addr);
10403 +
10404         switch (cmd) {
10405                 case Q_QUOTAON: {
10406                         char *pathname;
10407  
10408                         if (IS_ERR(pathname = getname(addr)))
10409                                 return PTR_ERR(pathname);
10410 -                       ret = sb->s_qcop->quota_on(sb, type, id, pathname);
10411 +                       ret = hash->dqh_qcop->quota_on(hash, type, id, pathname);
10412                         putname(pathname);
10413                         return ret;
10414                 }
10415                 case Q_QUOTAOFF:
10416 -                       return sb->s_qcop->quota_off(sb, type);
10417 +                       return hash->dqh_qcop->quota_off(hash, type);
10418  
10419                 case Q_GETFMT: {
10420                         __u32 fmt;
10421  
10422 -                       down_read(&sb_dqopt(sb)->dqptr_sem);
10423 -                       if (!sb_has_quota_enabled(sb, type)) {
10424 -                               up_read(&sb_dqopt(sb)->dqptr_sem);
10425 +                       down_read(&dqh_dqopt(hash)->dqptr_sem);
10426 +                       if (!dqh_has_quota_enabled(hash, type)) {
10427 +                               up_read(&dqh_dqopt(hash)->dqptr_sem);
10428                                 return -ESRCH;
10429                         }
10430 -                       fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
10431 -                       up_read(&sb_dqopt(sb)->dqptr_sem);
10432 +                       fmt = dqh_dqopt(hash)->info[type].dqi_format->qf_fmt_id;
10433 +                       up_read(&dqh_dqopt(hash)->dqptr_sem);
10434                         if (copy_to_user(addr, &fmt, sizeof(fmt)))
10435                                 return -EFAULT;
10436                         return 0;
10437 @@ -261,7 +339,7 @@ static int do_quotactl(struct super_bloc
10438                 case Q_GETINFO: {
10439                         struct if_dqinfo info;
10440  
10441 -                       if ((ret = sb->s_qcop->get_info(sb, type, &info)))
10442 +                       if ((ret = hash->dqh_qcop->get_info(hash, type, &info)))
10443                                 return ret;
10444                         if (copy_to_user(addr, &info, sizeof(info)))
10445                                 return -EFAULT;
10446 @@ -272,12 +350,12 @@ static int do_quotactl(struct super_bloc
10447  
10448                         if (copy_from_user(&info, addr, sizeof(info)))
10449                                 return -EFAULT;
10450 -                       return sb->s_qcop->set_info(sb, type, &info);
10451 +                       return hash->dqh_qcop->set_info(hash, type, &info);
10452                 }
10453                 case Q_GETQUOTA: {
10454                         struct if_dqblk idq;
10455  
10456 -                       if ((ret = sb->s_qcop->get_dqblk(sb, type, id, &idq)))
10457 +                       if ((ret = hash->dqh_qcop->get_dqblk(hash, type, id, &idq)))
10458                                 return ret;
10459                         if (copy_to_user(addr, &idq, sizeof(idq)))
10460                                 return -EFAULT;
10461 @@ -288,10 +366,10 @@ static int do_quotactl(struct super_bloc
10462  
10463                         if (copy_from_user(&idq, addr, sizeof(idq)))
10464                                 return -EFAULT;
10465 -                       return sb->s_qcop->set_dqblk(sb, type, id, &idq);
10466 +                       return hash->dqh_qcop->set_dqblk(hash, type, id, &idq);
10467                 }
10468                 case Q_SYNC:
10469 -                       sync_dquots(sb, type);
10470 +                       sync_dquots_dqh(hash, type);
10471                         return 0;
10472  
10473                 case Q_XQUOTAON:
10474 @@ -301,12 +379,12 @@ static int do_quotactl(struct super_bloc
10475  
10476                         if (copy_from_user(&flags, addr, sizeof(flags)))
10477                                 return -EFAULT;
10478 -                       return sb->s_qcop->set_xstate(sb, flags, cmd);
10479 +                       return hash->dqh_qcop->set_xstate(hash, flags, cmd);
10480                 }
10481                 case Q_XGETQSTAT: {
10482                         struct fs_quota_stat fqs;
10483                 
10484 -                       if ((ret = sb->s_qcop->get_xstate(sb, &fqs)))
10485 +                       if ((ret = hash->dqh_qcop->get_xstate(hash, &fqs)))
10486                                 return ret;
10487                         if (copy_to_user(addr, &fqs, sizeof(fqs)))
10488                                 return -EFAULT;
10489 @@ -317,19 +395,19 @@ static int do_quotactl(struct super_bloc
10490  
10491                         if (copy_from_user(&fdq, addr, sizeof(fdq)))
10492                                 return -EFAULT;
10493 -                      return sb->s_qcop->set_xquota(sb, type, id, &fdq);
10494 +                      return hash->dqh_qcop->set_xquota(hash, type, id, &fdq);
10495                 }
10496                 case Q_XGETQUOTA: {
10497                         struct fs_disk_quota fdq;
10498  
10499 -                       if ((ret = sb->s_qcop->get_xquota(sb, type, id, &fdq)))
10500 +                       if ((ret = hash->dqh_qcop->get_xquota(hash, type, id, &fdq)))
10501                                 return ret;
10502                         if (copy_to_user(addr, &fdq, sizeof(fdq)))
10503                                 return -EFAULT;
10504                         return 0;
10505                 }
10506                 case Q_XQUOTASYNC:
10507 -                       return sb->s_qcop->quota_sync(sb, type);
10508 +                       return hash->dqh_qcop->quota_sync(hash, type);
10509                 /* We never reach here unless validity check is broken */
10510                 default:
10511                         BUG();
10512 @@ -365,6 +443,43 @@ static inline struct super_block *quotac
10513  #endif
10514  }
10515  
10516 +#if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
10517 +
10518 +#include <linux/vroot.h>
10519 +#include <linux/kallsyms.h>
10520 +
10521 +static vroot_grb_func *vroot_get_real_bdev = NULL;
10522 +
10523 +static spinlock_t vroot_grb_lock = SPIN_LOCK_UNLOCKED;
10524 +
10525 +int register_vroot_grb(vroot_grb_func *func) {
10526 +       int ret = -EBUSY;
10527 +
10528 +       spin_lock(&vroot_grb_lock);
10529 +       if (!vroot_get_real_bdev) {
10530 +               vroot_get_real_bdev = func;
10531 +               ret = 0;
10532 +       }
10533 +       spin_unlock(&vroot_grb_lock);
10534 +       return ret;
10535 +}
10536 +EXPORT_SYMBOL(register_vroot_grb);
10537 +
10538 +int unregister_vroot_grb(vroot_grb_func *func) {
10539 +       int ret = -EINVAL;
10540 +
10541 +       spin_lock(&vroot_grb_lock);
10542 +       if (vroot_get_real_bdev) {
10543 +               vroot_get_real_bdev = NULL;
10544 +               ret = 0;
10545 +       }
10546 +       spin_unlock(&vroot_grb_lock);
10547 +       return ret;
10548 +}
10549 +EXPORT_SYMBOL(unregister_vroot_grb);
10550 +
10551 +#endif
10552 +
10553  /*
10554   * This is the system call interface. This communicates with
10555   * the user-level programs. Currently this only supports diskquota
10556 @@ -375,6 +490,7 @@ asmlinkage long sys_quotactl(unsigned in
10557  {
10558         uint cmds, type;
10559         struct super_block *sb = NULL;
10560 +       struct dqhash *dqh = NULL;
10561         int ret;
10562  
10563         cmds = cmd >> SUBCMDSHIFT;
10564 @@ -386,9 +502,11 @@ asmlinkage long sys_quotactl(unsigned in
10565                         return PTR_ERR(sb);
10566         }
10567  
10568 -       ret = check_quotactl_valid(sb, type, cmds, id);
10569 +       if (sb)
10570 +               dqh = sb->s_dqh;
10571 +       ret = check_quotactl_valid(dqh, type, cmds, id);
10572         if (ret >= 0)
10573 -               ret = do_quotactl(sb, type, cmds, id, addr);
10574 +               ret = do_quotactl(dqh, type, cmds, id, addr);
10575         if (sb)
10576                 drop_super(sb);
10577  
10578 diff -NurpP --minimal linux-2.6.19.1/fs/quota_v1.c linux-2.6.19.1-vs2.3.0.6/fs/quota_v1.c
10579 --- linux-2.6.19.1/fs/quota_v1.c        2005-03-02 12:38:45 +0100
10580 +++ linux-2.6.19.1-vs2.3.0.6/fs/quota_v1.c      2006-11-08 04:57:51 +0100
10581 @@ -42,12 +42,13 @@ static int v1_read_dqblk(struct dquot *d
10582         int type = dquot->dq_type;
10583         struct v1_disk_dqblk dqblk;
10584  
10585 -       if (!sb_dqopt(dquot->dq_sb)->files[type])
10586 +       if (!dqh_dqopt(dquot->dq_dqh)->files[type])
10587                 return -EINVAL;
10588  
10589         /* Set structure to 0s in case read fails/is after end of file */
10590         memset(&dqblk, 0, sizeof(struct v1_disk_dqblk));
10591 -       dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10592 +       dquot->dq_dqh->dqh_sb->s_op->quota_read(dquot->dq_dqh, type,
10593 +               (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10594  
10595         v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk);
10596         if (dquot->dq_dqb.dqb_bhardlimit == 0 && dquot->dq_dqb.dqb_bsoftlimit == 0 &&
10597 @@ -66,16 +67,16 @@ static int v1_commit_dqblk(struct dquot 
10598  
10599         v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb);
10600         if (dquot->dq_id == 0) {
10601 -               dqblk.dqb_btime = sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace;
10602 -               dqblk.dqb_itime = sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace;
10603 +               dqblk.dqb_btime = dqh_dqopt(dquot->dq_dqh)->info[type].dqi_bgrace;
10604 +               dqblk.dqb_itime = dqh_dqopt(dquot->dq_dqh)->info[type].dqi_igrace;
10605         }
10606         ret = 0;
10607 -       if (sb_dqopt(dquot->dq_sb)->files[type])
10608 -               ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, (char *)&dqblk,
10609 -                                       sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10610 +       if (dqh_dqopt(dquot->dq_dqh)->files[type])
10611 +               ret = dquot->dq_dqh->dqh_sb->s_op->quota_write(dquot->dq_dqh, type,
10612 +                       (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id));
10613         if (ret != sizeof(struct v1_disk_dqblk)) {
10614                 printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
10615 -                       dquot->dq_sb->s_id);
10616 +                       dquot->dq_dqh->dqh_sb->s_id);
10617                 if (ret >= 0)
10618                         ret = -EIO;
10619                 goto out;
10620 @@ -100,9 +101,9 @@ struct v2_disk_dqheader {
10621         __le32 dqh_version;      /* File version */
10622  };
10623  
10624 -static int v1_check_quota_file(struct super_block *sb, int type)
10625 +static int v1_check_quota_file(struct dqhash *hash, int type)
10626  {
10627 -       struct inode *inode = sb_dqopt(sb)->files[type];
10628 +       struct inode *inode = dqh_dqopt(hash)->files[type];
10629         ulong blocks;
10630         size_t off; 
10631         struct v2_disk_dqheader dqhead;
10632 @@ -118,22 +119,26 @@ static int v1_check_quota_file(struct su
10633         if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % sizeof(struct v1_disk_dqblk))
10634                 return 0;
10635         /* Doublecheck whether we didn't get file with new format - with old quotactl() this could happen */
10636 -       size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10637 +       size = hash->dqh_sb->s_op->quota_read(hash, type,
10638 +               (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10639         if (size != sizeof(struct v2_disk_dqheader))
10640                 return 1;       /* Probably not new format */
10641         if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type])
10642                 return 1;       /* Definitely not new format */
10643 -       printk(KERN_INFO "VFS: %s: Refusing to turn on old quota format on given file. It probably contains newer quota format.\n", sb->s_id);
10644 +       printk(KERN_INFO "VFS: %s: Refusing to turn on old quota format on given file."
10645 +               " It probably contains newer quota format.\n", hash->dqh_sb->s_id);
10646          return 0;              /* Seems like a new format file -> refuse it */
10647  }
10648  
10649 -static int v1_read_file_info(struct super_block *sb, int type)
10650 +static int v1_read_file_info(struct dqhash *hash, int type)
10651  {
10652 -       struct quota_info *dqopt = sb_dqopt(sb);
10653 +       struct quota_info *dqopt = dqh_dqopt(hash);
10654         struct v1_disk_dqblk dqblk;
10655         int ret;
10656  
10657 -       if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
10658 +       if ((ret = hash->dqh_sb->s_op->quota_read(hash, type,
10659 +               (char *)&dqblk, sizeof(struct v1_disk_dqblk),
10660 +               v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
10661                 if (ret >= 0)
10662                         ret = -EIO;
10663                 goto out;
10664 @@ -145,14 +150,14 @@ out:
10665         return ret;
10666  }
10667  
10668 -static int v1_write_file_info(struct super_block *sb, int type)
10669 +static int v1_write_file_info(struct dqhash *hash, int type)
10670  {
10671 -       struct quota_info *dqopt = sb_dqopt(sb);
10672 +       struct quota_info *dqopt = dqh_dqopt(hash);
10673         struct v1_disk_dqblk dqblk;
10674         int ret;
10675  
10676         dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY;
10677 -       if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk,
10678 +       if ((ret = hash->dqh_sb->s_op->quota_read(hash, type, (char *)&dqblk,
10679             sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) {
10680                 if (ret >= 0)
10681                         ret = -EIO;
10682 @@ -160,7 +165,7 @@ static int v1_write_file_info(struct sup
10683         }
10684         dqblk.dqb_itime = dqopt->info[type].dqi_igrace;
10685         dqblk.dqb_btime = dqopt->info[type].dqi_bgrace;
10686 -       ret = sb->s_op->quota_write(sb, type, (char *)&dqblk,
10687 +       ret = hash->dqh_sb->s_op->quota_write(hash, type, (char *)&dqblk,
10688               sizeof(struct v1_disk_dqblk), v1_dqoff(0));
10689         if (ret == sizeof(struct v1_disk_dqblk))
10690                 ret = 0;
10691 diff -NurpP --minimal linux-2.6.19.1/fs/quota_v2.c linux-2.6.19.1-vs2.3.0.6/fs/quota_v2.c
10692 --- linux-2.6.19.1/fs/quota_v2.c        2006-06-18 04:54:47 +0200
10693 +++ linux-2.6.19.1-vs2.3.0.6/fs/quota_v2.c      2006-11-08 04:57:51 +0100
10694 @@ -26,14 +26,15 @@ typedef char *dqbuf_t;
10695  #define GETENTRIES(buf) ((struct v2_disk_dqblk *)(((char *)buf)+sizeof(struct v2_disk_dqdbheader)))
10696  
10697  /* Check whether given file is really vfsv0 quotafile */
10698 -static int v2_check_quota_file(struct super_block *sb, int type)
10699 +static int v2_check_quota_file(struct dqhash *hash, int type)
10700  {
10701         struct v2_disk_dqheader dqhead;
10702         ssize_t size;
10703         static const uint quota_magics[] = V2_INITQMAGICS;
10704         static const uint quota_versions[] = V2_INITQVERSIONS;
10705   
10706 -       size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10707 +       size = hash->dqh_sb->s_op->quota_read(hash, type,
10708 +               (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
10709         if (size != sizeof(struct v2_disk_dqheader)) {
10710                 printk("quota_v2: failed read expected=%zd got=%zd\n",
10711                         sizeof(struct v2_disk_dqheader), size);
10712 @@ -46,17 +47,17 @@ static int v2_check_quota_file(struct su
10713  }
10714  
10715  /* Read information header from quota file */
10716 -static int v2_read_file_info(struct super_block *sb, int type)
10717 +static int v2_read_file_info(struct dqhash *hash, int type)
10718  {
10719         struct v2_disk_dqinfo dinfo;
10720 -       struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
10721 +       struct mem_dqinfo *info = dqh_dqopt(hash)->info+type;
10722         ssize_t size;
10723  
10724 -       size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
10725 -              sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
10726 +       size = hash->dqh_sb->s_op->quota_read(hash, type,
10727 +               (char *)&dinfo, sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
10728         if (size != sizeof(struct v2_disk_dqinfo)) {
10729                 printk(KERN_WARNING "Can't read info structure on device %s.\n",
10730 -                       sb->s_id);
10731 +                       hash->dqh_sb->s_id);
10732                 return -1;
10733         }
10734         info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
10735 @@ -69,10 +70,10 @@ static int v2_read_file_info(struct supe
10736  }
10737  
10738  /* Write information header to quota file */
10739 -static int v2_write_file_info(struct super_block *sb, int type)
10740 +static int v2_write_file_info(struct dqhash *hash, int type)
10741  {
10742         struct v2_disk_dqinfo dinfo;
10743 -       struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
10744 +       struct mem_dqinfo *info = dqh_dqopt(hash)->info+type;
10745         ssize_t size;
10746  
10747         spin_lock(&dq_data_lock);
10748 @@ -84,11 +85,11 @@ static int v2_write_file_info(struct sup
10749         dinfo.dqi_blocks = cpu_to_le32(info->u.v2_i.dqi_blocks);
10750         dinfo.dqi_free_blk = cpu_to_le32(info->u.v2_i.dqi_free_blk);
10751         dinfo.dqi_free_entry = cpu_to_le32(info->u.v2_i.dqi_free_entry);
10752 -       size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
10753 +       size = hash->dqh_sb->s_op->quota_write(hash, type, (char *)&dinfo,
10754                sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
10755         if (size != sizeof(struct v2_disk_dqinfo)) {
10756                 printk(KERN_WARNING "Can't write info structure on device %s.\n",
10757 -                       sb->s_id);
10758 +                       hash->dqh_sb->s_id);
10759                 return -1;
10760         }
10761         return 0;
10762 @@ -132,24 +133,24 @@ static inline void freedqbuf(dqbuf_t buf
10763         kfree(buf);
10764  }
10765  
10766 -static inline ssize_t read_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
10767 +static inline ssize_t read_blk(struct dqhash *hash, int type, uint blk, dqbuf_t buf)
10768  {
10769         memset(buf, 0, V2_DQBLKSIZE);
10770 -       return sb->s_op->quota_read(sb, type, (char *)buf,
10771 -              V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10772 +       return hash->dqh_sb->s_op->quota_read(hash, type,
10773 +               (char *)buf, V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10774  }
10775  
10776 -static inline ssize_t write_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
10777 +static inline ssize_t write_blk(struct dqhash *hash, int type, uint blk, dqbuf_t buf)
10778  {
10779 -       return sb->s_op->quota_write(sb, type, (char *)buf,
10780 -              V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10781 +       return hash->dqh_sb->s_op->quota_write(hash, type,
10782 +               (char *)buf, V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
10783  }
10784  
10785  /* Remove empty block from list and return it */
10786 -static int get_free_dqblk(struct super_block *sb, int type)
10787 +static int get_free_dqblk(struct dqhash *hash, int type)
10788  {
10789         dqbuf_t buf = getdqbuf();
10790 -       struct mem_dqinfo *info = sb_dqinfo(sb, type);
10791 +       struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10792         struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10793         int ret, blk;
10794  
10795 @@ -157,18 +158,18 @@ static int get_free_dqblk(struct super_b
10796                 return -ENOMEM;
10797         if (info->u.v2_i.dqi_free_blk) {
10798                 blk = info->u.v2_i.dqi_free_blk;
10799 -               if ((ret = read_blk(sb, type, blk, buf)) < 0)
10800 +               if ((ret = read_blk(hash, type, blk, buf)) < 0)
10801                         goto out_buf;
10802                 info->u.v2_i.dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
10803         }
10804         else {
10805                 memset(buf, 0, V2_DQBLKSIZE);
10806                 /* Assure block allocation... */
10807 -               if ((ret = write_blk(sb, type, info->u.v2_i.dqi_blocks, buf)) < 0)
10808 +               if ((ret = write_blk(hash, type, info->u.v2_i.dqi_blocks, buf)) < 0)
10809                         goto out_buf;
10810                 blk = info->u.v2_i.dqi_blocks++;
10811         }
10812 -       mark_info_dirty(sb, type);
10813 +       mark_info_dirty(hash, type);
10814         ret = blk;
10815  out_buf:
10816         freedqbuf(buf);
10817 @@ -176,9 +177,9 @@ out_buf:
10818  }
10819  
10820  /* Insert empty block to the list */
10821 -static int put_free_dqblk(struct super_block *sb, int type, dqbuf_t buf, uint blk)
10822 +static int put_free_dqblk(struct dqhash *hash, int type, dqbuf_t buf, uint blk)
10823  {
10824 -       struct mem_dqinfo *info = sb_dqinfo(sb, type);
10825 +       struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10826         struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10827         int err;
10828  
10829 @@ -186,18 +187,18 @@ static int put_free_dqblk(struct super_b
10830         dh->dqdh_prev_free = cpu_to_le32(0);
10831         dh->dqdh_entries = cpu_to_le16(0);
10832         info->u.v2_i.dqi_free_blk = blk;
10833 -       mark_info_dirty(sb, type);
10834 +       mark_info_dirty(hash, type);
10835         /* Some strange block. We had better leave it... */
10836 -       if ((err = write_blk(sb, type, blk, buf)) < 0)
10837 +       if ((err = write_blk(hash, type, blk, buf)) < 0)
10838                 return err;
10839         return 0;
10840  }
10841  
10842  /* Remove given block from the list of blocks with free entries */
10843 -static int remove_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
10844 +static int remove_free_dqentry(struct dqhash *hash, int type, dqbuf_t buf, uint blk)
10845  {
10846         dqbuf_t tmpbuf = getdqbuf();
10847 -       struct mem_dqinfo *info = sb_dqinfo(sb, type);
10848 +       struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10849         struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10850         uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = le32_to_cpu(dh->dqdh_prev_free);
10851         int err;
10852 @@ -205,27 +206,27 @@ static int remove_free_dqentry(struct su
10853         if (!tmpbuf)
10854                 return -ENOMEM;
10855         if (nextblk) {
10856 -               if ((err = read_blk(sb, type, nextblk, tmpbuf)) < 0)
10857 +               if ((err = read_blk(hash, type, nextblk, tmpbuf)) < 0)
10858                         goto out_buf;
10859                 ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = dh->dqdh_prev_free;
10860 -               if ((err = write_blk(sb, type, nextblk, tmpbuf)) < 0)
10861 +               if ((err = write_blk(hash, type, nextblk, tmpbuf)) < 0)
10862                         goto out_buf;
10863         }
10864         if (prevblk) {
10865 -               if ((err = read_blk(sb, type, prevblk, tmpbuf)) < 0)
10866 +               if ((err = read_blk(hash, type, prevblk, tmpbuf)) < 0)
10867                         goto out_buf;
10868                 ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_next_free = dh->dqdh_next_free;
10869 -               if ((err = write_blk(sb, type, prevblk, tmpbuf)) < 0)
10870 +               if ((err = write_blk(hash, type, prevblk, tmpbuf)) < 0)
10871                         goto out_buf;
10872         }
10873         else {
10874                 info->u.v2_i.dqi_free_entry = nextblk;
10875 -               mark_info_dirty(sb, type);
10876 +               mark_info_dirty(hash, type);
10877         }
10878         freedqbuf(tmpbuf);
10879         dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
10880         /* No matter whether write succeeds block is out of list */
10881 -       if (write_blk(sb, type, blk, buf) < 0)
10882 +       if (write_blk(hash, type, blk, buf) < 0)
10883                 printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk);
10884         return 0;
10885  out_buf:
10886 @@ -234,10 +235,10 @@ out_buf:
10887  }
10888  
10889  /* Insert given block to the beginning of list with free entries */
10890 -static int insert_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
10891 +static int insert_free_dqentry(struct dqhash *hash, int type, dqbuf_t buf, uint blk)
10892  {
10893         dqbuf_t tmpbuf = getdqbuf();
10894 -       struct mem_dqinfo *info = sb_dqinfo(sb, type);
10895 +       struct mem_dqinfo *info = dqh_dqinfo(hash, type);
10896         struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
10897         int err;
10898  
10899 @@ -245,18 +246,18 @@ static int insert_free_dqentry(struct su
10900                 return -ENOMEM;
10901         dh->dqdh_next_free = cpu_to_le32(info->u.v2_i.dqi_free_entry);
10902         dh->dqdh_prev_free = cpu_to_le32(0);
10903 -       if ((err = write_blk(sb, type, blk, buf)) < 0)
10904 +       if ((err = write_blk(hash, type, blk, buf)) < 0)
10905                 goto out_buf;
10906         if (info->u.v2_i.dqi_free_entry) {
10907 -               if ((err = read_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10908 +               if ((err = read_blk(hash, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10909                         goto out_buf;
10910                 ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = cpu_to_le32(blk);
10911 -               if ((err = write_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10912 +               if ((err = write_blk(hash, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
10913                         goto out_buf;
10914         }
10915         freedqbuf(tmpbuf);
10916         info->u.v2_i.dqi_free_entry = blk;
10917 -       mark_info_dirty(sb, type);
10918 +       mark_info_dirty(hash, type);
10919         return 0;
10920  out_buf:
10921         freedqbuf(tmpbuf);
10922 @@ -266,8 +267,9 @@ out_buf:
10923  /* Find space for dquot */
10924  static uint find_free_dqentry(struct dquot *dquot, int *err)
10925  {
10926 -       struct super_block *sb = dquot->dq_sb;
10927 -       struct mem_dqinfo *info = sb_dqopt(sb)->info+dquot->dq_type;
10928 +       // struct super_block *sb = dquot->dq_sb;
10929 +       struct dqhash *dqh = dquot->dq_dqh;
10930 +       struct mem_dqinfo *info = dqh_dqopt(dqh)->info+dquot->dq_type;
10931         uint blk, i;
10932         struct v2_disk_dqdbheader *dh;
10933         struct v2_disk_dqblk *ddquot;
10934 @@ -283,11 +285,11 @@ static uint find_free_dqentry(struct dqu
10935         ddquot = GETENTRIES(buf);
10936         if (info->u.v2_i.dqi_free_entry) {
10937                 blk = info->u.v2_i.dqi_free_entry;
10938 -               if ((*err = read_blk(sb, dquot->dq_type, blk, buf)) < 0)
10939 +               if ((*err = read_blk(dqh, dquot->dq_type, blk, buf)) < 0)
10940                         goto out_buf;
10941         }
10942         else {
10943 -               blk = get_free_dqblk(sb, dquot->dq_type);
10944 +               blk = get_free_dqblk(dqh, dquot->dq_type);
10945                 if ((int)blk < 0) {
10946                         *err = blk;
10947                         freedqbuf(buf);
10948 @@ -296,10 +298,10 @@ static uint find_free_dqentry(struct dqu
10949                 memset(buf, 0, V2_DQBLKSIZE);
10950                 /* This is enough as block is already zeroed and entry list is empty... */
10951                 info->u.v2_i.dqi_free_entry = blk;
10952 -               mark_info_dirty(sb, dquot->dq_type);
10953 +               mark_info_dirty(dqh, dquot->dq_type);
10954         }
10955         if (le16_to_cpu(dh->dqdh_entries)+1 >= V2_DQSTRINBLK)   /* Block will be full? */
10956 -               if ((*err = remove_free_dqentry(sb, dquot->dq_type, buf, blk)) < 0) {
10957 +               if ((*err = remove_free_dqentry(dqh, dquot->dq_type, buf, blk)) < 0) {
10958                         printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk);
10959                         goto out_buf;
10960                 }
10961 @@ -314,7 +316,7 @@ static uint find_free_dqentry(struct dqu
10962                 goto out_buf;
10963         }
10964  #endif
10965 -       if ((*err = write_blk(sb, dquot->dq_type, blk, buf)) < 0) {
10966 +       if ((*err = write_blk(dqh, dquot->dq_type, blk, buf)) < 0) {
10967                 printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota data block %u.\n", blk);
10968                 goto out_buf;
10969         }
10970 @@ -329,7 +331,7 @@ out_buf:
10971  /* Insert reference to structure into the trie */
10972  static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth)
10973  {
10974 -       struct super_block *sb = dquot->dq_sb;
10975 +       struct dqhash *dqh = dquot->dq_dqh;
10976         dqbuf_t buf;
10977         int ret = 0, newson = 0, newact = 0;
10978         __le32 *ref;
10979 @@ -338,7 +340,7 @@ static int do_insert_tree(struct dquot *
10980         if (!(buf = getdqbuf()))
10981                 return -ENOMEM;
10982         if (!*treeblk) {
10983 -               ret = get_free_dqblk(sb, dquot->dq_type);
10984 +               ret = get_free_dqblk(dqh, dquot->dq_type);
10985                 if (ret < 0)
10986                         goto out_buf;
10987                 *treeblk = ret;
10988 @@ -346,7 +348,7 @@ static int do_insert_tree(struct dquot *
10989                 newact = 1;
10990         }
10991         else {
10992 -               if ((ret = read_blk(sb, dquot->dq_type, *treeblk, buf)) < 0) {
10993 +               if ((ret = read_blk(dqh, dquot->dq_type, *treeblk, buf)) < 0) {
10994                         printk(KERN_ERR "VFS: Can't read tree quota block %u.\n", *treeblk);
10995                         goto out_buf;
10996                 }
10997 @@ -369,10 +371,10 @@ static int do_insert_tree(struct dquot *
10998                 ret = do_insert_tree(dquot, &newblk, depth+1);
10999         if (newson && ret >= 0) {
11000                 ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk);
11001 -               ret = write_blk(sb, dquot->dq_type, *treeblk, buf);
11002 +               ret = write_blk(dqh, dquot->dq_type, *treeblk, buf);
11003         }
11004         else if (newact && ret < 0)
11005 -               put_free_dqblk(sb, dquot->dq_type, buf, *treeblk);
11006 +               put_free_dqblk(dqh, dquot->dq_type, buf, *treeblk);
11007  out_buf:
11008         freedqbuf(buf);
11009         return ret;
11010 @@ -409,10 +411,11 @@ static int v2_write_dquot(struct dquot *
11011         if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
11012                 ddquot.dqb_itime = cpu_to_le64(1);
11013         spin_unlock(&dq_data_lock);
11014 -       ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,
11015 +       ret = dquot->dq_dqh->dqh_sb->s_op->quota_write(dquot->dq_dqh, type,
11016               (char *)&ddquot, sizeof(struct v2_disk_dqblk), dquot->dq_off);
11017         if (ret != sizeof(struct v2_disk_dqblk)) {
11018 -               printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", dquot->dq_sb->s_id);
11019 +               printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
11020 +                       dquot->dq_dqh->dqh_sb->s_id);
11021                 if (ret >= 0)
11022                         ret = -ENOSPC;
11023         }
11024 @@ -426,7 +429,8 @@ static int v2_write_dquot(struct dquot *
11025  /* Free dquot entry in data block */
11026  static int free_dqentry(struct dquot *dquot, uint blk)
11027  {
11028 -       struct super_block *sb = dquot->dq_sb;
11029 +       // struct super_block *sb = dquot->dq_sb;
11030 +       struct dqhash *dqh = dquot->dq_dqh;
11031         int type = dquot->dq_type;
11032         struct v2_disk_dqdbheader *dh;
11033         dqbuf_t buf = getdqbuf();
11034 @@ -440,15 +444,15 @@ static int free_dqentry(struct dquot *dq
11035                   (uint)(dquot->dq_off >> V2_DQBLKSIZE_BITS));
11036                 goto out_buf;
11037         }
11038 -       if ((ret = read_blk(sb, type, blk, buf)) < 0) {
11039 +       if ((ret = read_blk(dqh, type, blk, buf)) < 0) {
11040                 printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk);
11041                 goto out_buf;
11042         }
11043         dh = (struct v2_disk_dqdbheader *)buf;
11044         dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)-1);
11045         if (!le16_to_cpu(dh->dqdh_entries)) {   /* Block got free? */
11046 -               if ((ret = remove_free_dqentry(sb, type, buf, blk)) < 0 ||
11047 -                   (ret = put_free_dqblk(sb, type, buf, blk)) < 0) {
11048 +               if ((ret = remove_free_dqentry(dqh, type, buf, blk)) < 0 ||
11049 +                   (ret = put_free_dqblk(dqh, type, buf, blk)) < 0) {
11050                         printk(KERN_ERR "VFS: Can't move quota data block (%u) "
11051                           "to free list.\n", blk);
11052                         goto out_buf;
11053 @@ -459,13 +463,13 @@ static int free_dqentry(struct dquot *dq
11054                   sizeof(struct v2_disk_dqblk));
11055                 if (le16_to_cpu(dh->dqdh_entries) == V2_DQSTRINBLK-1) {
11056                         /* Insert will write block itself */
11057 -                       if ((ret = insert_free_dqentry(sb, type, buf, blk)) < 0) {
11058 +                       if ((ret = insert_free_dqentry(dqh, type, buf, blk)) < 0) {
11059                                 printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk);
11060                                 goto out_buf;
11061                         }
11062                 }
11063                 else
11064 -                       if ((ret = write_blk(sb, type, blk, buf)) < 0) {
11065 +                       if ((ret = write_blk(dqh, type, blk, buf)) < 0) {
11066                                 printk(KERN_ERR "VFS: Can't write quota data "
11067                                   "block %u\n", blk);
11068                                 goto out_buf;
11069 @@ -480,7 +484,7 @@ out_buf:
11070  /* Remove reference to dquot from tree */
11071  static int remove_tree(struct dquot *dquot, uint *blk, int depth)
11072  {
11073 -       struct super_block *sb = dquot->dq_sb;
11074 +       struct dqhash *dqh = dquot->dq_dqh;
11075         int type = dquot->dq_type;
11076         dqbuf_t buf = getdqbuf();
11077         int ret = 0;
11078 @@ -489,7 +493,7 @@ static int remove_tree(struct dquot *dqu
11079         
11080         if (!buf)
11081                 return -ENOMEM;
11082 -       if ((ret = read_blk(sb, type, *blk, buf)) < 0) {
11083 +       if ((ret = read_blk(dqh, type, *blk, buf)) < 0) {
11084                 printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk);
11085                 goto out_buf;
11086         }
11087 @@ -506,11 +510,11 @@ static int remove_tree(struct dquot *dqu
11088                 for (i = 0; i < V2_DQBLKSIZE && !buf[i]; i++);  /* Block got empty? */
11089                 /* Don't put the root block into the free block list */
11090                 if (i == V2_DQBLKSIZE && *blk != V2_DQTREEOFF) {
11091 -                       put_free_dqblk(sb, type, buf, *blk);
11092 +                       put_free_dqblk(dqh, type, buf, *blk);
11093                         *blk = 0;
11094                 }
11095                 else
11096 -                       if ((ret = write_blk(sb, type, *blk, buf)) < 0)
11097 +                       if ((ret = write_blk(dqh, type, *blk, buf)) < 0)
11098                                 printk(KERN_ERR "VFS: Can't write quota tree "
11099                                   "block %u.\n", *blk);
11100         }
11101 @@ -539,7 +543,7 @@ static loff_t find_block_dqentry(struct 
11102  
11103         if (!buf)
11104                 return -ENOMEM;
11105 -       if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
11106 +       if ((ret = read_blk(dquot->dq_dqh, dquot->dq_type, blk, buf)) < 0) {
11107                 printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
11108                 goto out_buf;
11109         }
11110 @@ -578,7 +582,7 @@ static loff_t find_tree_dqentry(struct d
11111  
11112         if (!buf)
11113                 return -ENOMEM;
11114 -       if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
11115 +       if ((ret = read_blk(dquot->dq_dqh, dquot->dq_type, blk, buf)) < 0) {
11116                 printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
11117                 goto out_buf;
11118         }
11119 @@ -610,7 +614,7 @@ static int v2_read_dquot(struct dquot *d
11120  
11121  #ifdef __QUOTA_V2_PARANOIA
11122         /* Invalidated quota? */
11123 -       if (!dquot->dq_sb || !sb_dqopt(dquot->dq_sb)->files[type]) {
11124 +       if (!dquot->dq_dqh || !dqh_dqopt(dquot->dq_dqh)->files[type]) {
11125                 printk(KERN_ERR "VFS: Quota invalidated while reading!\n");
11126                 return -EIO;
11127         }
11128 @@ -627,7 +631,7 @@ static int v2_read_dquot(struct dquot *d
11129         }
11130         else {
11131                 dquot->dq_off = offset;
11132 -               if ((ret = dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type,
11133 +               if ((ret = dquot->dq_dqh->dqh_sb->s_op->quota_read(dquot->dq_dqh, type,
11134                     (char *)&ddquot, sizeof(struct v2_disk_dqblk), offset))
11135                     != sizeof(struct v2_disk_dqblk)) {
11136                         if (ret >= 0)
11137 diff -NurpP --minimal linux-2.6.19.1/fs/read_write.c linux-2.6.19.1-vs2.3.0.6/fs/read_write.c
11138 --- linux-2.6.19.1/fs/read_write.c      2006-11-30 21:19:28 +0100
11139 +++ linux-2.6.19.1-vs2.3.0.6/fs/read_write.c    2006-11-08 04:57:51 +0100
11140 @@ -703,12 +703,77 @@ sys_writev(unsigned long fd, const struc
11141         return ret;
11142  }
11143  
11144 +ssize_t vfs_sendfile(struct file *out_file, struct file *in_file, loff_t *ppos,
11145 +                    size_t count, loff_t max)
11146 +{
11147 +       struct inode * in_inode, * out_inode;
11148 +       loff_t pos;
11149 +       ssize_t ret;
11150 +
11151 +       /* verify in_file */
11152 +       in_inode = in_file->f_dentry->d_inode;
11153 +       if (!in_inode)
11154 +               return -EINVAL;
11155 +       if (!in_file->f_op || !in_file->f_op->sendfile)
11156 +               return -EINVAL;
11157 +
11158 +       if (!ppos)
11159 +               ppos = &in_file->f_pos;
11160 +       else
11161 +               if (!(in_file->f_mode & FMODE_PREAD))
11162 +                       return -ESPIPE;
11163 +
11164 +       ret = rw_verify_area(READ, in_file, ppos, count);
11165 +       if (ret < 0)
11166 +               return ret;
11167 +       count = ret;
11168 +
11169 +       /* verify out_file */
11170 +       out_inode = out_file->f_dentry->d_inode;
11171 +       if (!out_inode)
11172 +               return -EINVAL;
11173 +       if (!out_file->f_op || !out_file->f_op->sendpage)
11174 +               return -EINVAL;
11175 +
11176 +       ret = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
11177 +       if (ret < 0)
11178 +               return ret;
11179 +       count = ret;
11180 +
11181 +       ret = security_file_permission (out_file, MAY_WRITE);
11182 +       if (ret)
11183 +               return ret;
11184 +
11185 +       if (!max)
11186 +               max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
11187 +
11188 +       pos = *ppos;
11189 +       if (unlikely(pos < 0))
11190 +               return -EINVAL;
11191 +       if (unlikely(pos + count > max)) {
11192 +               if (pos >= max)
11193 +                       return -EOVERFLOW;
11194 +               count = max - pos;
11195 +       }
11196 +
11197 +       ret = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
11198 +
11199 +       if (ret > 0) {
11200 +               current->rchar += ret;
11201 +               current->wchar += ret;
11202 +       }
11203 +
11204 +       if (*ppos > max)
11205 +               return -EOVERFLOW;
11206 +       return ret;
11207 +}
11208 +
11209 +EXPORT_SYMBOL(vfs_sendfile);
11210 +
11211  static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
11212                            size_t count, loff_t max)
11213  {
11214         struct file * in_file, * out_file;
11215 -       struct inode * in_inode, * out_inode;
11216 -       loff_t pos;
11217         ssize_t retval;
11218         int fput_needed_in, fput_needed_out;
11219  
11220 @@ -721,22 +786,6 @@ static ssize_t do_sendfile(int out_fd, i
11221                 goto out;
11222         if (!(in_file->f_mode & FMODE_READ))
11223                 goto fput_in;
11224 -       retval = -EINVAL;
11225 -       in_inode = in_file->f_dentry->d_inode;
11226 -       if (!in_inode)
11227 -               goto fput_in;
11228 -       if (!in_file->f_op || !in_file->f_op->sendfile)
11229 -               goto fput_in;
11230 -       retval = -ESPIPE;
11231 -       if (!ppos)
11232 -               ppos = &in_file->f_pos;
11233 -       else
11234 -               if (!(in_file->f_mode & FMODE_PREAD))
11235 -                       goto fput_in;
11236 -       retval = rw_verify_area(READ, in_file, ppos, count);
11237 -       if (retval < 0)
11238 -               goto fput_in;
11239 -       count = retval;
11240  
11241         retval = security_file_permission (in_file, MAY_READ);
11242         if (retval)
11243 @@ -751,45 +800,12 @@ static ssize_t do_sendfile(int out_fd, i
11244                 goto fput_in;
11245         if (!(out_file->f_mode & FMODE_WRITE))
11246                 goto fput_out;
11247 -       retval = -EINVAL;
11248 -       if (!out_file->f_op || !out_file->f_op->sendpage)
11249 -               goto fput_out;
11250 -       out_inode = out_file->f_dentry->d_inode;
11251 -       retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
11252 -       if (retval < 0)
11253 -               goto fput_out;
11254 -       count = retval;
11255 -
11256 -       retval = security_file_permission (out_file, MAY_WRITE);
11257 -       if (retval)
11258 -               goto fput_out;
11259 -
11260 -       if (!max)
11261 -               max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
11262 -
11263 -       pos = *ppos;
11264 -       retval = -EINVAL;
11265 -       if (unlikely(pos < 0))
11266 -               goto fput_out;
11267 -       if (unlikely(pos + count > max)) {
11268 -               retval = -EOVERFLOW;
11269 -               if (pos >= max)
11270 -                       goto fput_out;
11271 -               count = max - pos;
11272 -       }
11273  
11274 -       retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
11275 +       retval = vfs_sendfile(out_file, in_file, ppos, count, max);
11276  
11277 -       if (retval > 0) {
11278 -               current->rchar += retval;
11279 -               current->wchar += retval;
11280 -       }
11281         current->syscr++;
11282         current->syscw++;
11283  
11284 -       if (*ppos > max)
11285 -               retval = -EOVERFLOW;
11286 -
11287  fput_out:
11288         fput_light(out_file, fput_needed_out);
11289  fput_in:
11290 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/bitmap.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/bitmap.c
11291 --- linux-2.6.19.1/fs/reiserfs/bitmap.c 2006-11-30 21:19:28 +0100
11292 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/bitmap.c       2006-11-08 04:57:50 +0100
11293 @@ -13,6 +13,7 @@
11294  #include <linux/reiserfs_fs_sb.h>
11295  #include <linux/reiserfs_fs_i.h>
11296  #include <linux/quotaops.h>
11297 +#include <linux/vs_dlimit.h>
11298  
11299  #define PREALLOCATION_SIZE 9
11300  
11301 @@ -425,8 +426,10 @@ static void _reiserfs_free_block(struct 
11302         set_sb_free_blocks(rs, sb_free_blocks(rs) + 1);
11303  
11304         journal_mark_dirty(th, s, sbh);
11305 -       if (for_unformatted)
11306 +       if (for_unformatted) {
11307 +               DLIMIT_FREE_BLOCK(inode, 1);
11308                 DQUOT_FREE_BLOCK_NODIRTY(inode, 1);
11309 +       }
11310  }
11311  
11312  void reiserfs_free_block(struct reiserfs_transaction_handle *th,
11313 @@ -1034,6 +1037,7 @@ static inline int blocknrs_and_prealloc_
11314         b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1;
11315         int passno = 0;
11316         int nr_allocated = 0;
11317 +       int blocks;
11318  
11319         determine_prealloc_size(hint);
11320         if (!hint->formatted_node) {
11321 @@ -1043,19 +1047,30 @@ static inline int blocknrs_and_prealloc_
11322                                "reiserquota: allocating %d blocks id=%u",
11323                                amount_needed, hint->inode->i_uid);
11324  #endif
11325 -               quota_ret =
11326 -                   DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed);
11327 -               if (quota_ret)  /* Quota exceeded? */
11328 +               quota_ret = DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode,
11329 +                       amount_needed);
11330 +               if (quota_ret)
11331                         return QUOTA_EXCEEDED;
11332 +               if (DLIMIT_ALLOC_BLOCK(hint->inode, amount_needed)) {
11333 +                       DQUOT_FREE_BLOCK_NODIRTY(hint->inode,
11334 +                               amount_needed);
11335 +                       return NO_DISK_SPACE;
11336 +               }
11337 +
11338                 if (hint->preallocate && hint->prealloc_size) {
11339  #ifdef REISERQUOTA_DEBUG
11340                         reiserfs_debug(s, REISERFS_DEBUG_CODE,
11341                                        "reiserquota: allocating (prealloc) %d blocks id=%u",
11342                                        hint->prealloc_size, hint->inode->i_uid);
11343  #endif
11344 -                       quota_ret =
11345 -                           DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
11346 -                                                        hint->prealloc_size);
11347 +                       quota_ret = DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
11348 +                               hint->prealloc_size);
11349 +                       if (!quota_ret &&
11350 +                               DLIMIT_ALLOC_BLOCK(hint->inode, hint->prealloc_size)) {
11351 +                               DQUOT_FREE_BLOCK_NODIRTY(hint->inode,
11352 +                                       hint->prealloc_size);
11353 +                               quota_ret = 1;
11354 +                       }
11355                         if (quota_ret)
11356                                 hint->preallocate = hint->prealloc_size = 0;
11357                 }
11358 @@ -1087,7 +1102,10 @@ static inline int blocknrs_and_prealloc_
11359                                                nr_allocated,
11360                                                hint->inode->i_uid);
11361  #endif
11362 -                               DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated);      /* Free not allocated blocks */
11363 +                               /* Free not allocated blocks */
11364 +                               blocks = amount_needed + hint->prealloc_size - nr_allocated;
11365 +                               DLIMIT_FREE_BLOCK(hint->inode, blocks);
11366 +                               DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks);
11367                         }
11368                         while (nr_allocated--)
11369                                 reiserfs_free_block(hint->th, hint->inode,
11370 @@ -1118,10 +1136,10 @@ static inline int blocknrs_and_prealloc_
11371                                REISERFS_I(hint->inode)->i_prealloc_count,
11372                                hint->inode->i_uid);
11373  #endif
11374 -               DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed +
11375 -                                        hint->prealloc_size - nr_allocated -
11376 -                                        REISERFS_I(hint->inode)->
11377 -                                        i_prealloc_count);
11378 +               blocks = amount_needed + hint->prealloc_size - nr_allocated -
11379 +                       REISERFS_I(hint->inode)->i_prealloc_count;
11380 +               DLIMIT_FREE_BLOCK(hint->inode, blocks);
11381 +               DQUOT_FREE_BLOCK_NODIRTY(hint->inode, blocks);
11382         }
11383  
11384         return CARRY_ON;
11385 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/file.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/file.c
11386 --- linux-2.6.19.1/fs/reiserfs/file.c   2006-11-30 21:19:28 +0100
11387 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/file.c 2006-11-30 20:55:45 +0100
11388 @@ -1575,6 +1575,7 @@ const struct file_operations reiserfs_fi
11389         .release = reiserfs_file_release,
11390         .fsync = reiserfs_sync_file,
11391         .sendfile = generic_file_sendfile,
11392 +       .sendpage = generic_file_sendpage,
11393         .aio_read = generic_file_aio_read,
11394         .aio_write = generic_file_aio_write,
11395         .splice_read = generic_file_splice_read,
11396 @@ -1589,4 +1590,5 @@ struct inode_operations reiserfs_file_in
11397         .listxattr = reiserfs_listxattr,
11398         .removexattr = reiserfs_removexattr,
11399         .permission = reiserfs_permission,
11400 +       .sync_flags = reiserfs_sync_flags,
11401  };
11402 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/inode.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/inode.c
11403 --- linux-2.6.19.1/fs/reiserfs/inode.c  2006-11-30 21:19:28 +0100
11404 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/inode.c        2006-11-30 18:53:18 +0100
11405 @@ -16,6 +16,8 @@
11406  #include <linux/mpage.h>
11407  #include <linux/writeback.h>
11408  #include <linux/quotaops.h>
11409 +#include <linux/vs_dlimit.h>
11410 +#include <linux/vs_tag.h>
11411  
11412  static int reiserfs_commit_write(struct file *f, struct page *page,
11413                                  unsigned from, unsigned to);
11414 @@ -50,6 +52,7 @@ void reiserfs_delete_inode(struct inode 
11415                  * stat data deletion */
11416                 if (!err) 
11417                         DQUOT_FREE_INODE(inode);
11418 +               DLIMIT_FREE_INODE(inode);
11419  
11420                 if (journal_end(&th, inode->i_sb, jbegin_count))
11421                         goto out;
11422 @@ -1114,6 +1117,8 @@ static void init_inode(struct inode *ino
11423         struct buffer_head *bh;
11424         struct item_head *ih;
11425         __u32 rdev;
11426 +       uid_t uid;
11427 +       gid_t gid;
11428         //int version = ITEM_VERSION_1;
11429  
11430         bh = PATH_PLAST_BUFFER(path);
11431 @@ -1136,12 +1141,13 @@ static void init_inode(struct inode *ino
11432                     (struct stat_data_v1 *)B_I_PITEM(bh, ih);
11433                 unsigned long blocks;
11434  
11435 +               uid = sd_v1_uid(sd);
11436 +               gid = sd_v1_gid(sd);
11437 +
11438                 set_inode_item_key_version(inode, KEY_FORMAT_3_5);
11439                 set_inode_sd_version(inode, STAT_DATA_V1);
11440                 inode->i_mode = sd_v1_mode(sd);
11441                 inode->i_nlink = sd_v1_nlink(sd);
11442 -               inode->i_uid = sd_v1_uid(sd);
11443 -               inode->i_gid = sd_v1_gid(sd);
11444                 inode->i_size = sd_v1_size(sd);
11445                 inode->i_atime.tv_sec = sd_v1_atime(sd);
11446                 inode->i_mtime.tv_sec = sd_v1_mtime(sd);
11447 @@ -1183,11 +1189,12 @@ static void init_inode(struct inode *ino
11448                 // (directories and symlinks)
11449                 struct stat_data *sd = (struct stat_data *)B_I_PITEM(bh, ih);
11450  
11451 +               uid    = sd_v2_uid(sd);
11452 +               gid    = sd_v2_gid(sd);
11453 +
11454                 inode->i_mode = sd_v2_mode(sd);
11455                 inode->i_nlink = sd_v2_nlink(sd);
11456 -               inode->i_uid = sd_v2_uid(sd);
11457                 inode->i_size = sd_v2_size(sd);
11458 -               inode->i_gid = sd_v2_gid(sd);
11459                 inode->i_mtime.tv_sec = sd_v2_mtime(sd);
11460                 inode->i_atime.tv_sec = sd_v2_atime(sd);
11461                 inode->i_ctime.tv_sec = sd_v2_ctime(sd);
11462 @@ -1217,6 +1224,10 @@ static void init_inode(struct inode *ino
11463                 sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode);
11464         }
11465  
11466 +       inode->i_uid = INOTAG_UID(DX_TAG(inode), uid, gid);
11467 +       inode->i_gid = INOTAG_GID(DX_TAG(inode), uid, gid);
11468 +       inode->i_tag = INOTAG_TAG(DX_TAG(inode), uid, gid, 0);
11469 +
11470         pathrelse(path);
11471         if (S_ISREG(inode->i_mode)) {
11472                 inode->i_op = &reiserfs_file_inode_operations;
11473 @@ -1239,13 +1250,15 @@ static void init_inode(struct inode *ino
11474  static void inode2sd(void *sd, struct inode *inode, loff_t size)
11475  {
11476         struct stat_data *sd_v2 = (struct stat_data *)sd;
11477 +       uid_t uid = TAGINO_UID(DX_TAG(inode), inode->i_uid, inode->i_tag);
11478 +       gid_t gid = TAGINO_GID(DX_TAG(inode), inode->i_gid, inode->i_tag);
11479         __u16 flags;
11480  
11481 +       set_sd_v2_uid(sd_v2, uid);
11482 +       set_sd_v2_gid(sd_v2, gid);
11483         set_sd_v2_mode(sd_v2, inode->i_mode);
11484         set_sd_v2_nlink(sd_v2, inode->i_nlink);
11485 -       set_sd_v2_uid(sd_v2, inode->i_uid);
11486         set_sd_v2_size(sd_v2, size);
11487 -       set_sd_v2_gid(sd_v2, inode->i_gid);
11488         set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec);
11489         set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec);
11490         set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec);
11491 @@ -1776,6 +1789,10 @@ int reiserfs_new_inode(struct reiserfs_t
11492  
11493         BUG_ON(!th->t_trans_id);
11494  
11495 +       if (DLIMIT_ALLOC_INODE(inode)) {
11496 +               err = -ENOSPC;
11497 +               goto out_bad_dlimit;
11498 +       }
11499         if (DQUOT_ALLOC_INODE(inode)) {
11500                 err = -EDQUOT;
11501                 goto out_end_trans;
11502 @@ -1960,6 +1977,9 @@ int reiserfs_new_inode(struct reiserfs_t
11503         DQUOT_FREE_INODE(inode);
11504  
11505        out_end_trans:
11506 +       DLIMIT_FREE_INODE(inode);
11507 +
11508 +      out_bad_dlimit:
11509         journal_end(th, th->t_super, th->t_blocks_allocated);
11510         /* Drop can be outside and it needs more credits so it's better to have it outside */
11511         DQUOT_DROP(inode);
11512 @@ -2699,6 +2719,14 @@ void sd_attrs_to_i_attrs(__u16 sd_attrs,
11513                         inode->i_flags |= S_IMMUTABLE;
11514                 else
11515                         inode->i_flags &= ~S_IMMUTABLE;
11516 +               if (sd_attrs & REISERFS_IUNLINK_FL)
11517 +                       inode->i_flags |= S_IUNLINK;
11518 +               else
11519 +                       inode->i_flags &= ~S_IUNLINK;
11520 +               if (sd_attrs & REISERFS_BARRIER_FL)
11521 +                       inode->i_flags |= S_BARRIER;
11522 +               else
11523 +                       inode->i_flags &= ~S_BARRIER;
11524                 if (sd_attrs & REISERFS_APPEND_FL)
11525                         inode->i_flags |= S_APPEND;
11526                 else
11527 @@ -2721,6 +2749,14 @@ void i_attrs_to_sd_attrs(struct inode *i
11528                         *sd_attrs |= REISERFS_IMMUTABLE_FL;
11529                 else
11530                         *sd_attrs &= ~REISERFS_IMMUTABLE_FL;
11531 +               if (inode->i_flags & S_IUNLINK)
11532 +                       *sd_attrs |= REISERFS_IUNLINK_FL;
11533 +               else
11534 +                       *sd_attrs &= ~REISERFS_IUNLINK_FL;
11535 +               if (inode->i_flags & S_BARRIER)
11536 +                       *sd_attrs |= REISERFS_BARRIER_FL;
11537 +               else
11538 +                       *sd_attrs &= ~REISERFS_BARRIER_FL;
11539                 if (inode->i_flags & S_SYNC)
11540                         *sd_attrs |= REISERFS_SYNC_FL;
11541                 else
11542 @@ -2900,6 +2936,22 @@ static ssize_t reiserfs_direct_IO(int rw
11543                                   reiserfs_get_blocks_direct_io, NULL);
11544  }
11545  
11546 +int reiserfs_sync_flags(struct inode *inode)
11547 +{
11548 +       u16 oldflags, newflags;
11549 +
11550 +       oldflags = REISERFS_I(inode)->i_attrs;
11551 +       newflags = oldflags;
11552 +       i_attrs_to_sd_attrs(inode, &newflags);
11553 +
11554 +       if (oldflags ^ newflags) {
11555 +               REISERFS_I(inode)->i_attrs = newflags;
11556 +               inode->i_ctime = CURRENT_TIME_SEC;
11557 +               mark_inode_dirty(inode);
11558 +       }
11559 +       return 0;
11560 +}
11561 +
11562  int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
11563  {
11564         struct inode *inode = dentry->d_inode;
11565 @@ -2949,9 +3001,11 @@ int reiserfs_setattr(struct dentry *dent
11566         }
11567  
11568         error = inode_change_ok(inode, attr);
11569 +
11570         if (!error) {
11571                 if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
11572 -                   (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
11573 +                   (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid) ||
11574 +                   (ia_valid & ATTR_TAG && attr->ia_tag != inode->i_tag)) {
11575                         error = reiserfs_chown_xattrs(inode, attr);
11576  
11577                         if (!error) {
11578 @@ -2981,6 +3035,9 @@ int reiserfs_setattr(struct dentry *dent
11579                                         inode->i_uid = attr->ia_uid;
11580                                 if (attr->ia_valid & ATTR_GID)
11581                                         inode->i_gid = attr->ia_gid;
11582 +                               if ((attr->ia_valid & ATTR_TAG) &&
11583 +                                       IS_TAGGED(inode))
11584 +                                       inode->i_tag = attr->ia_tag;
11585                                 mark_inode_dirty(inode);
11586                                 error =
11587                                     journal_end(&th, inode->i_sb, jbegin_count);
11588 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/ioctl.c
11589 --- linux-2.6.19.1/fs/reiserfs/ioctl.c  2006-11-30 21:19:28 +0100
11590 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/ioctl.c        2006-11-08 04:57:52 +0100
11591 @@ -4,6 +4,7 @@
11592  
11593  #include <linux/capability.h>
11594  #include <linux/fs.h>
11595 +#include <linux/mount.h>
11596  #include <linux/reiserfs_fs.h>
11597  #include <linux/time.h>
11598  #include <asm/uaccess.h>
11599 @@ -24,7 +25,7 @@ static int reiserfs_unpack(struct inode 
11600  int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
11601                    unsigned long arg)
11602  {
11603 -       unsigned int flags;
11604 +       unsigned int flags, oldflags;
11605  
11606         switch (cmd) {
11607         case REISERFS_IOC_UNPACK:
11608 @@ -43,12 +44,14 @@ int reiserfs_ioctl(struct inode *inode, 
11609  
11610                 flags = REISERFS_I(inode)->i_attrs;
11611                 i_attrs_to_sd_attrs(inode, (__u16 *) & flags);
11612 +               flags &= REISERFS_FL_USER_VISIBLE;
11613                 return put_user(flags, (int __user *)arg);
11614         case REISERFS_IOC_SETFLAGS:{
11615                         if (!reiserfs_attrs(inode->i_sb))
11616                                 return -ENOTTY;
11617  
11618 -                       if (IS_RDONLY(inode))
11619 +                       if (IS_RDONLY(inode) ||
11620 +                               (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
11621                                 return -EROFS;
11622  
11623                         if ((current->fsuid != inode->i_uid)
11624 @@ -58,10 +61,12 @@ int reiserfs_ioctl(struct inode *inode, 
11625                         if (get_user(flags, (int __user *)arg))
11626                                 return -EFAULT;
11627  
11628 -                       if (((flags ^ REISERFS_I(inode)->
11629 -                             i_attrs) & (REISERFS_IMMUTABLE_FL |
11630 -                                         REISERFS_APPEND_FL))
11631 -                           && !capable(CAP_LINUX_IMMUTABLE))
11632 +                       oldflags = REISERFS_I(inode) -> i_attrs;
11633 +                       if (((oldflags & REISERFS_IMMUTABLE_FL) ||
11634 +                               ((flags ^ oldflags) &
11635 +                               (REISERFS_IMMUTABLE_FL | REISERFS_IUNLINK_FL |
11636 +                                REISERFS_APPEND_FL))) &&
11637 +                               !capable(CAP_LINUX_IMMUTABLE))
11638                                 return -EPERM;
11639  
11640                         if ((flags & REISERFS_NOTAIL_FL) &&
11641 @@ -72,6 +77,9 @@ int reiserfs_ioctl(struct inode *inode, 
11642                                 if (result)
11643                                         return result;
11644                         }
11645 +
11646 +                       flags = flags & REISERFS_FL_USER_MODIFIABLE;
11647 +                       flags |= oldflags & ~REISERFS_FL_USER_MODIFIABLE;
11648                         sd_attrs_to_i_attrs(flags, inode);
11649                         REISERFS_I(inode)->i_attrs = flags;
11650                         inode->i_ctime = CURRENT_TIME_SEC;
11651 @@ -83,7 +91,8 @@ int reiserfs_ioctl(struct inode *inode, 
11652         case REISERFS_IOC_SETVERSION:
11653                 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
11654                         return -EPERM;
11655 -               if (IS_RDONLY(inode))
11656 +               if (IS_RDONLY(inode) ||
11657 +                       (filp && MNT_IS_RDONLY(filp->f_vfsmnt)))
11658                         return -EROFS;
11659                 if (get_user(inode->i_generation, (int __user *)arg))
11660                         return -EFAULT;
11661 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/namei.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/namei.c
11662 --- linux-2.6.19.1/fs/reiserfs/namei.c  2006-11-30 21:19:28 +0100
11663 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/namei.c        2006-11-08 04:57:47 +0100
11664 @@ -18,6 +18,7 @@
11665  #include <linux/reiserfs_xattr.h>
11666  #include <linux/smp_lock.h>
11667  #include <linux/quotaops.h>
11668 +#include <linux/vs_tag.h>
11669  
11670  #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
11671  #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i);
11672 @@ -361,6 +362,7 @@ static struct dentry *reiserfs_lookup(st
11673                         reiserfs_write_unlock(dir->i_sb);
11674                         return ERR_PTR(-EACCES);
11675                 }
11676 +               dx_propagate_tag(nd, inode);
11677  
11678                 /* Propogate the priv_object flag so we know we're in the priv tree */
11679                 if (is_reiserfs_priv_object(dir))
11680 @@ -596,6 +598,7 @@ static int new_inode_init(struct inode *
11681         } else {
11682                 inode->i_gid = current->fsgid;
11683         }
11684 +       inode->i_tag = dx_current_fstag(inode->i_sb);
11685         DQUOT_INIT(inode);
11686         return 0;
11687  }
11688 @@ -1542,6 +1545,7 @@ struct inode_operations reiserfs_dir_ino
11689         .listxattr = reiserfs_listxattr,
11690         .removexattr = reiserfs_removexattr,
11691         .permission = reiserfs_permission,
11692 +       .sync_flags = reiserfs_sync_flags,
11693  };
11694  
11695  /*
11696 @@ -1558,6 +1562,7 @@ struct inode_operations reiserfs_symlink
11697         .listxattr = reiserfs_listxattr,
11698         .removexattr = reiserfs_removexattr,
11699         .permission = reiserfs_permission,
11700 +       .sync_flags = reiserfs_sync_flags,
11701  
11702  };
11703  
11704 @@ -1571,5 +1576,6 @@ struct inode_operations reiserfs_special
11705         .listxattr = reiserfs_listxattr,
11706         .removexattr = reiserfs_removexattr,
11707         .permission = reiserfs_permission,
11708 +       .sync_flags = reiserfs_sync_flags,
11709  
11710  };
11711 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/stree.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/stree.c
11712 --- linux-2.6.19.1/fs/reiserfs/stree.c  2006-11-30 21:19:28 +0100
11713 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/stree.c        2006-11-08 04:57:50 +0100
11714 @@ -56,6 +56,7 @@
11715  #include <linux/smp_lock.h>
11716  #include <linux/buffer_head.h>
11717  #include <linux/quotaops.h>
11718 +#include <linux/vs_dlimit.h>
11719  
11720  /* Does the buffer contain a disk block which is in the tree. */
11721  inline int B_IS_IN_TREE(const struct buffer_head *p_s_bh)
11722 @@ -1297,6 +1298,7 @@ int reiserfs_delete_item(struct reiserfs
11723                        "reiserquota delete_item(): freeing %u, id=%u type=%c",
11724                        quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih));
11725  #endif
11726 +       DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes);
11727         DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
11728  
11729         /* Return deleted body length */
11730 @@ -1385,6 +1387,7 @@ void reiserfs_delete_solid_item(struct r
11731  #endif
11732                                 DQUOT_FREE_SPACE_NODIRTY(inode,
11733                                                          quota_cut_bytes);
11734 +                               DLIMIT_FREE_SPACE(inode, quota_cut_bytes);
11735                         }
11736                         break;
11737                 }
11738 @@ -1738,6 +1741,7 @@ int reiserfs_cut_from_item(struct reiser
11739                        "reiserquota cut_from_item(): freeing %u id=%u type=%c",
11740                        quota_cut_bytes, p_s_inode->i_uid, '?');
11741  #endif
11742 +       DLIMIT_FREE_SPACE(p_s_inode, quota_cut_bytes);
11743         DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
11744         return n_ret_value;
11745  }
11746 @@ -1979,6 +1983,11 @@ int reiserfs_paste_into_item(struct reis
11747                 pathrelse(p_s_search_path);
11748                 return -EDQUOT;
11749         }
11750 +       if (DLIMIT_ALLOC_SPACE(inode, n_pasted_size)) {
11751 +               DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
11752 +               pathrelse(p_s_search_path);
11753 +               return -ENOSPC;
11754 +       }
11755         init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path,
11756                        n_pasted_size);
11757  #ifdef DISPLACE_NEW_PACKING_LOCALITIES
11758 @@ -2031,6 +2040,7 @@ int reiserfs_paste_into_item(struct reis
11759                        n_pasted_size, inode->i_uid,
11760                        key2type(&(p_s_key->on_disk_key)));
11761  #endif
11762 +       DLIMIT_FREE_SPACE(inode, n_pasted_size);
11763         DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
11764         return retval;
11765  }
11766 @@ -2068,6 +2078,11 @@ int reiserfs_insert_item(struct reiserfs
11767                         pathrelse(p_s_path);
11768                         return -EDQUOT;
11769                 }
11770 +               if (DLIMIT_ALLOC_SPACE(inode, quota_bytes)) {
11771 +                       DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
11772 +                       pathrelse(p_s_path);
11773 +                       return -ENOSPC;
11774 +               }
11775         }
11776         init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path,
11777                        IH_SIZE + ih_item_len(p_s_ih));
11778 @@ -2115,7 +2130,9 @@ int reiserfs_insert_item(struct reiserfs
11779                        "reiserquota insert_item(): freeing %u id=%u type=%c",
11780                        quota_bytes, inode->i_uid, head2type(p_s_ih));
11781  #endif
11782 -       if (inode)
11783 +       if (inode) {
11784 +               DLIMIT_FREE_SPACE(inode, quota_bytes);
11785                 DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
11786 +       }
11787         return retval;
11788  }
11789 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/super.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/super.c
11790 --- linux-2.6.19.1/fs/reiserfs/super.c  2006-11-30 21:19:28 +0100
11791 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/super.c        2006-11-08 21:52:09 +0100
11792 @@ -137,7 +137,7 @@ static int remove_save_link_only(struct 
11793  }
11794  
11795  #ifdef CONFIG_QUOTA
11796 -static int reiserfs_quota_on_mount(struct super_block *, int);
11797 +static int reiserfs_quota_on_mount(struct dqhash *, int);
11798  #endif
11799  
11800  /* look for uncompleted unlinks and truncates and complete them */
11801 @@ -177,7 +177,7 @@ static int finish_unfinished(struct supe
11802         /* Turn on quotas so that they are updated correctly */
11803         for (i = 0; i < MAXQUOTAS; i++) {
11804                 if (REISERFS_SB(s)->s_qf_names[i]) {
11805 -                       int ret = reiserfs_quota_on_mount(s, i);
11806 +                       int ret = reiserfs_quota_on_mount(s->s_dqh, i);
11807                         if (ret < 0)
11808                                 reiserfs_warning(s,
11809                                                  "reiserfs: cannot turn on journalled quota: error %d",
11810 @@ -291,8 +291,8 @@ static int finish_unfinished(struct supe
11811  #ifdef CONFIG_QUOTA
11812         /* Turn quotas off */
11813         for (i = 0; i < MAXQUOTAS; i++) {
11814 -               if (sb_dqopt(s)->files[i])
11815 -                       vfs_quota_off_mount(s, i);
11816 +               if (dqh_dqopt(s->s_dqh)->files[i])
11817 +                       vfs_quota_off_mount(s->s_dqh, i);
11818         }
11819         if (ms_active_set)
11820                 /* Restore the flag back */
11821 @@ -587,9 +587,9 @@ static void reiserfs_clear_inode(struct 
11822  #endif
11823  
11824  #ifdef CONFIG_QUOTA
11825 -static ssize_t reiserfs_quota_write(struct super_block *, int, const char *,
11826 +static ssize_t reiserfs_quota_write(struct dqhash *, int, const char *,
11827                                     size_t, loff_t);
11828 -static ssize_t reiserfs_quota_read(struct super_block *, int, char *, size_t,
11829 +static ssize_t reiserfs_quota_read(struct dqhash *, int, char *, size_t,
11830                                    loff_t);
11831  #endif
11832  
11833 @@ -622,8 +622,8 @@ static int reiserfs_write_dquot(struct d
11834  static int reiserfs_acquire_dquot(struct dquot *);
11835  static int reiserfs_release_dquot(struct dquot *);
11836  static int reiserfs_mark_dquot_dirty(struct dquot *);
11837 -static int reiserfs_write_info(struct super_block *, int);
11838 -static int reiserfs_quota_on(struct super_block *, int, int, char *);
11839 +static int reiserfs_write_info(struct dqhash *, int);
11840 +static int reiserfs_quota_on(struct dqhash *, int, int, char *);
11841  
11842  static struct dquot_operations reiserfs_quota_operations = {
11843         .initialize = reiserfs_dquot_initialize,
11844 @@ -885,6 +885,14 @@ static int reiserfs_parse_options(struct
11845                 {"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},
11846                 {"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},
11847  #endif
11848 +#ifndef CONFIG_TAGGING_NONE
11849 +               {"tagxid",.setmask = 1 << REISERFS_TAGGED},
11850 +               {"tag",.setmask = 1 << REISERFS_TAGGED},
11851 +               {"notag",.clrmask = 1 << REISERFS_TAGGED},
11852 +#endif
11853 +#ifdef CONFIG_PROPAGATE
11854 +               {"tag",.arg_required = 'T',.values = NULL},
11855 +#endif
11856  #ifdef CONFIG_REISERFS_FS_POSIX_ACL
11857                 {"acl",.setmask = 1 << REISERFS_POSIXACL},
11858                 {"noacl",.clrmask = 1 << REISERFS_POSIXACL},
11859 @@ -981,7 +989,7 @@ static int reiserfs_parse_options(struct
11860                 if (c == 'u' || c == 'g') {
11861                         int qtype = c == 'u' ? USRQUOTA : GRPQUOTA;
11862  
11863 -                       if (sb_any_quota_enabled(s)) {
11864 +                       if (dqh_any_quota_enabled(s->s_dqh)) {
11865                                 reiserfs_warning(s,
11866                                                  "reiserfs_parse_options: cannot change journalled quota options when quota turned on.");
11867                                 return 0;
11868 @@ -1044,7 +1052,7 @@ static int reiserfs_parse_options(struct
11869         }
11870         /* This checking is not precise wrt the quota type but for our purposes it is sufficient */
11871         if (!(*mount_options & (1 << REISERFS_QUOTA))
11872 -           && sb_any_quota_enabled(s)) {
11873 +           && dqh_any_quota_enabled(s->s_dqh)) {
11874                 reiserfs_warning(s,
11875                                  "reiserfs_parse_options: quota options must be present when quota is turned on.");
11876                 return 0;
11877 @@ -1146,6 +1154,12 @@ static int reiserfs_remount(struct super
11878                 return -EINVAL;
11879         }
11880  
11881 +       if ((mount_options & (1 << REISERFS_TAGGED)) &&
11882 +               !(s->s_flags & MS_TAGGED)) {
11883 +               reiserfs_warning(s, "reiserfs: tagging not permitted on remount.");
11884 +               return -EINVAL;
11885 +       }
11886 +
11887         handle_attrs(s);
11888  
11889         /* Add options that are safe here */
11890 @@ -1336,7 +1350,7 @@ static int read_super_block(struct super
11891         s->s_export_op = &reiserfs_export_ops;
11892  #ifdef CONFIG_QUOTA
11893         s->s_qcop = &reiserfs_qctl_operations;
11894 -       s->dq_op = &reiserfs_quota_operations;
11895 +       s->s_qop = &reiserfs_quota_operations;
11896  #endif
11897  
11898         /* new format is limited by the 32 bit wide i_blocks field, want to
11899 @@ -1594,6 +1608,10 @@ static int reiserfs_fill_super(struct su
11900                 goto error;
11901         }
11902  
11903 +       /* map mount option tagxid */
11904 +       if (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_TAGGED))
11905 +               s->s_flags |= MS_TAGGED;
11906 +
11907         rs = SB_DISK_SUPER_BLOCK(s);
11908         /* Let's do basic sanity check to verify that underlying device is not
11909            smaller than the filesystem. If the check fails then abort and scream,
11910 @@ -1869,16 +1887,16 @@ static int reiserfs_write_dquot(struct d
11911         struct reiserfs_transaction_handle th;
11912         int ret, err;
11913  
11914 -       reiserfs_write_lock(dquot->dq_sb);
11915 +       reiserfs_write_lock(dquot->dq_dqh->dqh_sb);
11916         ret =
11917 -           journal_begin(&th, dquot->dq_sb,
11918 -                         REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
11919 +           journal_begin(&th, dquot->dq_dqh->dqh_sb,
11920 +               REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb));
11921         if (ret)
11922                 goto out;
11923         ret = dquot_commit(dquot);
11924         err =
11925 -           journal_end(&th, dquot->dq_sb,
11926 -                       REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
11927 +           journal_end(&th, dquot->dq_dqh->dqh_sb,
11928 +               REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_dqh->dqh_sb));
11929         if (!ret && err)
11930                 ret = err;
11931        out:
11932 @@ -1891,20 +1909,20 @@ static int reiserfs_acquire_dquot(struct
11933         struct reiserfs_transaction_handle th;
11934         int ret, err;
11935  
11936 -       reiserfs_write_lock(dquot->dq_sb);
11937 +       reiserfs_write_lock(dquot->dq_dqh->dqh_sb);
11938         ret =
11939 -           journal_begin(&th, dquot->dq_sb,
11940 -                         REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
11941 +           journal_begin(&th, dquot->dq_dqh->dqh_sb,
11942 +               REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb));
11943         if (ret)
11944                 goto out;
11945         ret = dquot_acquire(dquot);
11946         err =
11947 -           journal_end(&th, dquot->dq_sb,
11948 -                       REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
11949 +           journal_end(&th, dquot->dq_dqh->dqh_sb,
11950 +               REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_dqh->dqh_sb));
11951         if (!ret && err)
11952                 ret = err;
11953        out:
11954 -       reiserfs_write_unlock(dquot->dq_sb);
11955 +       reiserfs_write_unlock(dquot->dq_dqh->dqh_sb);
11956         return ret;
11957  }
11958  
11959 @@ -1913,37 +1931,38 @@ static int reiserfs_release_dquot(struct
11960         struct reiserfs_transaction_handle th;
11961         int ret, err;
11962  
11963 -       reiserfs_write_lock(dquot->dq_sb);
11964 +       reiserfs_write_lock(dquot->dq_dqh->dqh_sb);
11965         ret =
11966 -           journal_begin(&th, dquot->dq_sb,
11967 -                         REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
11968 +           journal_begin(&th, dquot->dq_dqh->dqh_sb,
11969 +               REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb));
11970         if (ret)
11971                 goto out;
11972         ret = dquot_release(dquot);
11973         err =
11974 -           journal_end(&th, dquot->dq_sb,
11975 -                       REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
11976 +           journal_end(&th, dquot->dq_dqh->dqh_sb,
11977 +               REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_dqh->dqh_sb));
11978         if (!ret && err)
11979                 ret = err;
11980        out:
11981 -       reiserfs_write_unlock(dquot->dq_sb);
11982 +       reiserfs_write_unlock(dquot->dq_dqh->dqh_sb);
11983         return ret;
11984  }
11985  
11986  static int reiserfs_mark_dquot_dirty(struct dquot *dquot)
11987  {
11988         /* Are we journalling quotas? */
11989 -       if (REISERFS_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
11990 -           REISERFS_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
11991 +       if (REISERFS_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[USRQUOTA] ||
11992 +           REISERFS_SB(dquot->dq_dqh->dqh_sb)->s_qf_names[GRPQUOTA]) {
11993                 dquot_mark_dquot_dirty(dquot);
11994                 return reiserfs_write_dquot(dquot);
11995         } else
11996                 return dquot_mark_dquot_dirty(dquot);
11997  }
11998  
11999 -static int reiserfs_write_info(struct super_block *sb, int type)
12000 +static int reiserfs_write_info(struct dqhash *hash, int type)
12001  {
12002         struct reiserfs_transaction_handle th;
12003 +       struct super_block *sb = hash->dqh_sb;
12004         int ret, err;
12005  
12006         /* Data block + inode block */
12007 @@ -1951,7 +1970,7 @@ static int reiserfs_write_info(struct su
12008         ret = journal_begin(&th, sb, 2);
12009         if (ret)
12010                 goto out;
12011 -       ret = dquot_commit_info(sb, type);
12012 +       ret = dquot_commit_info(hash, type);
12013         err = journal_end(&th, sb, 2);
12014         if (!ret && err)
12015                 ret = err;
12016 @@ -1963,18 +1982,21 @@ static int reiserfs_write_info(struct su
12017  /*
12018   * Turn on quotas during mount time - we need to find the quota file and such...
12019   */
12020 -static int reiserfs_quota_on_mount(struct super_block *sb, int type)
12021 +static int reiserfs_quota_on_mount(struct dqhash *hash, int type)
12022  {
12023 -       return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type],
12024 +       struct super_block *sb = hash->dqh_sb;
12025 +
12026 +       return vfs_quota_on_mount(hash, REISERFS_SB(sb)->s_qf_names[type],
12027                                   REISERFS_SB(sb)->s_jquota_fmt, type);
12028  }
12029  
12030  /*
12031   * Standard function to be called on quota_on
12032   */
12033 -static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
12034 +static int reiserfs_quota_on(struct dqhash *hash, int type, int format_id,
12035                              char *path)
12036  {
12037 +       struct super_block *sb = hash->dqh_sb;
12038         int err;
12039         struct nameidata nd;
12040  
12041 @@ -1999,7 +2021,7 @@ static int reiserfs_quota_on(struct supe
12042         if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&
12043             !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) {
12044                 path_release(&nd);
12045 -               return vfs_quota_on(sb, type, format_id, path);
12046 +               return vfs_quota_on(hash, type, format_id, path);
12047         }
12048         /* Quotafile not of fs root? */
12049         if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
12050 @@ -2007,17 +2029,18 @@ static int reiserfs_quota_on(struct supe
12051                                  "reiserfs: Quota file not on filesystem root. "
12052                                  "Journalled quota will not work.");
12053         path_release(&nd);
12054 -       return vfs_quota_on(sb, type, format_id, path);
12055 +       return vfs_quota_on(hash, type, format_id, path);
12056  }
12057  
12058  /* Read data from quotafile - avoid pagecache and such because we cannot afford
12059   * acquiring the locks... As quota files are never truncated and quota code
12060   * itself serializes the operations (and noone else should touch the files)
12061   * we don't have to be afraid of races */
12062 -static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data,
12063 +static ssize_t reiserfs_quota_read(struct dqhash *hash, int type, char *data,
12064                                    size_t len, loff_t off)
12065  {
12066 -       struct inode *inode = sb_dqopt(sb)->files[type];
12067 +       struct inode *inode = dqh_dqopt(hash)->files[type];
12068 +       struct super_block *sb = hash->dqh_sb;
12069         unsigned long blk = off >> sb->s_blocksize_bits;
12070         int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
12071         size_t toread;
12072 @@ -2059,10 +2082,11 @@ static ssize_t reiserfs_quota_read(struc
12073  
12074  /* Write to quotafile (we know the transaction is already started and has
12075   * enough credits) */
12076 -static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
12077 +static ssize_t reiserfs_quota_write(struct dqhash *hash, int type,
12078                                     const char *data, size_t len, loff_t off)
12079  {
12080 -       struct inode *inode = sb_dqopt(sb)->files[type];
12081 +       struct inode *inode = dqh_dqopt(hash)->files[type];
12082 +       struct super_block *sb = hash->dqh_sb;
12083         unsigned long blk = off >> sb->s_blocksize_bits;
12084         int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
12085         int journal_quota = REISERFS_SB(sb)->s_qf_names[type] != NULL;
12086 diff -NurpP --minimal linux-2.6.19.1/fs/reiserfs/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/xattr.c
12087 --- linux-2.6.19.1/fs/reiserfs/xattr.c  2006-11-30 21:19:28 +0100
12088 +++ linux-2.6.19.1-vs2.3.0.6/fs/reiserfs/xattr.c        2006-11-08 04:57:52 +0100
12089 @@ -35,6 +35,7 @@
12090  #include <linux/namei.h>
12091  #include <linux/errno.h>
12092  #include <linux/fs.h>
12093 +#include <linux/mount.h>
12094  #include <linux/file.h>
12095  #include <linux/pagemap.h>
12096  #include <linux/xattr.h>
12097 @@ -823,7 +824,7 @@ int reiserfs_delete_xattrs(struct inode 
12098         if (dir->d_inode->i_nlink <= 2) {
12099                 root = get_xa_root(inode->i_sb);
12100                 reiserfs_write_lock_xattrs(inode->i_sb);
12101 -               err = vfs_rmdir(root->d_inode, dir);
12102 +               err = vfs_rmdir(root->d_inode, dir, NULL);
12103                 reiserfs_write_unlock_xattrs(inode->i_sb);
12104                 dput(root);
12105         } else {
12106 diff -NurpP --minimal linux-2.6.19.1/fs/stat.c linux-2.6.19.1-vs2.3.0.6/fs/stat.c
12107 --- linux-2.6.19.1/fs/stat.c    2006-11-30 21:19:28 +0100
12108 +++ linux-2.6.19.1-vs2.3.0.6/fs/stat.c  2006-11-08 04:57:46 +0100
12109 @@ -27,6 +27,7 @@ void generic_fillattr(struct inode *inod
12110         stat->nlink = inode->i_nlink;
12111         stat->uid = inode->i_uid;
12112         stat->gid = inode->i_gid;
12113 +       stat->tag = inode->i_tag;
12114         stat->rdev = inode->i_rdev;
12115         stat->atime = inode->i_atime;
12116         stat->mtime = inode->i_mtime;
12117 diff -NurpP --minimal linux-2.6.19.1/fs/super.c linux-2.6.19.1-vs2.3.0.6/fs/super.c
12118 --- linux-2.6.19.1/fs/super.c   2006-11-30 21:19:28 +0100
12119 +++ linux-2.6.19.1-vs2.3.0.6/fs/super.c 2006-11-30 19:49:06 +0100
12120 @@ -37,6 +37,9 @@
12121  #include <linux/idr.h>
12122  #include <linux/kobject.h>
12123  #include <linux/mutex.h>
12124 +#include <linux/devpts_fs.h>
12125 +#include <linux/proc_fs.h>
12126 +#include <linux/vs_context.h>
12127  #include <asm/uaccess.h>
12128  
12129  
12130 @@ -84,15 +87,14 @@ static struct super_block *alloc_super(s
12131                 s->s_count = S_BIAS;
12132                 atomic_set(&s->s_active, 1);
12133                 mutex_init(&s->s_vfs_rename_mutex);
12134 -               mutex_init(&s->s_dquot.dqio_mutex);
12135 -               mutex_init(&s->s_dquot.dqonoff_mutex);
12136 -               init_rwsem(&s->s_dquot.dqptr_sem);
12137                 init_waitqueue_head(&s->s_wait_unfrozen);
12138                 s->s_maxbytes = MAX_NON_LFS;
12139 -               s->dq_op = sb_dquot_ops;
12140 +               s->s_qop = sb_dquot_ops;
12141                 s->s_qcop = sb_quotactl_ops;
12142                 s->s_op = &default_op;
12143                 s->s_time_gran = 1000000000;
12144 +               /* quick hack to make dqhash id unique, sufficient for now */
12145 +               s->s_dqh = new_dqhash(s, (unsigned long)s);
12146         }
12147  out:
12148         return s;
12149 @@ -107,6 +109,7 @@ out:
12150  static inline void destroy_super(struct super_block *s)
12151  {
12152         security_sb_free(s);
12153 +       dqhput(s->s_dqh);
12154         kfree(s);
12155  }
12156  
12157 @@ -178,7 +181,7 @@ void deactivate_super(struct super_block
12158         if (atomic_dec_and_lock(&s->s_active, &sb_lock)) {
12159                 s->s_count -= S_BIAS-1;
12160                 spin_unlock(&sb_lock);
12161 -               DQUOT_OFF(s);
12162 +               DQUOT_OFF(s->s_dqh);
12163                 down_write(&s->s_umount);
12164                 fs->kill_sb(s);
12165                 put_filesystem(fs);
12166 @@ -229,7 +232,7 @@ static int grab_super(struct super_block
12167  void __fsync_super(struct super_block *sb)
12168  {
12169         sync_inodes_sb(sb, 0);
12170 -       DQUOT_SYNC(sb);
12171 +       DQUOT_SYNC(sb->s_dqh);
12172         lock_super(sb);
12173         if (sb->s_dirt && sb->s_op->write_super)
12174                 sb->s_op->write_super(sb);
12175 @@ -853,6 +856,7 @@ struct vfsmount *
12176  vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
12177  {
12178         struct vfsmount *mnt;
12179 +       struct super_block *sb;
12180         char *secdata = NULL;
12181         int error;
12182  
12183 @@ -878,7 +882,14 @@ vfs_kern_mount(struct file_system_type *
12184         if (error < 0)
12185                 goto out_free_secdata;
12186  
12187 -       error = security_sb_kern_mount(mnt->mnt_sb, secdata);
12188 +       sb = mnt->mnt_sb;
12189 +       error = -EPERM;
12190 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT) && !sb->s_bdev &&
12191 +               (sb->s_magic != PROC_SUPER_MAGIC) &&
12192 +               (sb->s_magic != DEVPTS_SUPER_MAGIC))
12193 +               goto out_sb;
12194 +
12195 +       error = security_sb_kern_mount(sb, secdata);
12196         if (error)
12197                 goto out_sb;
12198  
12199 @@ -906,9 +917,17 @@ do_kern_mount(const char *fstype, int fl
12200  {
12201         struct file_system_type *type = get_fs_type(fstype);
12202         struct vfsmount *mnt;
12203 +
12204         if (!type)
12205                 return ERR_PTR(-ENODEV);
12206 +
12207 +       mnt = ERR_PTR(-EPERM);
12208 +       if ((type->fs_flags & FS_BINARY_MOUNTDATA) &&
12209 +               !vx_capable(CAP_SYS_ADMIN, VXC_BINARY_MOUNT))
12210 +               goto out_put;
12211 +
12212         mnt = vfs_kern_mount(type, flags, name, data);
12213 +out_put:
12214         put_filesystem(type);
12215         return mnt;
12216  }
12217 diff -NurpP --minimal linux-2.6.19.1/fs/sysfs/mount.c linux-2.6.19.1-vs2.3.0.6/fs/sysfs/mount.c
12218 --- linux-2.6.19.1/fs/sysfs/mount.c     2006-11-30 21:19:28 +0100
12219 +++ linux-2.6.19.1-vs2.3.0.6/fs/sysfs/mount.c   2006-11-08 04:57:53 +0100
12220 @@ -11,8 +11,6 @@
12221  
12222  #include "sysfs.h"
12223  
12224 -/* Random magic number */
12225 -#define SYSFS_MAGIC 0x62656572
12226  
12227  struct vfsmount *sysfs_mount;
12228  struct super_block * sysfs_sb = NULL;
12229 @@ -38,7 +36,7 @@ static int sysfs_fill_super(struct super
12230  
12231         sb->s_blocksize = PAGE_CACHE_SIZE;
12232         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
12233 -       sb->s_magic = SYSFS_MAGIC;
12234 +       sb->s_magic = SYSFS_SUPER_MAGIC;
12235         sb->s_op = &sysfs_ops;
12236         sb->s_time_gran = 1;
12237         sysfs_sb = sb;
12238 diff -NurpP --minimal linux-2.6.19.1/fs/udf/super.c linux-2.6.19.1-vs2.3.0.6/fs/udf/super.c
12239 --- linux-2.6.19.1/fs/udf/super.c       2006-11-30 21:19:28 +0100
12240 +++ linux-2.6.19.1-vs2.3.0.6/fs/udf/super.c     2006-11-08 04:57:51 +0100
12241 @@ -1576,7 +1576,7 @@ static int udf_fill_super(struct super_b
12242  
12243         /* Fill in the rest of the superblock */
12244         sb->s_op = &udf_sb_ops;
12245 -       sb->dq_op = NULL;
12246 +       sb->s_qop = NULL;
12247         sb->s_dirt = 0;
12248         sb->s_magic = UDF_SUPER_MAGIC;
12249         sb->s_time_gran = 1000;
12250 diff -NurpP --minimal linux-2.6.19.1/fs/ufs/super.c linux-2.6.19.1-vs2.3.0.6/fs/ufs/super.c
12251 --- linux-2.6.19.1/fs/ufs/super.c       2006-11-30 21:19:28 +0100
12252 +++ linux-2.6.19.1-vs2.3.0.6/fs/ufs/super.c     2006-11-08 04:57:51 +0100
12253 @@ -930,7 +930,7 @@ magic_found:
12254          * Read ufs_super_block into internal data structures
12255          */
12256         sb->s_op = &ufs_super_ops;
12257 -       sb->dq_op = NULL; /***/
12258 +       sb->s_qop = NULL; /***/
12259         sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic);
12260  
12261         uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno);
12262 @@ -1248,8 +1248,8 @@ static void destroy_inodecache(void)
12263  }
12264  
12265  #ifdef CONFIG_QUOTA
12266 -static ssize_t ufs_quota_read(struct super_block *, int, char *,size_t, loff_t);
12267 -static ssize_t ufs_quota_write(struct super_block *, int, const char *, size_t, loff_t);
12268 +static ssize_t ufs_quota_read(struct dqhash *, int, char *,size_t, loff_t);
12269 +static ssize_t ufs_quota_write(struct dqhash *, int, const char *, size_t, loff_t);
12270  #endif
12271  
12272  static struct super_operations ufs_super_ops = {
12273 @@ -1274,10 +1274,11 @@ static struct super_operations ufs_super
12274   * acquiring the locks... As quota files are never truncated and quota code
12275   * itself serializes the operations (and noone else should touch the files)
12276   * we don't have to be afraid of races */
12277 -static ssize_t ufs_quota_read(struct super_block *sb, int type, char *data,
12278 +static ssize_t ufs_quota_read(struct dqhash *hash, int type, char *data,
12279                                size_t len, loff_t off)
12280  {
12281 -       struct inode *inode = sb_dqopt(sb)->files[type];
12282 +       struct inode *inode = dqh_dqopt(hash)->files[type];
12283 +       struct super_block *sb = hash->dqh_sb;
12284         sector_t blk = off >> sb->s_blocksize_bits;
12285         int err = 0;
12286         int offset = off & (sb->s_blocksize - 1);
12287 @@ -1313,10 +1314,11 @@ static ssize_t ufs_quota_read(struct sup
12288  }
12289  
12290  /* Write to quotafile */
12291 -static ssize_t ufs_quota_write(struct super_block *sb, int type,
12292 +static ssize_t ufs_quota_write(struct dqhash *hash, int type,
12293                                 const char *data, size_t len, loff_t off)
12294  {
12295 -       struct inode *inode = sb_dqopt(sb)->files[type];
12296 +       struct inode *inode = dqh_dqopt(hash)->files[type];
12297 +       struct super_block *sb = hash->dqh_sb;
12298         sector_t blk = off >> sb->s_blocksize_bits;
12299         int err = 0;
12300         int offset = off & (sb->s_blocksize - 1);
12301 diff -NurpP --minimal linux-2.6.19.1/fs/utimes.c linux-2.6.19.1-vs2.3.0.6/fs/utimes.c
12302 --- linux-2.6.19.1/fs/utimes.c  2006-11-30 21:19:28 +0100
12303 +++ linux-2.6.19.1-vs2.3.0.6/fs/utimes.c        2006-11-08 22:44:42 +0100
12304 @@ -3,6 +3,8 @@
12305  #include <linux/linkage.h>
12306  #include <linux/namei.h>
12307  #include <linux/utime.h>
12308 +#include <linux/mount.h>
12309 +#include <linux/vs_cowbl.h>
12310  #include <asm/uaccess.h>
12311  #include <asm/unistd.h>
12312  
12313 @@ -32,7 +34,7 @@ asmlinkage long sys_utime(char __user * 
12314         inode = nd.dentry->d_inode;
12315  
12316         error = -EROFS;
12317 -       if (IS_RDONLY(inode))
12318 +       if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd.mnt))
12319                 goto dput_and_out;
12320  
12321         /* Don't worry, the checks are done in inode_change_ok() */
12322 @@ -83,14 +85,13 @@ long do_utimes(int dfd, char __user *fil
12323         struct iattr newattrs;
12324  
12325         error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
12326 -
12327         if (error)
12328                 goto out;
12329 -       inode = nd.dentry->d_inode;
12330  
12331 -       error = -EROFS;
12332 -       if (IS_RDONLY(inode))
12333 +       error = cow_check_and_break(&nd);
12334 +       if (error)
12335                 goto dput_and_out;
12336 +       inode = nd.dentry->d_inode;
12337  
12338         /* Don't worry, the checks are done in inode_change_ok() */
12339         newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
12340 diff -NurpP --minimal linux-2.6.19.1/fs/xattr.c linux-2.6.19.1-vs2.3.0.6/fs/xattr.c
12341 --- linux-2.6.19.1/fs/xattr.c   2006-11-30 21:19:28 +0100
12342 +++ linux-2.6.19.1-vs2.3.0.6/fs/xattr.c 2006-11-08 21:52:09 +0100
12343 @@ -18,6 +18,7 @@
12344  #include <linux/module.h>
12345  #include <linux/fsnotify.h>
12346  #include <linux/audit.h>
12347 +#include <linux/mount.h>
12348  #include <asm/uaccess.h>
12349  
12350  
12351 @@ -195,7 +196,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
12352   */
12353  static long
12354  setxattr(struct dentry *d, char __user *name, void __user *value,
12355 -        size_t size, int flags)
12356 +        size_t size, int flags, struct vfsmount *mnt)
12357  {
12358         int error;
12359         void *kvalue = NULL;
12360 @@ -222,6 +223,9 @@ setxattr(struct dentry *d, char __user *
12361                 }
12362         }
12363  
12364 +       if (MNT_IS_RDONLY(mnt))
12365 +               return -EROFS;
12366 +
12367         error = vfs_setxattr(d, kname, kvalue, size, flags);
12368         kfree(kvalue);
12369         return error;
12370 @@ -237,7 +241,7 @@ sys_setxattr(char __user *path, char __u
12371         error = user_path_walk(path, &nd);
12372         if (error)
12373                 return error;
12374 -       error = setxattr(nd.dentry, name, value, size, flags);
12375 +       error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
12376         path_release(&nd);
12377         return error;
12378  }
12379 @@ -252,7 +256,7 @@ sys_lsetxattr(char __user *path, char __
12380         error = user_path_walk_link(path, &nd);
12381         if (error)
12382                 return error;
12383 -       error = setxattr(nd.dentry, name, value, size, flags);
12384 +       error = setxattr(nd.dentry, name, value, size, flags, nd.mnt);
12385         path_release(&nd);
12386         return error;
12387  }
12388 @@ -270,7 +274,7 @@ sys_fsetxattr(int fd, char __user *name,
12389                 return error;
12390         dentry = f->f_dentry;
12391         audit_inode(NULL, dentry->d_inode);
12392 -       error = setxattr(dentry, name, value, size, flags);
12393 +       error = setxattr(dentry, name, value, size, flags, f->f_vfsmnt);
12394         fput(f);
12395         return error;
12396  }
12397 @@ -432,7 +436,7 @@ sys_flistxattr(int fd, char __user *list
12398   * Extended attribute REMOVE operations
12399   */
12400  static long
12401 -removexattr(struct dentry *d, char __user *name)
12402 +removexattr(struct dentry *d, char __user *name, struct vfsmount *mnt)
12403  {
12404         int error;
12405         char kname[XATTR_NAME_MAX + 1];
12406 @@ -443,6 +447,9 @@ removexattr(struct dentry *d, char __use
12407         if (error < 0)
12408                 return error;
12409  
12410 +       if (MNT_IS_RDONLY(mnt))
12411 +               return -EROFS;
12412 +
12413         return vfs_removexattr(d, kname);
12414  }
12415  
12416 @@ -455,7 +462,7 @@ sys_removexattr(char __user *path, char 
12417         error = user_path_walk(path, &nd);
12418         if (error)
12419                 return error;
12420 -       error = removexattr(nd.dentry, name);
12421 +       error = removexattr(nd.dentry, name, nd.mnt);
12422         path_release(&nd);
12423         return error;
12424  }
12425 @@ -469,7 +476,7 @@ sys_lremovexattr(char __user *path, char
12426         error = user_path_walk_link(path, &nd);
12427         if (error)
12428                 return error;
12429 -       error = removexattr(nd.dentry, name);
12430 +       error = removexattr(nd.dentry, name, nd.mnt);
12431         path_release(&nd);
12432         return error;
12433  }
12434 @@ -486,7 +493,7 @@ sys_fremovexattr(int fd, char __user *na
12435                 return error;
12436         dentry = f->f_dentry;
12437         audit_inode(NULL, dentry->d_inode);
12438 -       error = removexattr(dentry, name);
12439 +       error = removexattr(dentry, name, f->f_vfsmnt);
12440         fput(f);
12441         return error;
12442  }
12443 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_file.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_file.c
12444 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_file.c  2006-11-30 21:19:29 +0100
12445 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_file.c        2006-11-08 04:57:51 +0100
12446 @@ -453,6 +453,7 @@ const struct file_operations xfs_file_op
12447         .aio_read       = xfs_file_aio_read,
12448         .aio_write      = xfs_file_aio_write,
12449         .sendfile       = xfs_file_sendfile,
12450 +       .sendpage       = generic_file_sendpage,
12451         .splice_read    = xfs_file_splice_read,
12452         .splice_write   = xfs_file_splice_write,
12453         .unlocked_ioctl = xfs_file_ioctl,
12454 @@ -476,6 +477,7 @@ const struct file_operations xfs_invis_f
12455         .aio_read       = xfs_file_aio_read_invis,
12456         .aio_write      = xfs_file_aio_write_invis,
12457         .sendfile       = xfs_file_sendfile_invis,
12458 +       .sendpage       = generic_file_sendpage,
12459         .splice_read    = xfs_file_splice_read_invis,
12460         .splice_write   = xfs_file_splice_write_invis,
12461         .unlocked_ioctl = xfs_file_ioctl_invis,
12462 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_ioctl.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_ioctl.c
12463 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_ioctl.c 2006-11-30 21:19:29 +0100
12464 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_ioctl.c       2006-11-20 21:12:32 +0100
12465 @@ -1100,6 +1100,8 @@ xfs_ioc_fsgeometry(
12466  #define LINUX_XFLAG_APPEND     0x00000020 /* writes to file may only append */
12467  #define LINUX_XFLAG_NODUMP     0x00000040 /* do not dump file */
12468  #define LINUX_XFLAG_NOATIME    0x00000080 /* do not update atime */
12469 +#define LINUX_XFLAG_BARRIER    0x04000000 /* chroot() barrier */
12470 +#define LINUX_XFLAG_IUNLINK    0x08000000 /* immutable unlink */
12471  
12472  STATIC unsigned int
12473  xfs_merge_ioc_xflags(
12474 @@ -1140,6 +1142,10 @@ xfs_di2lxflags(
12475  
12476         if (di_flags & XFS_DIFLAG_IMMUTABLE)
12477                 flags |= LINUX_XFLAG_IMMUTABLE;
12478 +       if (di_flags & XFS_DIFLAG_IUNLINK)
12479 +               flags |= LINUX_XFLAG_IUNLINK;
12480 +       if (di_flags & XFS_DIFLAG_BARRIER)
12481 +               flags |= LINUX_XFLAG_BARRIER;
12482         if (di_flags & XFS_DIFLAG_APPEND)
12483                 flags |= LINUX_XFLAG_APPEND;
12484         if (di_flags & XFS_DIFLAG_SYNC)
12485 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_iops.c
12486 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_iops.c  2006-11-30 21:19:29 +0100
12487 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_iops.c        2006-11-30 18:53:18 +0100
12488 @@ -53,6 +53,7 @@
12489  #include <linux/xattr.h>
12490  #include <linux/namei.h>
12491  #include <linux/security.h>
12492 +#include <linux/vs_tag.h>
12493  
12494  /*
12495   * Get a XFS inode from a given vnode.
12496 @@ -402,6 +403,7 @@ xfs_vn_lookup(
12497                 d_add(dentry, NULL);
12498                 return NULL;
12499         }
12500 +       dx_propagate_tag(nd, vn_to_inode(cvp));
12501  
12502         return d_splice_alias(vn_to_inode(cvp), dentry);
12503  }
12504 @@ -659,6 +661,10 @@ xfs_vn_setattr(
12505         int             flags = 0;
12506         int             error;
12507  
12508 +       error = inode_change_ok(inode, attr);
12509 +       if (error)
12510 +               return error;
12511 +
12512         if (ia_valid & ATTR_UID) {
12513                 vattr.va_mask |= XFS_AT_UID;
12514                 vattr.va_uid = attr->ia_uid;
12515 @@ -667,6 +673,10 @@ xfs_vn_setattr(
12516                 vattr.va_mask |= XFS_AT_GID;
12517                 vattr.va_gid = attr->ia_gid;
12518         }
12519 +       if ((ia_valid & ATTR_TAG) && IS_TAGGED(inode)) {
12520 +               vattr.va_mask |= XFS_AT_TAG;
12521 +               vattr.va_tag = attr->ia_tag;
12522 +       }
12523         if (ia_valid & ATTR_SIZE) {
12524                 vattr.va_mask |= XFS_AT_SIZE;
12525                 vattr.va_size = attr->ia_size;
12526 @@ -712,6 +722,42 @@ xfs_vn_truncate(
12527  }
12528  
12529  STATIC int
12530 +xfs_vn_sync_flags(struct inode *inode)
12531 +{
12532 +       unsigned int oldflags, newflags;
12533 +       int             flags = 0;
12534 +       int             error;
12535 +       bhv_vattr_t     vattr;
12536 +       bhv_vnode_t     *vp = vn_from_inode(inode);
12537 +
12538 +       memset(&vattr, 0, sizeof vattr);
12539 +
12540 +       vattr.va_mask = XFS_AT_XFLAGS;
12541 +       error = bhv_vop_getattr(vp, &vattr, 0, NULL);
12542 +
12543 +       if (error)
12544 +               return error;
12545 +       oldflags = vattr.va_xflags;
12546 +       newflags = oldflags & ~(XFS_XFLAG_IMMUTABLE |
12547 +               XFS_XFLAG_IUNLINK | XFS_XFLAG_BARRIER);
12548 +
12549 +       if (IS_IMMUTABLE(inode))
12550 +               newflags |= XFS_XFLAG_IMMUTABLE;
12551 +       if (IS_IUNLINK(inode))
12552 +               newflags |= XFS_XFLAG_IUNLINK;
12553 +       if (IS_BARRIER(inode))
12554 +               newflags |= XFS_XFLAG_BARRIER;
12555 +
12556 +       if (oldflags ^ newflags) {
12557 +               vattr.va_xflags = newflags;
12558 +               vattr.va_mask |= XFS_AT_XFLAGS;
12559 +               error = bhv_vop_setattr(vp, &vattr, flags, NULL);
12560 +       }
12561 +       vn_revalidate(vp);
12562 +       return error;
12563 +}
12564 +
12565 +STATIC int
12566  xfs_vn_setxattr(
12567         struct dentry   *dentry,
12568         const char      *name,
12569 @@ -824,6 +870,7 @@ struct inode_operations xfs_inode_operat
12570         .getxattr               = xfs_vn_getxattr,
12571         .listxattr              = xfs_vn_listxattr,
12572         .removexattr            = xfs_vn_removexattr,
12573 +       .sync_flags             = xfs_vn_sync_flags,
12574  };
12575  
12576  struct inode_operations xfs_dir_inode_operations = {
12577 @@ -843,6 +890,7 @@ struct inode_operations xfs_dir_inode_op
12578         .getxattr               = xfs_vn_getxattr,
12579         .listxattr              = xfs_vn_listxattr,
12580         .removexattr            = xfs_vn_removexattr,
12581 +       .sync_flags             = xfs_vn_sync_flags,
12582  };
12583  
12584  struct inode_operations xfs_symlink_inode_operations = {
12585 @@ -856,4 +904,5 @@ struct inode_operations xfs_symlink_inod
12586         .getxattr               = xfs_vn_getxattr,
12587         .listxattr              = xfs_vn_listxattr,
12588         .removexattr            = xfs_vn_removexattr,
12589 +       .sync_flags             = xfs_vn_sync_flags,
12590  };
12591 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_linux.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_linux.h
12592 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_linux.h 2006-11-30 21:19:29 +0100
12593 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_linux.h       2006-11-08 04:57:47 +0100
12594 @@ -139,6 +139,7 @@ BUFFER_FNS(PrivateStart, unwritten);
12595  #define current_pid()          (current->pid)
12596  #define current_fsuid(cred)    (current->fsuid)
12597  #define current_fsgid(cred)    (current->fsgid)
12598 +#define current_fstag(cred,vp) (dx_current_fstag(vn_to_inode(vp)->i_sb))
12599  #define current_test_flags(f)  (current->flags & (f))
12600  #define current_set_flags_nested(sp, f)                \
12601                 (*(sp) = current->flags, current->flags |= (f))
12602 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_super.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_super.c
12603 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_super.c 2006-11-30 21:19:29 +0100
12604 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_super.c       2006-11-20 21:12:32 +0100
12605 @@ -158,6 +158,7 @@ xfs_revalidate_inode(
12606         inode->i_nlink  = ip->i_d.di_nlink;
12607         inode->i_uid    = ip->i_d.di_uid;
12608         inode->i_gid    = ip->i_d.di_gid;
12609 +       inode->i_tag    = ip->i_d.di_tag;
12610  
12611         switch (inode->i_mode & S_IFMT) {
12612         case S_IFBLK:
12613 @@ -185,6 +186,14 @@ xfs_revalidate_inode(
12614                 inode->i_flags |= S_IMMUTABLE;
12615         else
12616                 inode->i_flags &= ~S_IMMUTABLE;
12617 +       if (ip->i_d.di_flags & XFS_DIFLAG_IUNLINK)
12618 +               inode->i_flags |= S_IUNLINK;
12619 +       else
12620 +               inode->i_flags &= ~S_IUNLINK;
12621 +       if (ip->i_d.di_flags & XFS_DIFLAG_BARRIER)
12622 +               inode->i_flags |= S_BARRIER;
12623 +       else
12624 +               inode->i_flags &= ~S_BARRIER;
12625         if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
12626                 inode->i_flags |= S_APPEND;
12627         else
12628 @@ -708,6 +717,12 @@ xfs_fs_remount(
12629         int                     error;
12630  
12631         error = bhv_vfs_parseargs(vfsp, options, args, 1);
12632 +       if ((args->flags2 & XFSMNT2_TAGGED) &&
12633 +               !(sb->s_flags & MS_TAGGED)) {
12634 +               printk("XFS: %s: tagging not permitted on remount.\n",
12635 +                       sb->s_id);
12636 +               error = EINVAL;
12637 +       }
12638         if (!error)
12639                 error = bhv_vfs_mntupdate(vfsp, flags, args);
12640         kmem_free(args, sizeof(*args));
12641 @@ -731,36 +746,40 @@ xfs_fs_show_options(
12642  
12643  STATIC int
12644  xfs_fs_quotasync(
12645 -       struct super_block      *sb,
12646 +       struct dqhash           *hash,
12647         int                     type)
12648  {
12649 +       struct super_block      *sb = hash->dqh_sb;
12650         return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL);
12651  }
12652  
12653  STATIC int
12654  xfs_fs_getxstate(
12655 -       struct super_block      *sb,
12656 +       struct dqhash           *hash,
12657         struct fs_quota_stat    *fqs)
12658  {
12659 +       struct super_block      *sb = hash->dqh_sb;
12660         return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
12661  }
12662  
12663  STATIC int
12664  xfs_fs_setxstate(
12665 -       struct super_block      *sb,
12666 +       struct dqhash           *hash,
12667         unsigned int            flags,
12668         int                     op)
12669  {
12670 +       struct super_block      *sb = hash->dqh_sb;
12671         return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags);
12672  }
12673  
12674  STATIC int
12675  xfs_fs_getxquota(
12676 -       struct super_block      *sb,
12677 +       struct dqhash           *hash,
12678         int                     type,
12679         qid_t                   id,
12680         struct fs_disk_quota    *fdq)
12681  {
12682 +       struct super_block      *sb = hash->dqh_sb;
12683         return -bhv_vfs_quotactl(vfs_from_sb(sb),
12684                                  (type == USRQUOTA) ? Q_XGETQUOTA :
12685                                   ((type == GRPQUOTA) ? Q_XGETGQUOTA :
12686 @@ -769,11 +788,12 @@ xfs_fs_getxquota(
12687  
12688  STATIC int
12689  xfs_fs_setxquota(
12690 -       struct super_block      *sb,
12691 +       struct dqhash           *hash,
12692         int                     type,
12693         qid_t                   id,
12694         struct fs_disk_quota    *fdq)
12695  {
12696 +       struct super_block      *sb = hash->dqh_sb;
12697         return -bhv_vfs_quotactl(vfs_from_sb(sb),
12698                                  (type == USRQUOTA) ? Q_XSETQLIM :
12699                                   ((type == GRPQUOTA) ? Q_XSETGQLIM :
12700 @@ -803,6 +823,9 @@ xfs_fs_fill_super(
12701         sb_min_blocksize(sb, BBSIZE);
12702         sb->s_export_op = &xfs_export_operations;
12703         sb->s_qcop = &xfs_quotactl_operations;
12704 +#ifdef CONFIG_QUOTACTL
12705 +       sb->s_dqh->dqh_qcop = &xfs_quotactl_operations;
12706 +#endif
12707         sb->s_op = &xfs_super_operations;
12708  
12709         error = bhv_vfs_mount(vfsp, args, NULL);
12710 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_sysctl.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_sysctl.c
12711 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_sysctl.c        2006-09-20 16:58:39 +0200
12712 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_sysctl.c      2006-11-08 04:57:40 +0100
12713 @@ -57,79 +57,79 @@ xfs_stats_clear_proc_handler(
12714  STATIC ctl_table xfs_table[] = {
12715         {XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown.val,
12716         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12717 -       &sysctl_intvec, NULL,
12718 +       NULL, &sysctl_intvec, NULL,
12719         &xfs_params.restrict_chown.min, &xfs_params.restrict_chown.max},
12720  
12721         {XFS_SGID_INHERIT, "irix_sgid_inherit", &xfs_params.sgid_inherit.val,
12722         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12723 -       &sysctl_intvec, NULL,
12724 +       NULL, &sysctl_intvec, NULL,
12725         &xfs_params.sgid_inherit.min, &xfs_params.sgid_inherit.max},
12726  
12727         {XFS_SYMLINK_MODE, "irix_symlink_mode", &xfs_params.symlink_mode.val,
12728         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12729 -       &sysctl_intvec, NULL,
12730 +       NULL, &sysctl_intvec, NULL,
12731         &xfs_params.symlink_mode.min, &xfs_params.symlink_mode.max},
12732  
12733         {XFS_PANIC_MASK, "panic_mask", &xfs_params.panic_mask.val,
12734         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12735 -       &sysctl_intvec, NULL,
12736 +       NULL, &sysctl_intvec, NULL,
12737         &xfs_params.panic_mask.min, &xfs_params.panic_mask.max},
12738  
12739         {XFS_ERRLEVEL, "error_level", &xfs_params.error_level.val,
12740         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12741 -       &sysctl_intvec, NULL,
12742 +       NULL, &sysctl_intvec, NULL,
12743         &xfs_params.error_level.min, &xfs_params.error_level.max},
12744  
12745         {XFS_SYNCD_TIMER, "xfssyncd_centisecs", &xfs_params.syncd_timer.val,
12746         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12747 -       &sysctl_intvec, NULL,
12748 +       NULL, &sysctl_intvec, NULL,
12749         &xfs_params.syncd_timer.min, &xfs_params.syncd_timer.max},
12750  
12751         {XFS_INHERIT_SYNC, "inherit_sync", &xfs_params.inherit_sync.val,
12752         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12753 -       &sysctl_intvec, NULL,
12754 +       NULL, &sysctl_intvec, NULL,
12755         &xfs_params.inherit_sync.min, &xfs_params.inherit_sync.max},
12756  
12757         {XFS_INHERIT_NODUMP, "inherit_nodump", &xfs_params.inherit_nodump.val,
12758         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12759 -       &sysctl_intvec, NULL,
12760 +       NULL, &sysctl_intvec, NULL,
12761         &xfs_params.inherit_nodump.min, &xfs_params.inherit_nodump.max},
12762  
12763         {XFS_INHERIT_NOATIME, "inherit_noatime", &xfs_params.inherit_noatim.val,
12764         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12765 -       &sysctl_intvec, NULL,
12766 +       NULL, &sysctl_intvec, NULL,
12767         &xfs_params.inherit_noatim.min, &xfs_params.inherit_noatim.max},
12768  
12769         {XFS_BUF_TIMER, "xfsbufd_centisecs", &xfs_params.xfs_buf_timer.val,
12770         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12771 -       &sysctl_intvec, NULL,
12772 +       NULL, &sysctl_intvec, NULL,
12773         &xfs_params.xfs_buf_timer.min, &xfs_params.xfs_buf_timer.max},
12774  
12775         {XFS_BUF_AGE, "age_buffer_centisecs", &xfs_params.xfs_buf_age.val,
12776         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12777 -       &sysctl_intvec, NULL,
12778 +       NULL, &sysctl_intvec, NULL,
12779         &xfs_params.xfs_buf_age.min, &xfs_params.xfs_buf_age.max},
12780  
12781         {XFS_INHERIT_NOSYM, "inherit_nosymlinks", &xfs_params.inherit_nosym.val,
12782         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12783 -       &sysctl_intvec, NULL,
12784 +       NULL, &sysctl_intvec, NULL,
12785         &xfs_params.inherit_nosym.min, &xfs_params.inherit_nosym.max},
12786  
12787         {XFS_ROTORSTEP, "rotorstep", &xfs_params.rotorstep.val,
12788         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12789 -       &sysctl_intvec, NULL,
12790 +       NULL, &sysctl_intvec, NULL,
12791         &xfs_params.rotorstep.min, &xfs_params.rotorstep.max},
12792  
12793         {XFS_INHERIT_NODFRG, "inherit_nodefrag", &xfs_params.inherit_nodfrg.val,
12794         sizeof(int), 0644, NULL, &proc_dointvec_minmax,
12795 -       &sysctl_intvec, NULL,
12796 +       NULL, &sysctl_intvec, NULL,
12797         &xfs_params.inherit_nodfrg.min, &xfs_params.inherit_nodfrg.max},
12798  
12799         /* please keep this the last entry */
12800  #ifdef CONFIG_PROC_FS
12801         {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
12802         sizeof(int), 0644, NULL, &xfs_stats_clear_proc_handler,
12803 -       &sysctl_intvec, NULL,
12804 +       NULL, &sysctl_intvec, NULL,
12805         &xfs_params.stats_clear.min, &xfs_params.stats_clear.max},
12806  #endif /* CONFIG_PROC_FS */
12807  
12808 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_vnode.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_vnode.c
12809 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_vnode.c 2006-11-30 21:19:29 +0100
12810 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_vnode.c       2006-11-08 04:57:46 +0100
12811 @@ -119,6 +119,7 @@ vn_revalidate_core(
12812         inode->i_nlink      = vap->va_nlink;
12813         inode->i_uid        = vap->va_uid;
12814         inode->i_gid        = vap->va_gid;
12815 +       inode->i_tag        = vap->va_tag;
12816         inode->i_blocks     = vap->va_nblocks;
12817         inode->i_mtime      = vap->va_mtime;
12818         inode->i_ctime      = vap->va_ctime;
12819 @@ -126,6 +127,14 @@ vn_revalidate_core(
12820                 inode->i_flags |= S_IMMUTABLE;
12821         else
12822                 inode->i_flags &= ~S_IMMUTABLE;
12823 +       if (vap->va_xflags & XFS_XFLAG_IUNLINK)
12824 +               inode->i_flags |= S_IUNLINK;
12825 +       else
12826 +               inode->i_flags &= ~S_IUNLINK;
12827 +       if (vap->va_xflags & XFS_XFLAG_BARRIER)
12828 +               inode->i_flags |= S_BARRIER;
12829 +       else
12830 +               inode->i_flags &= ~S_BARRIER;
12831         if (vap->va_xflags & XFS_XFLAG_APPEND)
12832                 inode->i_flags |= S_APPEND;
12833         else
12834 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/linux-2.6/xfs_vnode.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_vnode.h
12835 --- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_vnode.h 2006-11-30 21:19:29 +0100
12836 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/linux-2.6/xfs_vnode.h       2006-11-08 04:57:46 +0100
12837 @@ -350,6 +350,7 @@ typedef struct bhv_vattr {
12838         xfs_nlink_t     va_nlink;       /* number of references to file */
12839         uid_t           va_uid;         /* owner user id */
12840         gid_t           va_gid;         /* owner group id */
12841 +       tag_t           va_tag;         /* owner group id */
12842         xfs_ino_t       va_nodeid;      /* file id */
12843         xfs_off_t       va_size;        /* file size in bytes */
12844         u_long          va_blocksize;   /* blocksize preferred for i/o */
12845 @@ -398,13 +399,15 @@ typedef struct bhv_vattr {
12846  #define XFS_AT_PROJID          0x04000000
12847  #define XFS_AT_SIZE_NOPERM     0x08000000
12848  #define XFS_AT_GENCOUNT                0x10000000
12849 +#define XFS_AT_TAG             0x20000000
12850  
12851  #define XFS_AT_ALL     (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
12852                 XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
12853                 XFS_AT_ATIME|XFS_AT_MTIME|XFS_AT_CTIME|XFS_AT_RDEV|\
12854                 XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|XFS_AT_MAC|\
12855                 XFS_AT_ACL|XFS_AT_CAP|XFS_AT_INF|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|\
12856 -               XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT)
12857 +               XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_PROJID|XFS_AT_GENCOUNT\
12858 +               XFS_AT_TAG)
12859  
12860  #define XFS_AT_STAT    (XFS_AT_TYPE|XFS_AT_MODE|XFS_AT_UID|XFS_AT_GID|\
12861                 XFS_AT_FSID|XFS_AT_NODEID|XFS_AT_NLINK|XFS_AT_SIZE|\
12862 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/quota/xfs_qm_syscalls.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/quota/xfs_qm_syscalls.c
12863 --- linux-2.6.19.1/fs/xfs/quota/xfs_qm_syscalls.c       2006-09-20 16:58:40 +0200
12864 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/quota/xfs_qm_syscalls.c     2006-11-30 18:53:18 +0100
12865 @@ -17,6 +17,7 @@
12866   */
12867  
12868  #include <linux/capability.h>
12869 +#include <linux/vs_context.h>
12870  
12871  #include "xfs.h"
12872  #include "xfs_fs.h"
12873 @@ -213,7 +214,7 @@ xfs_qm_scall_quotaoff(
12874         xfs_qoff_logitem_t      *qoffstart;
12875         int                     nculprits;
12876  
12877 -       if (!force && !capable(CAP_SYS_ADMIN))
12878 +       if (!force && !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12879                 return XFS_ERROR(EPERM);
12880         /*
12881          * No file system can have quotas enabled on disk but not in core.
12882 @@ -382,7 +383,7 @@ xfs_qm_scall_trunc_qfiles(
12883         int             error;
12884         xfs_inode_t     *qip;
12885  
12886 -       if (!capable(CAP_SYS_ADMIN))
12887 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12888                 return XFS_ERROR(EPERM);
12889         error = 0;
12890         if (!XFS_SB_VERSION_HASQUOTA(&mp->m_sb) || flags == 0) {
12891 @@ -427,7 +428,7 @@ xfs_qm_scall_quotaon(
12892         uint            accflags;
12893         __int64_t       sbflags;
12894  
12895 -       if (!capable(CAP_SYS_ADMIN))
12896 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12897                 return XFS_ERROR(EPERM);
12898  
12899         flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
12900 @@ -598,7 +599,7 @@ xfs_qm_scall_setqlim(
12901         int                     error;
12902         xfs_qcnt_t              hard, soft;
12903  
12904 -       if (!capable(CAP_SYS_ADMIN))
12905 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
12906                 return XFS_ERROR(EPERM);
12907  
12908         if ((newlim->d_fieldmask &
12909 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_clnt.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_clnt.h
12910 --- linux-2.6.19.1/fs/xfs/xfs_clnt.h    2006-06-18 04:54:50 +0200
12911 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_clnt.h  2006-11-08 04:57:46 +0100
12912 @@ -99,5 +99,7 @@ struct xfs_mount_args {
12913   */
12914  #define XFSMNT2_COMPAT_IOSIZE  0x00000001      /* don't report large preferred
12915                                                  * I/O size in stat(2) */
12916 +#define XFSMNT2_TAGGED         0x80000000      /* context tagging */
12917 +
12918  
12919  #endif /* __XFS_CLNT_H__ */
12920 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_dinode.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_dinode.h
12921 --- linux-2.6.19.1/fs/xfs/xfs_dinode.h  2006-09-20 16:58:40 +0200
12922 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_dinode.h        2006-11-08 04:57:46 +0100
12923 @@ -53,7 +53,8 @@ typedef struct xfs_dinode_core
12924         __uint32_t      di_gid;         /* owner's group id */
12925         __uint32_t      di_nlink;       /* number of links to file */
12926         __uint16_t      di_projid;      /* owner's project id */
12927 -       __uint8_t       di_pad[8];      /* unused, zeroed space */
12928 +       __uint16_t      di_tag;         /* context tagging */
12929 +       __uint8_t       di_pad[6];      /* unused, zeroed space */
12930         __uint16_t      di_flushiter;   /* incremented on flush */
12931         xfs_timestamp_t di_atime;       /* time last accessed */
12932         xfs_timestamp_t di_mtime;       /* time last modified */
12933 @@ -257,6 +258,9 @@ typedef enum xfs_dinode_fmt
12934  #define XFS_DIFLAG_EXTSIZE_BIT      11 /* inode extent size allocator hint */
12935  #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */
12936  #define XFS_DIFLAG_NODEFRAG_BIT     13 /* do not reorganize/defragment */
12937 +#define XFS_DIFLAG_BARRIER_BIT 14      /* chroot() barrier */
12938 +#define XFS_DIFLAG_IUNLINK_BIT 15      /* immutable unlink */
12939 +
12940  #define XFS_DIFLAG_REALTIME      (1 << XFS_DIFLAG_REALTIME_BIT)
12941  #define XFS_DIFLAG_PREALLOC      (1 << XFS_DIFLAG_PREALLOC_BIT)
12942  #define XFS_DIFLAG_NEWRTBM       (1 << XFS_DIFLAG_NEWRTBM_BIT)
12943 @@ -271,12 +275,15 @@ typedef enum xfs_dinode_fmt
12944  #define XFS_DIFLAG_EXTSIZE       (1 << XFS_DIFLAG_EXTSIZE_BIT)
12945  #define XFS_DIFLAG_EXTSZINHERIT  (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
12946  #define XFS_DIFLAG_NODEFRAG      (1 << XFS_DIFLAG_NODEFRAG_BIT)
12947 +#define XFS_DIFLAG_BARRIER      (1 << XFS_DIFLAG_BARRIER_BIT)
12948 +#define XFS_DIFLAG_IUNLINK      (1 << XFS_DIFLAG_IUNLINK_BIT)
12949  
12950  #define XFS_DIFLAG_ANY \
12951         (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
12952          XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
12953          XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
12954          XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
12955 -        XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG)
12956 +        XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_BARRIER | \
12957 +        XFS_DIFLAG_IUNLINK)
12958  
12959  #endif /* __XFS_DINODE_H__ */
12960 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_fs.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_fs.h
12961 --- linux-2.6.19.1/fs/xfs/xfs_fs.h      2006-11-30 21:19:29 +0100
12962 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_fs.h    2006-11-08 04:57:46 +0100
12963 @@ -66,6 +66,8 @@ struct fsxattr {
12964  #define XFS_XFLAG_EXTSIZE      0x00000800      /* extent size allocator hint */
12965  #define XFS_XFLAG_EXTSZINHERIT 0x00001000      /* inherit inode extent size */
12966  #define XFS_XFLAG_NODEFRAG     0x00002000      /* do not defragment */
12967 +#define XFS_XFLAG_BARRIER      0x00004000      /* chroot() barrier */
12968 +#define XFS_XFLAG_IUNLINK      0x00008000      /* immutable unlink */
12969  #define XFS_XFLAG_HASATTR      0x80000000      /* no DIFLAG for this   */
12970  
12971  /*
12972 @@ -294,7 +296,8 @@ typedef struct xfs_bstat {
12973         __s32           bs_extents;     /* number of extents            */
12974         __u32           bs_gen;         /* generation count             */
12975         __u16           bs_projid;      /* project id                   */
12976 -       unsigned char   bs_pad[14];     /* pad space, unused            */
12977 +       __u16           bs_tag;         /* context tagging              */
12978 +       unsigned char   bs_pad[12];     /* pad space, unused            */
12979         __u32           bs_dmevmask;    /* DMIG event mask              */
12980         __u16           bs_dmstate;     /* DMIG state info              */
12981         __u16           bs_aextents;    /* attribute number of extents  */
12982 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_inode.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_inode.c
12983 --- linux-2.6.19.1/fs/xfs/xfs_inode.c   2006-11-30 21:19:29 +0100
12984 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_inode.c 2006-11-30 20:55:45 +0100
12985 @@ -50,6 +50,7 @@
12986  #include "xfs_mac.h"
12987  #include "xfs_acl.h"
12988  
12989 +#include <linux/vs_tag.h>
12990  
12991  kmem_zone_t *xfs_ifork_zone;
12992  kmem_zone_t *xfs_inode_zone;
12993 @@ -736,20 +737,35 @@ xfs_xlate_dinode_core(
12994         xfs_dinode_core_t       *buf_core = (xfs_dinode_core_t *)buf;
12995         xfs_dinode_core_t       *mem_core = (xfs_dinode_core_t *)dip;
12996         xfs_arch_t              arch = ARCH_CONVERT;
12997 +       uint32_t                uid = 0, gid = 0;
12998 +       uint16_t                tag = 0;
12999  
13000         ASSERT(dir);
13001  
13002 +       if (dir < 0) {
13003 +               tag = mem_core->di_tag;
13004 +               /* FIXME: supposed to use superblock flag */
13005 +               uid = TAGINO_UID(1, mem_core->di_uid, tag);
13006 +               gid = TAGINO_GID(1, mem_core->di_gid, tag);
13007 +               tag = TAGINO_TAG(1, tag);
13008 +       }
13009 +
13010         INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch);
13011         INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch);
13012         INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch);
13013         INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch);
13014         INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch);
13015 -       INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch);
13016 -       INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch);
13017 +       INT_XLATE(buf_core->di_uid, uid, dir, arch);
13018 +       INT_XLATE(buf_core->di_gid, gid, dir, arch);
13019 +       INT_XLATE(buf_core->di_tag, tag, dir, arch);
13020         INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch);
13021         INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch);
13022  
13023         if (dir > 0) {
13024 +               /* FIXME: supposed to use superblock flag */
13025 +               mem_core->di_uid = INOTAG_UID(1, uid, gid);
13026 +               mem_core->di_gid = INOTAG_GID(1, uid, gid);
13027 +               mem_core->di_tag = INOTAG_TAG(1, uid, gid, tag);
13028                 memcpy(mem_core->di_pad, buf_core->di_pad,
13029                         sizeof(buf_core->di_pad));
13030         } else {
13031 @@ -797,6 +813,10 @@ _xfs_dic2xflags(
13032                         flags |= XFS_XFLAG_PREALLOC;
13033                 if (di_flags & XFS_DIFLAG_IMMUTABLE)
13034                         flags |= XFS_XFLAG_IMMUTABLE;
13035 +               if (di_flags & XFS_DIFLAG_IUNLINK)
13036 +                       flags |= XFS_XFLAG_IUNLINK;
13037 +               if (di_flags & XFS_DIFLAG_BARRIER)
13038 +                       flags |= XFS_XFLAG_BARRIER;
13039                 if (di_flags & XFS_DIFLAG_APPEND)
13040                         flags |= XFS_XFLAG_APPEND;
13041                 if (di_flags & XFS_DIFLAG_SYNC)
13042 @@ -1128,6 +1148,7 @@ xfs_ialloc(
13043         ASSERT(ip->i_d.di_nlink == nlink);
13044         ip->i_d.di_uid = current_fsuid(cr);
13045         ip->i_d.di_gid = current_fsgid(cr);
13046 +       ip->i_d.di_tag = current_fstag(cr, vp);
13047         ip->i_d.di_projid = prid;
13048         memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
13049  
13050 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_itable.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_itable.c
13051 --- linux-2.6.19.1/fs/xfs/xfs_itable.c  2006-11-30 21:19:29 +0100
13052 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_itable.c        2006-11-08 04:57:46 +0100
13053 @@ -89,6 +89,7 @@ xfs_bulkstat_one_iget(
13054         buf->bs_mode = dic->di_mode;
13055         buf->bs_uid = dic->di_uid;
13056         buf->bs_gid = dic->di_gid;
13057 +       buf->bs_tag = dic->di_tag;
13058         buf->bs_size = dic->di_size;
13059         vn_atime_to_bstime(vp, &buf->bs_atime);
13060         buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
13061 @@ -163,6 +164,7 @@ xfs_bulkstat_one_dinode(
13062         buf->bs_mode = INT_GET(dic->di_mode, ARCH_CONVERT);
13063         buf->bs_uid = INT_GET(dic->di_uid, ARCH_CONVERT);
13064         buf->bs_gid = INT_GET(dic->di_gid, ARCH_CONVERT);
13065 +       buf->bs_tag = INT_GET(dic->di_tag, ARCH_CONVERT);
13066         buf->bs_size = INT_GET(dic->di_size, ARCH_CONVERT);
13067         buf->bs_atime.tv_sec = INT_GET(dic->di_atime.t_sec, ARCH_CONVERT);
13068         buf->bs_atime.tv_nsec = INT_GET(dic->di_atime.t_nsec, ARCH_CONVERT);
13069 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_mount.h linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_mount.h
13070 --- linux-2.6.19.1/fs/xfs/xfs_mount.h   2006-11-30 21:19:29 +0100
13071 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_mount.h 2006-11-08 04:57:46 +0100
13072 @@ -460,6 +460,7 @@ typedef struct xfs_mount {
13073  #define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23)    /* don't use per-cpu superblock
13074                                                    counters */
13075  
13076 +#define XFS_MOUNT_TAGGED       (1ULL << 31)    /* context tagging */
13077  
13078  /*
13079   * Default minimum read and write sizes.
13080 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_vfsops.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_vfsops.c
13081 --- linux-2.6.19.1/fs/xfs/xfs_vfsops.c  2006-11-30 21:19:29 +0100
13082 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_vfsops.c        2006-11-08 04:57:47 +0100
13083 @@ -300,6 +300,8 @@ xfs_start_flags(
13084  
13085         if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE)
13086                 mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
13087 +       if (ap->flags2 & XFSMNT2_TAGGED)
13088 +               mp->m_flags |= XFS_MOUNT_TAGGED;
13089  
13090         /*
13091          * no recovery flag requires a read-only mount
13092 @@ -394,6 +396,8 @@ xfs_finish_flags(
13093                         return XFS_ERROR(EINVAL);
13094         }
13095  
13096 +       if (ap->flags2 & XFSMNT2_TAGGED)
13097 +               vfs->vfs_super->s_flags |= MS_TAGGED;
13098         return 0;
13099  }
13100  
13101 @@ -1645,6 +1649,9 @@ xfs_vget(
13102                                          * in stat(). */
13103  #define MNTOPT_ATTR2   "attr2"         /* do use attr2 attribute format */
13104  #define MNTOPT_NOATTR2 "noattr2"       /* do not use attr2 attribute format */
13105 +#define MNTOPT_TAGXID  "tagxid"        /* context tagging for inodes */
13106 +#define MNTOPT_TAGGED  "tag"           /* context tagging for inodes */
13107 +#define MNTOPT_NOTAGTAG        "notag"         /* do not use context tagging */
13108  
13109  STATIC unsigned long
13110  suffix_strtoul(char *s, char **endp, unsigned int base)
13111 @@ -1831,6 +1838,19 @@ xfs_parseargs(
13112                         args->flags |= XFSMNT_ATTR2;
13113                 } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
13114                         args->flags &= ~XFSMNT_ATTR2;
13115 +#ifndef CONFIG_TAGGING_NONE
13116 +               } else if (!strcmp(this_char, MNTOPT_TAGGED)) {
13117 +                       args->flags2 |= XFSMNT2_TAGGED;
13118 +               } else if (!strcmp(this_char, MNTOPT_NOTAGTAG)) {
13119 +                       args->flags2 &= ~XFSMNT2_TAGGED;
13120 +               } else if (!strcmp(this_char, MNTOPT_TAGXID)) {
13121 +                       args->flags2 |= XFSMNT2_TAGGED;
13122 +#endif
13123 +#ifdef CONFIG_PROPAGATE
13124 +               } else if (!strcmp(this_char, MNTOPT_TAGGED)) {
13125 +                       /* use value */
13126 +                       args->flags2 |= XFSMNT2_TAGGED;
13127 +#endif
13128                 } else if (!strcmp(this_char, "osyncisdsync")) {
13129                         /* no-op, this is now the default */
13130                         cmn_err(CE_WARN,
13131 diff -NurpP --minimal linux-2.6.19.1/fs/xfs/xfs_vnodeops.c linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_vnodeops.c
13132 --- linux-2.6.19.1/fs/xfs/xfs_vnodeops.c        2006-11-30 21:19:29 +0100
13133 +++ linux-2.6.19.1-vs2.3.0.6/fs/xfs/xfs_vnodeops.c      2006-11-20 21:12:32 +0100
13134 @@ -160,6 +160,7 @@ xfs_getattr(
13135         vap->va_mode = ip->i_d.di_mode;
13136         vap->va_uid = ip->i_d.di_uid;
13137         vap->va_gid = ip->i_d.di_gid;
13138 +       vap->va_tag = ip->i_d.di_tag;
13139         vap->va_projid = ip->i_d.di_projid;
13140  
13141         /*
13142 @@ -260,6 +261,7 @@ xfs_setattr(
13143         uint                    commit_flags=0;
13144         uid_t                   uid=0, iuid=0;
13145         gid_t                   gid=0, igid=0;
13146 +       tag_t                   tag=0, itag=0;
13147         int                     timeflags = 0;
13148         bhv_vnode_t             *vp;
13149         xfs_prid_t              projid=0, iprojid=0;
13150 @@ -316,6 +318,7 @@ xfs_setattr(
13151             (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
13152                 uint    qflags = 0;
13153  
13154 +               /* FIXME: handle tagging? */
13155                 if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
13156                         uid = vap->va_uid;
13157                         qflags |= XFS_QMOPT_UQUOTA;
13158 @@ -395,6 +398,8 @@ xfs_setattr(
13159         if (mask &
13160             (XFS_AT_MODE|XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_UID|
13161              XFS_AT_GID|XFS_AT_PROJID)) {
13162 +               /* FIXME: handle tagging? */
13163 +
13164                 /*
13165                  * CAP_FOWNER overrides the following restrictions:
13166                  *
13167 @@ -443,7 +448,7 @@ xfs_setattr(
13168          * and can change the group id only to a group of which he
13169          * or she is a member.
13170          */
13171 -       if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
13172 +       if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|XFS_AT_PROJID)) {
13173                 /*
13174                  * These IDs could have changed since we last looked at them.
13175                  * But, we're assured that if the ownership did change
13176 @@ -451,10 +456,12 @@ xfs_setattr(
13177                  * would have changed also.
13178                  */
13179                 iuid = ip->i_d.di_uid;
13180 -               iprojid = ip->i_d.di_projid;
13181                 igid = ip->i_d.di_gid;
13182 -               gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
13183 +               itag = ip->i_d.di_tag;
13184 +               iprojid = ip->i_d.di_projid;
13185                 uid = (mask & XFS_AT_UID) ? vap->va_uid : iuid;
13186 +               gid = (mask & XFS_AT_GID) ? vap->va_gid : igid;
13187 +               tag = (mask & XFS_AT_TAG) ? vap->va_tag : itag;
13188                 projid = (mask & XFS_AT_PROJID) ? (xfs_prid_t)vap->va_projid :
13189                          iprojid;
13190  
13191 @@ -482,6 +489,7 @@ xfs_setattr(
13192                 if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
13193                     (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
13194                     (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
13195 +                       /* FIXME: handle tagging? */
13196                         ASSERT(tp);
13197                         code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
13198                                                 capable(CAP_FOWNER) ?
13199 @@ -707,7 +715,7 @@ xfs_setattr(
13200          * and can change the group id only to a group of which he
13201          * or she is a member.
13202          */
13203 -       if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID)) {
13204 +       if (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_TAG|XFS_AT_PROJID)) {
13205                 /*
13206                  * CAP_FSETID overrides the following restrictions:
13207                  *
13208 @@ -723,6 +731,12 @@ xfs_setattr(
13209                  * Change the ownerships and register quota modifications
13210                  * in the transaction.
13211                  */
13212 +               if (itag != tag) {
13213 +                       if (XFS_IS_GQUOTA_ON(mp)) {
13214 +                               /* FIXME: handle tag quota? */
13215 +                       }
13216 +                       ip->i_d.di_tag = tag;
13217 +               }
13218                 if (iuid != uid) {
13219                         if (XFS_IS_UQUOTA_ON(mp)) {
13220                                 ASSERT(mask & XFS_AT_UID);
13221 @@ -803,6 +817,10 @@ xfs_setattr(
13222                         di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
13223                         if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
13224                                 di_flags |= XFS_DIFLAG_IMMUTABLE;
13225 +                       if (vap->va_xflags & XFS_XFLAG_IUNLINK)
13226 +                               di_flags |= XFS_DIFLAG_IUNLINK;
13227 +                       if (vap->va_xflags & XFS_XFLAG_BARRIER)
13228 +                               di_flags |= XFS_DIFLAG_BARRIER;
13229                         if (vap->va_xflags & XFS_XFLAG_APPEND)
13230                                 di_flags |= XFS_DIFLAG_APPEND;
13231                         if (vap->va_xflags & XFS_XFLAG_SYNC)
13232 diff -NurpP --minimal linux-2.6.19.1/include/asm-arm/tlb.h linux-2.6.19.1-vs2.3.0.6/include/asm-arm/tlb.h
13233 --- linux-2.6.19.1/include/asm-arm/tlb.h        2006-06-18 04:54:58 +0200
13234 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-arm/tlb.h      2006-11-08 04:57:40 +0100
13235 @@ -28,6 +28,7 @@
13236  #else /* !CONFIG_MMU */
13237  
13238  #include <asm/pgalloc.h>
13239 +#include <linux/vs_memory.h>
13240  
13241  /*
13242   * TLB handling.  This allows us to remove pages from the page
13243 diff -NurpP --minimal linux-2.6.19.1/include/asm-arm26/tlb.h linux-2.6.19.1-vs2.3.0.6/include/asm-arm26/tlb.h
13244 --- linux-2.6.19.1/include/asm-arm26/tlb.h      2006-01-03 17:30:02 +0100
13245 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-arm26/tlb.h    2006-11-08 04:57:40 +0100
13246 @@ -3,6 +3,7 @@
13247  
13248  #include <asm/pgalloc.h>
13249  #include <asm/tlbflush.h>
13250 +#include <linux/vs_memory.h>
13251  
13252  /*
13253   * TLB handling.  This allows us to remove pages from the page
13254 diff -NurpP --minimal linux-2.6.19.1/include/asm-arm26/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-arm26/unistd.h
13255 --- linux-2.6.19.1/include/asm-arm26/unistd.h   2006-11-30 21:19:31 +0100
13256 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-arm26/unistd.h 2006-11-08 04:57:41 +0100
13257 @@ -302,6 +302,8 @@
13258  #define __NR_mq_getsetattr             (__NR_SYSCALL_BASE+279)
13259  #define __NR_waitid                    (__NR_SYSCALL_BASE+280)
13260  
13261 +#define __NR_vserver                   (__NR_SYSCALL_BASE+313)
13262 +
13263  /*
13264   * The following SWIs are ARM private. FIXME - make appropriate for arm26
13265   */
13266 diff -NurpP --minimal linux-2.6.19.1/include/asm-generic/tlb.h linux-2.6.19.1-vs2.3.0.6/include/asm-generic/tlb.h
13267 --- linux-2.6.19.1/include/asm-generic/tlb.h    2006-11-30 21:19:31 +0100
13268 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-generic/tlb.h  2006-11-08 04:57:40 +0100
13269 @@ -14,6 +14,7 @@
13270  #define _ASM_GENERIC__TLB_H
13271  
13272  #include <linux/swap.h>
13273 +#include <linux/vs_memory.h>
13274  #include <asm/pgalloc.h>
13275  #include <asm/tlbflush.h>
13276  
13277 diff -NurpP --minimal linux-2.6.19.1/include/asm-i386/elf.h linux-2.6.19.1-vs2.3.0.6/include/asm-i386/elf.h
13278 --- linux-2.6.19.1/include/asm-i386/elf.h       2006-11-30 21:19:31 +0100
13279 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-i386/elf.h     2006-11-08 04:57:53 +0100
13280 @@ -75,7 +75,7 @@ typedef struct user_fxsr_struct elf_fpxr
13281     the loader.  We need to make sure that it is out of the way of the program
13282     that it will "exec", and that there is sufficient room for the brk.  */
13283  
13284 -#define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
13285 +#define ELF_ET_DYN_BASE                ((TASK_UNMAPPED_BASE) * 2)
13286  
13287  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
13288     now struct_user_regs, they are different) */
13289 diff -NurpP --minimal linux-2.6.19.1/include/asm-ia64/tlb.h linux-2.6.19.1-vs2.3.0.6/include/asm-ia64/tlb.h
13290 --- linux-2.6.19.1/include/asm-ia64/tlb.h       2006-09-20 16:58:40 +0200
13291 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-ia64/tlb.h     2006-11-08 04:57:40 +0100
13292 @@ -40,6 +40,7 @@
13293  #include <linux/mm.h>
13294  #include <linux/pagemap.h>
13295  #include <linux/swap.h>
13296 +#include <linux/vs_memory.h>
13297  
13298  #include <asm/pgalloc.h>
13299  #include <asm/processor.h>
13300 diff -NurpP --minimal linux-2.6.19.1/include/asm-powerpc/systbl.h linux-2.6.19.1-vs2.3.0.6/include/asm-powerpc/systbl.h
13301 --- linux-2.6.19.1/include/asm-powerpc/systbl.h 2006-11-30 21:19:33 +0100
13302 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-powerpc/systbl.h       2006-11-20 21:12:32 +0100
13303 @@ -260,7 +260,7 @@ COMPAT_SYS_SPU(fstatfs64)
13304  SYSX(sys_ni_syscall, ppc_fadvise64_64, ppc_fadvise64_64)
13305  PPC_SYS_SPU(rtas)
13306  OLDSYS(debug_setcontext)
13307 -SYSCALL(ni_syscall)
13308 +SYSX(sys_vserver, sys32_vserver, sys_vserver)
13309  COMPAT_SYS(migrate_pages)
13310  COMPAT_SYS(mbind)
13311  COMPAT_SYS(get_mempolicy)
13312 diff -NurpP --minimal linux-2.6.19.1/include/asm-powerpc/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-powerpc/unistd.h
13313 --- linux-2.6.19.1/include/asm-powerpc/unistd.h 2006-11-30 21:19:33 +0100
13314 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-powerpc/unistd.h       2006-11-20 21:12:32 +0100
13315 @@ -275,7 +275,7 @@
13316  #endif
13317  #define __NR_rtas              255
13318  #define __NR_sys_debug_setcontext 256
13319 -/* Number 257 is reserved for vserver */
13320 +#define __NR_vserver           257
13321  #define __NR_migrate_pages     258
13322  #define __NR_mbind             259
13323  #define __NR_get_mempolicy     260
13324 diff -NurpP --minimal linux-2.6.19.1/include/asm-s390/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-s390/unistd.h
13325 --- linux-2.6.19.1/include/asm-s390/unistd.h    2006-11-30 21:19:33 +0100
13326 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-s390/unistd.h  2006-11-08 04:57:41 +0100
13327 @@ -202,7 +202,7 @@
13328  #define __NR_clock_gettime     (__NR_timer_create+6)
13329  #define __NR_clock_getres      (__NR_timer_create+7)
13330  #define __NR_clock_nanosleep   (__NR_timer_create+8)
13331 -/* Number 263 is reserved for vserver */
13332 +#define __NR_vserver           263
13333  #define __NR_statfs64          265
13334  #define __NR_fstatfs64         266
13335  #define __NR_remap_file_pages  267
13336 diff -NurpP --minimal linux-2.6.19.1/include/asm-sparc/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-sparc/unistd.h
13337 --- linux-2.6.19.1/include/asm-sparc/unistd.h   2006-11-30 21:19:34 +0100
13338 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-sparc/unistd.h 2006-11-08 21:52:09 +0100
13339 @@ -283,7 +283,7 @@
13340  #define __NR_timer_getoverrun  264
13341  #define __NR_timer_delete      265
13342  #define __NR_timer_create      266
13343 -/* #define __NR_vserver                267 Reserved for VSERVER */
13344 +#define __NR_vserver           267
13345  #define __NR_io_setup          268
13346  #define __NR_io_destroy                269
13347  #define __NR_io_submit         270
13348 diff -NurpP --minimal linux-2.6.19.1/include/asm-sparc64/tlb.h linux-2.6.19.1-vs2.3.0.6/include/asm-sparc64/tlb.h
13349 --- linux-2.6.19.1/include/asm-sparc64/tlb.h    2006-09-20 16:58:43 +0200
13350 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-sparc64/tlb.h  2006-11-08 04:57:40 +0100
13351 @@ -2,6 +2,7 @@
13352  #define _SPARC64_TLB_H
13353  
13354  #include <linux/swap.h>
13355 +#include <linux/vs_memory.h>
13356  #include <asm/pgalloc.h>
13357  #include <asm/tlbflush.h>
13358  #include <asm/mmu_context.h>
13359 diff -NurpP --minimal linux-2.6.19.1/include/asm-sparc64/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-sparc64/unistd.h
13360 --- linux-2.6.19.1/include/asm-sparc64/unistd.h 2006-11-30 21:19:35 +0100
13361 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-sparc64/unistd.h       2006-11-08 21:52:09 +0100
13362 @@ -285,7 +285,7 @@
13363  #define __NR_timer_getoverrun  264
13364  #define __NR_timer_delete      265
13365  #define __NR_timer_create      266
13366 -/* #define __NR_vserver                267 Reserved for VSERVER */
13367 +#define __NR_vserver           267
13368  #define __NR_io_setup          268
13369  #define __NR_io_destroy                269
13370  #define __NR_io_submit         270
13371 diff -NurpP --minimal linux-2.6.19.1/include/asm-x86_64/unistd.h linux-2.6.19.1-vs2.3.0.6/include/asm-x86_64/unistd.h
13372 --- linux-2.6.19.1/include/asm-x86_64/unistd.h  2006-11-30 21:19:37 +0100
13373 +++ linux-2.6.19.1-vs2.3.0.6/include/asm-x86_64/unistd.h        2006-11-08 04:57:41 +0100
13374 @@ -532,7 +532,7 @@ __SYSCALL(__NR_tgkill, sys_tgkill)
13375  #define __NR_utimes            235
13376  __SYSCALL(__NR_utimes, sys_utimes)
13377  #define __NR_vserver           236
13378 -__SYSCALL(__NR_vserver, sys_ni_syscall)
13379 +__SYSCALL(__NR_vserver, sys_vserver)
13380  #define __NR_mbind             237
13381  __SYSCALL(__NR_mbind, sys_mbind)
13382  #define __NR_set_mempolicy     238
13383 diff -NurpP --minimal linux-2.6.19.1/include/linux/Kbuild linux-2.6.19.1-vs2.3.0.6/include/linux/Kbuild
13384 --- linux-2.6.19.1/include/linux/Kbuild 2006-11-30 21:19:37 +0100
13385 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/Kbuild       2006-11-08 04:57:49 +0100
13386 @@ -345,3 +345,6 @@ unifdef-y += xfrm.h
13387  unifdef-y += zftape.h
13388  
13389  objhdr-y += version.h
13390 +
13391 +header-y += vserver/
13392 +
13393 diff -NurpP --minimal linux-2.6.19.1/include/linux/capability.h linux-2.6.19.1-vs2.3.0.6/include/linux/capability.h
13394 --- linux-2.6.19.1/include/linux/capability.h   2006-06-18 04:55:15 +0200
13395 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/capability.h 2006-11-08 04:57:40 +0100
13396 @@ -235,6 +235,7 @@ typedef __u32 kernel_cap_t;
13397     arbitrary SCSI commands */
13398  /* Allow setting encryption key on loopback filesystem */
13399  /* Allow setting zone reclaim policy */
13400 +/* Allow the selection of a security context */
13401  
13402  #define CAP_SYS_ADMIN        21
13403  
13404 @@ -288,6 +289,11 @@ typedef __u32 kernel_cap_t;
13405  
13406  #define CAP_AUDIT_CONTROL    30
13407  
13408 +/* Allow context manipulations */
13409 +/* Allow changing context info on files */
13410 +
13411 +#define CAP_CONTEXT         31
13412 +
13413  #ifdef __KERNEL__
13414  /* 
13415   * Bounding set
13416 diff -NurpP --minimal linux-2.6.19.1/include/linux/devpts_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/devpts_fs.h
13417 --- linux-2.6.19.1/include/linux/devpts_fs.h    2004-08-14 12:55:59 +0200
13418 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/devpts_fs.h  2006-11-08 04:57:53 +0100
13419 @@ -30,5 +30,7 @@ static inline void devpts_pty_kill(int n
13420  
13421  #endif
13422  
13423 +#define DEVPTS_SUPER_MAGIC     0x00001cd1
13424 +
13425  
13426  #endif /* _LINUX_DEVPTS_FS_H */
13427 diff -NurpP --minimal linux-2.6.19.1/include/linux/ext2_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/ext2_fs.h
13428 --- linux-2.6.19.1/include/linux/ext2_fs.h      2006-11-30 21:19:37 +0100
13429 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/ext2_fs.h    2006-11-08 04:57:46 +0100
13430 @@ -188,6 +188,8 @@ struct ext2_group_desc
13431  #define EXT2_NOTAIL_FL                 FS_NOTAIL_FL    /* file tail should not be merged */
13432  #define EXT2_DIRSYNC_FL                        FS_DIRSYNC_FL   /* dirsync behaviour (directories only) */
13433  #define EXT2_TOPDIR_FL                 FS_TOPDIR_FL    /* Top of directory hierarchies*/
13434 +#define EXT2_BARRIER_FL                        FS_BARRIER_FL   /* Barrier for chroot() */
13435 +#define EXT2_IUNLINK_FL                        FS_IUNLINK_FL   /* Immutable unlink */
13436  #define EXT2_RESERVED_FL               FS_RESERVED_FL  /* reserved for ext2 lib */
13437  
13438  #define EXT2_FL_USER_VISIBLE           FS_FL_USER_VISIBLE      /* User visible flags */
13439 @@ -244,7 +246,7 @@ struct ext2_inode {
13440                 struct {
13441                         __u8    l_i_frag;       /* Fragment number */
13442                         __u8    l_i_fsize;      /* Fragment size */
13443 -                       __u16   i_pad1;
13444 +                       __u16   l_i_tag;        /* Context Tag */
13445                         __le16  l_i_uid_high;   /* these 2 fields    */
13446                         __le16  l_i_gid_high;   /* were reserved2[0] */
13447                         __u32   l_i_reserved2;
13448 @@ -276,6 +278,7 @@ struct ext2_inode {
13449  #define i_gid_low      i_gid
13450  #define i_uid_high     osd2.linux2.l_i_uid_high
13451  #define i_gid_high     osd2.linux2.l_i_gid_high
13452 +#define i_raw_tag      osd2.linux2.l_i_tag
13453  #define i_reserved2    osd2.linux2.l_i_reserved2
13454  #endif
13455  
13456 @@ -317,8 +320,9 @@ struct ext2_inode {
13457  #define EXT2_MOUNT_XATTR_USER          0x004000  /* Extended user attributes */
13458  #define EXT2_MOUNT_POSIX_ACL           0x008000  /* POSIX Access Control Lists */
13459  #define EXT2_MOUNT_XIP                 0x010000  /* Execute in place */
13460 -#define EXT2_MOUNT_USRQUOTA            0x020000 /* user quota */
13461 -#define EXT2_MOUNT_GRPQUOTA            0x040000 /* group quota */
13462 +#define EXT2_MOUNT_USRQUOTA            0x020000  /* user quota */
13463 +#define EXT2_MOUNT_GRPQUOTA            0x040000  /* group quota */
13464 +#define EXT2_MOUNT_TAGGED              (1<<24)   /* Enable Context Tags */
13465  
13466  
13467  #define clear_opt(o, opt)              o &= ~EXT2_MOUNT_##opt
13468 diff -NurpP --minimal linux-2.6.19.1/include/linux/ext3_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/ext3_fs.h
13469 --- linux-2.6.19.1/include/linux/ext3_fs.h      2006-11-30 21:19:37 +0100
13470 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/ext3_fs.h    2006-12-17 04:14:42 +0100
13471 @@ -177,6 +177,8 @@ struct ext3_group_desc
13472  #define EXT3_NOTAIL_FL                 0x00008000 /* file tail should not be merged */
13473  #define EXT3_DIRSYNC_FL                        0x00010000 /* dirsync behaviour (directories only) */
13474  #define EXT3_TOPDIR_FL                 0x00020000 /* Top of directory hierarchies*/
13475 +#define EXT3_BARRIER_FL                        0x04000000 /* Barrier for chroot() */
13476 +#define EXT3_IUNLINK_FL                        0x08000000 /* Immutable unlink */
13477  #define EXT3_RESERVED_FL               0x80000000 /* reserved for ext3 lib */
13478  
13479  #define EXT3_FL_USER_VISIBLE           0x0003DFFF /* User visible flags */
13480 @@ -296,7 +298,7 @@ struct ext3_inode {
13481                 struct {
13482                         __u8    l_i_frag;       /* Fragment number */
13483                         __u8    l_i_fsize;      /* Fragment size */
13484 -                       __u16   i_pad1;
13485 +                       __u16   l_i_tag;        /* Context Tag */
13486                         __le16  l_i_uid_high;   /* these 2 fields    */
13487                         __le16  l_i_gid_high;   /* were reserved2[0] */
13488                         __u32   l_i_reserved2;
13489 @@ -330,6 +332,7 @@ struct ext3_inode {
13490  #define i_gid_low      i_gid
13491  #define i_uid_high     osd2.linux2.l_i_uid_high
13492  #define i_gid_high     osd2.linux2.l_i_gid_high
13493 +#define i_raw_tag      osd2.linux2.l_i_tag
13494  #define i_reserved2    osd2.linux2.l_i_reserved2
13495  
13496  #elif defined(__GNU__)
13497 @@ -384,6 +387,7 @@ struct ext3_inode {
13498  #define EXT3_MOUNT_QUOTA               0x80000 /* Some quota option set */
13499  #define EXT3_MOUNT_USRQUOTA            0x100000 /* "old" user quota */
13500  #define EXT3_MOUNT_GRPQUOTA            0x200000 /* "old" group quota */
13501 +#define EXT3_MOUNT_TAGGED              (1<<24) /* Enable Context Tags */
13502  
13503  /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
13504  #ifndef _LINUX_EXT2_FS_H
13505 @@ -812,6 +816,7 @@ struct buffer_head * ext3_bread (handle_
13506  int ext3_get_blocks_handle(handle_t *handle, struct inode *inode,
13507         sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
13508         int create, int extend_disksize);
13509 +extern int ext3_sync_flags(struct inode *inode);
13510  
13511  extern void ext3_read_inode (struct inode *);
13512  extern int  ext3_write_inode (struct inode *, int);
13513 diff -NurpP --minimal linux-2.6.19.1/include/linux/ext3_jbd.h linux-2.6.19.1-vs2.3.0.6/include/linux/ext3_jbd.h
13514 --- linux-2.6.19.1/include/linux/ext3_jbd.h     2006-11-30 21:19:37 +0100
13515 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/ext3_jbd.h   2006-11-08 04:57:51 +0100
13516 @@ -77,10 +77,10 @@
13517  #define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0)
13518  /* Amount of blocks needed for quota insert/delete - we do some block writes
13519   * but inode, sb and group updates are done only once */
13520 -#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\
13521 -               (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0)
13522 -#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\
13523 -               (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0)
13524 +#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? \
13525 +       (DQUOT_INIT_ALLOC*(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0)
13526 +#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? \
13527 +       (DQUOT_DEL_ALLOC*(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0)
13528  #else
13529  #define EXT3_QUOTA_TRANS_BLOCKS(sb) 0
13530  #define EXT3_QUOTA_INIT_BLOCKS(sb) 0
13531 diff -NurpP --minimal linux-2.6.19.1/include/linux/ext4_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/ext4_fs.h
13532 --- linux-2.6.19.1/include/linux/ext4_fs.h      2006-11-30 21:19:37 +0100
13533 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/ext4_fs.h    2006-12-17 04:16:26 +0100
13534 @@ -189,8 +189,10 @@ struct ext4_group_desc
13535  #define EXT4_NOTAIL_FL                 0x00008000 /* file tail should not be merged */
13536  #define EXT4_DIRSYNC_FL                        0x00010000 /* dirsync behaviour (directories only) */
13537  #define EXT4_TOPDIR_FL                 0x00020000 /* Top of directory hierarchies*/
13538 -#define EXT4_RESERVED_FL               0x80000000 /* reserved for ext4 lib */
13539  #define EXT4_EXTENTS_FL                        0x00080000 /* Inode uses extents */
13540 +#define EXT4_BARRIER_FL                        0x04000000 /* Barrier for chroot() */
13541 +#define EXT4_IUNLINK_FL                        0x08000000 /* Immutable unlink */
13542 +#define EXT4_RESERVED_FL               0x80000000 /* reserved for ext4 lib */
13543  
13544  #define EXT4_FL_USER_VISIBLE           0x000BDFFF /* User visible flags */
13545  #define EXT4_FL_USER_MODIFIABLE                0x000380FF /* User modifiable flags */
13546 @@ -312,7 +314,8 @@ struct ext4_inode {
13547                         __le16  l_i_file_acl_high;
13548                         __le16  l_i_uid_high;   /* these 2 fields    */
13549                         __le16  l_i_gid_high;   /* were reserved2[0] */
13550 -                       __u32   l_i_reserved2;
13551 +                       __u16   l_i_tag;        /* Context Tag */
13552 +                       __u16   l_i_reserved2;
13553                 } linux2;
13554                 struct {
13555                         __u8    h_i_frag;       /* Fragment number */
13556 @@ -344,6 +347,7 @@ struct ext4_inode {
13557  #define i_gid_low      i_gid
13558  #define i_uid_high     osd2.linux2.l_i_uid_high
13559  #define i_gid_high     osd2.linux2.l_i_gid_high
13560 +#define i_raw_tag      osd2.linux2.l_i_tag
13561  #define i_reserved2    osd2.linux2.l_i_reserved2
13562  
13563  #elif defined(__GNU__)
13564 @@ -400,6 +404,7 @@ struct ext4_inode {
13565  #define EXT4_MOUNT_USRQUOTA            0x100000 /* "old" user quota */
13566  #define EXT4_MOUNT_GRPQUOTA            0x200000 /* "old" group quota */
13567  #define EXT4_MOUNT_EXTENTS             0x400000 /* Extents support */
13568 +#define EXT4_MOUNT_TAGGED              (1<<24) /* Enable Context Tags */
13569  
13570  /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */
13571  #ifndef _LINUX_EXT2_FS_H
13572 @@ -843,6 +848,7 @@ struct buffer_head * ext4_bread (handle_
13573  int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
13574         sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
13575         int create, int extend_disksize);
13576 +extern int ext4_sync_flags(struct inode *inode);
13577  
13578  extern void ext4_read_inode (struct inode *);
13579  extern int  ext4_write_inode (struct inode *, int);
13580 diff -NurpP --minimal linux-2.6.19.1/include/linux/fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/fs.h
13581 --- linux-2.6.19.1/include/linux/fs.h   2006-11-30 21:19:38 +0100
13582 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/fs.h 2006-12-17 04:16:36 +0100
13583 @@ -120,6 +120,8 @@ extern int dir_notify_enable;
13584  #define MS_PRIVATE     (1<<18) /* change to private */
13585  #define MS_SLAVE       (1<<19) /* change to slave */
13586  #define MS_SHARED      (1<<20) /* change to shared */
13587 +#define MS_TAGGED      (1<<24) /* use generic inode tagging */
13588 +#define MS_TAGID       (1<<25) /* use specific tag for this mount */
13589  #define MS_ACTIVE      (1<<30)
13590  #define MS_NOUSER      (1<<31)
13591  
13592 @@ -146,6 +148,8 @@ extern int dir_notify_enable;
13593  #define S_NOCMTIME     128     /* Do not update file c/mtime */
13594  #define S_SWAPFILE     256     /* Do not truncate: swapon got its bmaps */
13595  #define S_PRIVATE      512     /* Inode is fs-internal */
13596 +#define S_BARRIER      1024    /* Barrier for chroot() */
13597 +#define S_IUNLINK      2048    /* Immutable unlink */
13598  
13599  /*
13600   * Note that nosuid etc flags are inode-specific: setting some file-system
13601 @@ -162,23 +166,35 @@ extern int dir_notify_enable;
13602   */
13603  #define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))
13604  
13605 -#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
13606 +#define IS_RDONLY(inode)       __IS_FLG(inode, MS_RDONLY)
13607  #define IS_SYNC(inode)         (__IS_FLG(inode, MS_SYNCHRONOUS) || \
13608                                         ((inode)->i_flags & S_SYNC))
13609  #define IS_DIRSYNC(inode)      (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \
13610                                         ((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
13611  #define IS_MANDLOCK(inode)     __IS_FLG(inode, MS_MANDLOCK)
13612 +#define IS_TAGGED(inode)       __IS_FLG(inode, MS_TAGGED)
13613  
13614  #define IS_NOQUOTA(inode)      ((inode)->i_flags & S_NOQUOTA)
13615  #define IS_APPEND(inode)       ((inode)->i_flags & S_APPEND)
13616  #define IS_IMMUTABLE(inode)    ((inode)->i_flags & S_IMMUTABLE)
13617 +#define IS_IUNLINK(inode)      ((inode)->i_flags & S_IUNLINK)
13618 +#define IS_IXORUNLINK(inode)   ((IS_IUNLINK(inode) ? S_IMMUTABLE : 0) ^ IS_IMMUTABLE(inode))
13619  #define IS_POSIXACL(inode)     __IS_FLG(inode, MS_POSIXACL)
13620  
13621 +#define IS_BARRIER(inode)      (S_ISDIR((inode)->i_mode) && ((inode)->i_flags & S_BARRIER))
13622  #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
13623  #define IS_NOCMTIME(inode)     ((inode)->i_flags & S_NOCMTIME)
13624  #define IS_SWAPFILE(inode)     ((inode)->i_flags & S_SWAPFILE)
13625  #define IS_PRIVATE(inode)      ((inode)->i_flags & S_PRIVATE)
13626  
13627 +#ifdef CONFIG_VSERVER_COWBL
13628 +#  define IS_COW(inode)                (IS_IUNLINK(inode) && IS_IMMUTABLE(inode))
13629 +#  define IS_COW_LINK(inode)   (S_ISREG((inode)->i_mode) && ((inode)->i_nlink > 1))
13630 +#else
13631 +#  define IS_COW(inode)                (0)
13632 +#  define IS_COW_LINK(inode)   (0)
13633 +#endif
13634 +
13635  /* the read-only stuff doesn't really belong here, but any other place is
13636     probably as bad and I don't want to create yet another include file. */
13637  
13638 @@ -252,12 +268,13 @@ extern int dir_notify_enable;
13639  #define FS_TOPDIR_FL                   0x00020000 /* Top of directory hierarchies*/
13640  #define FS_EXTENT_FL                   0x00080000 /* Extents */
13641  #define FS_DIRECTIO_FL                 0x00100000 /* Use direct i/o */
13642 +#define FS_BARRIER_FL                  0x04000000 /* Barrier for chroot() */
13643 +#define FS_IUNLINK_FL                  0x08000000 /* Immutable unlink */
13644  #define FS_RESERVED_FL                 0x80000000 /* reserved for ext2 lib */
13645  
13646  #define FS_FL_USER_VISIBLE             0x0003DFFF /* User visible flags */
13647  #define FS_FL_USER_MODIFIABLE          0x000380FF /* User modifiable flags */
13648  
13649 -
13650  #define SYNC_FILE_RANGE_WAIT_BEFORE    1
13651  #define SYNC_FILE_RANGE_WRITE          2
13652  #define SYNC_FILE_RANGE_WAIT_AFTER     4
13653 @@ -322,6 +339,7 @@ typedef void (dio_iodone_t)(struct kiocb
13654  #define ATTR_KILL_SUID 2048
13655  #define ATTR_KILL_SGID 4096
13656  #define ATTR_FILE      8192
13657 +#define ATTR_TAG       16384
13658  
13659  /*
13660   * This is the Inode Attributes structure, used for notify_change().  It
13661 @@ -337,6 +355,7 @@ struct iattr {
13662         umode_t         ia_mode;
13663         uid_t           ia_uid;
13664         gid_t           ia_gid;
13665 +       tag_t           ia_tag;
13666         loff_t          ia_size;
13667         struct timespec ia_atime;
13668         struct timespec ia_mtime;
13669 @@ -350,6 +369,9 @@ struct iattr {
13670         struct file     *ia_file;
13671  };
13672  
13673 +#define ATTR_FLAG_BARRIER      512     /* Barrier for chroot() */
13674 +#define ATTR_FLAG_IUNLINK      1024    /* Immutable unlink */
13675 +
13676  /*
13677   * Includes for diskquotas.
13678   */
13679 @@ -547,6 +569,7 @@ struct inode {
13680         unsigned int            i_nlink;
13681         uid_t                   i_uid;
13682         gid_t                   i_gid;
13683 +       tag_t                   i_tag;
13684         dev_t                   i_rdev;
13685         loff_t                  i_size;
13686         struct timespec         i_atime;
13687 @@ -565,6 +588,9 @@ struct inode {
13688         struct file_lock        *i_flock;
13689         struct address_space    *i_mapping;
13690         struct address_space    i_data;
13691 +#ifdef CONFIG_QUOTACTL
13692 +       struct dqhash           *i_dqh;
13693 +#endif
13694  #ifdef CONFIG_QUOTA
13695         struct dquot            *i_dquot[MAXQUOTAS];
13696  #endif
13697 @@ -735,6 +761,7 @@ struct file {
13698         loff_t                  f_pos;
13699         struct fown_struct      f_owner;
13700         unsigned int            f_uid, f_gid;
13701 +       xid_t                   f_xid;
13702         struct file_ra_state    f_ra;
13703  
13704         unsigned long           f_version;
13705 @@ -817,6 +844,7 @@ struct file_lock {
13706         unsigned char fl_type;
13707         loff_t fl_start;
13708         loff_t fl_end;
13709 +       xid_t fl_xid;
13710  
13711         struct fasync_struct *  fl_fasync; /* for lease break notifications */
13712         unsigned long fl_break_time;    /* for nonblocking lease breaks */
13713 @@ -918,7 +946,7 @@ struct super_block {
13714         unsigned long long      s_maxbytes;     /* Max file size */
13715         struct file_system_type *s_type;
13716         struct super_operations *s_op;
13717 -       struct dquot_operations *dq_op;
13718 +       struct dquot_operations *s_qop;
13719         struct quotactl_ops     *s_qcop;
13720         struct export_operations *s_export_op;
13721         unsigned long           s_flags;
13722 @@ -943,7 +971,7 @@ struct super_block {
13723  
13724         struct block_device     *s_bdev;
13725         struct list_head        s_instances;
13726 -       struct quota_info       s_dquot;        /* Diskquota specific options */
13727 +       struct dqhash           *s_dqh;         /* Diskquota hash */
13728  
13729         int                     s_frozen;
13730         wait_queue_head_t       s_wait_unfrozen;
13731 @@ -1013,12 +1041,12 @@ static inline void unlock_super(struct s
13732   */
13733  extern int vfs_permission(struct nameidata *, int);
13734  extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
13735 -extern int vfs_mkdir(struct inode *, struct dentry *, int);
13736 -extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
13737 -extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
13738 -extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
13739 -extern int vfs_rmdir(struct inode *, struct dentry *);
13740 -extern int vfs_unlink(struct inode *, struct dentry *);
13741 +extern int vfs_mkdir(struct inode *, struct dentry *, int, struct nameidata *);
13742 +extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t, struct nameidata *);
13743 +extern int vfs_symlink(struct inode *, struct dentry *, const char *, int, struct nameidata *);
13744 +extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct nameidata *);
13745 +extern int vfs_rmdir(struct inode *, struct dentry *, struct nameidata *);
13746 +extern int vfs_unlink(struct inode *, struct dentry *, struct nameidata *);
13747  extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
13748  
13749  /*
13750 @@ -1158,6 +1186,7 @@ struct inode_operations {
13751         ssize_t (*listxattr) (struct dentry *, char *, size_t);
13752         int (*removexattr) (struct dentry *, const char *);
13753         void (*truncate_range)(struct inode *, loff_t, loff_t);
13754 +       int (*sync_flags) (struct inode *);
13755  };
13756  
13757  struct seq_file;
13758 @@ -1173,6 +1202,7 @@ extern ssize_t vfs_readv(struct file *, 
13759                 unsigned long, loff_t *);
13760  extern ssize_t vfs_writev(struct file *, const struct iovec __user *,
13761                 unsigned long, loff_t *);
13762 +ssize_t vfs_sendfile(struct file *, struct file *, loff_t *, size_t, loff_t);
13763  
13764  /*
13765   * NOTE: write_inode, delete_inode, clear_inode, put_inode can be called
13766 @@ -1202,8 +1232,8 @@ struct super_operations {
13767         int (*show_options)(struct seq_file *, struct vfsmount *);
13768         int (*show_stats)(struct seq_file *, struct vfsmount *);
13769  #ifdef CONFIG_QUOTA
13770 -       ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
13771 -       ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
13772 +       ssize_t (*quota_read)(struct dqhash *, int, char *, size_t, loff_t);
13773 +       ssize_t (*quota_write)(struct dqhash *, int, const char *, size_t, loff_t);
13774  #endif
13775  };
13776  
13777 @@ -1715,7 +1745,7 @@ extern struct inode *new_inode(struct su
13778  extern int __remove_suid(struct dentry *, int);
13779  extern int should_remove_suid(struct dentry *);
13780  extern int remove_suid(struct dentry *);
13781 -extern void remove_dquot_ref(struct super_block *, int, struct list_head *);
13782 +extern void remove_dquot_ref(struct dqhash *, int, struct list_head *);
13783  
13784  extern void __insert_inode_hash(struct inode *, unsigned long hashval);
13785  extern void remove_inode_hash(struct inode *);
13786 @@ -1751,6 +1781,7 @@ extern ssize_t generic_file_buffered_wri
13787  extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
13788  extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
13789  extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
13790 +extern ssize_t generic_file_sendpage(struct file *, struct page *, int, size_t, loff_t *, int);
13791  extern void do_generic_mapping_read(struct address_space *mapping,
13792                                     struct file_ra_state *, struct file *,
13793                                     loff_t *, read_descriptor_t *, read_actor_t);
13794 @@ -1884,6 +1915,7 @@ extern int dcache_dir_open(struct inode 
13795  extern int dcache_dir_close(struct inode *, struct file *);
13796  extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
13797  extern int dcache_readdir(struct file *, void *, filldir_t);
13798 +extern int dcache_readdir_filter(struct file *, void *, filldir_t, int (*)(struct dentry *));
13799  extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
13800  extern int simple_statfs(struct dentry *, struct kstatfs *);
13801  extern int simple_link(struct dentry *, struct inode *, struct dentry *);
13802 diff -NurpP --minimal linux-2.6.19.1/include/linux/init_task.h linux-2.6.19.1-vs2.3.0.6/include/linux/init_task.h
13803 --- linux-2.6.19.1/include/linux/init_task.h    2006-11-30 21:19:38 +0100
13804 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/init_task.h  2006-11-08 04:57:40 +0100
13805 @@ -140,6 +140,10 @@ extern struct group_info init_groups;
13806         .pi_lock        = SPIN_LOCK_UNLOCKED,                           \
13807         INIT_TRACE_IRQFLAGS                                             \
13808         INIT_LOCKDEP                                                    \
13809 +       .xid            = 0,                                            \
13810 +       .vx_info        = NULL,                                         \
13811 +       .nid            = 0,                                            \
13812 +       .nx_info        = NULL,                                         \
13813  }
13814  
13815  
13816 diff -NurpP --minimal linux-2.6.19.1/include/linux/ipc.h linux-2.6.19.1-vs2.3.0.6/include/linux/ipc.h
13817 --- linux-2.6.19.1/include/linux/ipc.h  2006-11-30 21:19:38 +0100
13818 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/ipc.h        2006-11-08 20:20:37 +0100
13819 @@ -63,6 +63,7 @@ struct kern_ipc_perm
13820         key_t           key;
13821         uid_t           uid;
13822         gid_t           gid;
13823 +       xid_t           xid;
13824         uid_t           cuid;
13825         gid_t           cgid;
13826         mode_t          mode; 
13827 diff -NurpP --minimal linux-2.6.19.1/include/linux/jffs2.h linux-2.6.19.1-vs2.3.0.6/include/linux/jffs2.h
13828 --- linux-2.6.19.1/include/linux/jffs2.h        2006-11-30 21:19:38 +0100
13829 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/jffs2.h      2006-12-16 10:19:32 +0100
13830 @@ -82,12 +82,16 @@
13831  //#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
13832  
13833  
13834 -#define JFFS2_INO_FLAG_PREREAD   1     /* Do read_inode() for this one at
13835 +#define JFFS2_INO_FLAG_PREREAD   0x01  /* Do read_inode() for this one at
13836                                            mount time, don't wait for it to
13837                                            happen later */
13838 -#define JFFS2_INO_FLAG_USERCOMPR  2    /* User has requested a specific
13839 +#define JFFS2_INO_FLAG_USERCOMPR  0x02 /* User has requested a specific
13840                                            compression type */
13841  
13842 +#define JFFS2_INO_FLAG_IMMUTABLE  0x10 /* immutable node */
13843 +#define JFFS2_INO_FLAG_IUNLINK   0x20  /* immutable unlink */
13844 +#define JFFS2_INO_FLAG_BARRIER   0x40  /* barrier */
13845 +
13846  
13847  /* These can go once we've made sure we've caught all uses without
13848     byteswapping */
13849 diff -NurpP --minimal linux-2.6.19.1/include/linux/loop.h linux-2.6.19.1-vs2.3.0.6/include/linux/loop.h
13850 --- linux-2.6.19.1/include/linux/loop.h 2006-11-30 21:19:38 +0100
13851 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/loop.h       2006-11-08 04:57:52 +0100
13852 @@ -45,6 +45,7 @@ struct loop_device {
13853         struct loop_func_table *lo_encryption;
13854         __u32           lo_init[2];
13855         uid_t           lo_key_owner;   /* Who set the key */
13856 +       xid_t           lo_xid;
13857         int             (*ioctl)(struct loop_device *, int cmd, 
13858                                  unsigned long arg); 
13859  
13860 diff -NurpP --minimal linux-2.6.19.1/include/linux/major.h linux-2.6.19.1-vs2.3.0.6/include/linux/major.h
13861 --- linux-2.6.19.1/include/linux/major.h        2006-06-18 04:55:19 +0200
13862 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/major.h      2006-11-08 04:57:51 +0100
13863 @@ -15,6 +15,7 @@
13864  #define HD_MAJOR               IDE0_MAJOR
13865  #define PTY_SLAVE_MAJOR                3
13866  #define TTY_MAJOR              4
13867 +#define VROOT_MAJOR            4
13868  #define TTYAUX_MAJOR           5
13869  #define LP_MAJOR               6
13870  #define VCS_MAJOR              7
13871 diff -NurpP --minimal linux-2.6.19.1/include/linux/mount.h linux-2.6.19.1-vs2.3.0.6/include/linux/mount.h
13872 --- linux-2.6.19.1/include/linux/mount.h        2006-09-20 16:58:44 +0200
13873 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/mount.h      2006-11-08 04:57:52 +0100
13874 @@ -27,12 +27,16 @@ struct namespace;
13875  #define MNT_NOEXEC     0x04
13876  #define MNT_NOATIME    0x08
13877  #define MNT_NODIRATIME 0x10
13878 +#define MNT_RDONLY     0x20
13879 +
13880 +#define MNT_IS_RDONLY(m)       ((m) && ((m)->mnt_flags & MNT_RDONLY))
13881  
13882  #define MNT_SHRINKABLE 0x100
13883  
13884  #define MNT_SHARED     0x1000  /* if the vfsmount is a shared mount */
13885  #define MNT_UNBINDABLE 0x2000  /* if the vfsmount is a unbindable mount */
13886  #define MNT_PNODE_MASK 0x3000  /* propogation flag mask */
13887 +#define MNT_TAGID              0x8000
13888  
13889  struct vfsmount {
13890         struct list_head mnt_hash;
13891 @@ -54,6 +58,7 @@ struct vfsmount {
13892         struct vfsmount *mnt_master;    /* slave is on master->mnt_slave_list */
13893         struct namespace *mnt_namespace; /* containing namespace */
13894         int mnt_pinned;
13895 +       tag_t mnt_tag;                  /* tagging used for vfsmount */
13896  };
13897  
13898  static inline struct vfsmount *mntget(struct vfsmount *mnt)
13899 diff -NurpP --minimal linux-2.6.19.1/include/linux/net.h linux-2.6.19.1-vs2.3.0.6/include/linux/net.h
13900 --- linux-2.6.19.1/include/linux/net.h  2006-11-30 21:19:38 +0100
13901 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/net.h        2006-11-08 04:57:42 +0100
13902 @@ -63,6 +63,7 @@ typedef enum {
13903  #define SOCK_NOSPACE           2
13904  #define SOCK_PASSCRED          3
13905  #define SOCK_PASSSEC           4
13906 +#define SOCK_USER_SOCKET       5
13907  
13908  #ifndef ARCH_HAS_SOCKET_TYPES
13909  /**
13910 diff -NurpP --minimal linux-2.6.19.1/include/linux/nfs_mount.h linux-2.6.19.1-vs2.3.0.6/include/linux/nfs_mount.h
13911 --- linux-2.6.19.1/include/linux/nfs_mount.h    2005-08-29 22:25:42 +0200
13912 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/nfs_mount.h  2006-11-08 04:57:47 +0100
13913 @@ -61,6 +61,7 @@ struct nfs_mount_data {
13914  #define NFS_MOUNT_NOACL                0x0800  /* 4 */
13915  #define NFS_MOUNT_STRICTLOCK   0x1000  /* reserved for NFSv4 */
13916  #define NFS_MOUNT_SECFLAVOUR   0x2000  /* 5 */
13917 +#define NFS_MOUNT_TAGGED       0x8000  /* context tagging */
13918  #define NFS_MOUNT_FLAGMASK     0xFFFF
13919  
13920  #endif
13921 diff -NurpP --minimal linux-2.6.19.1/include/linux/nsproxy.h linux-2.6.19.1-vs2.3.0.6/include/linux/nsproxy.h
13922 --- linux-2.6.19.1/include/linux/nsproxy.h      2006-11-30 21:19:39 +0100
13923 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/nsproxy.h    2006-11-30 20:55:45 +0100
13924 @@ -51,4 +51,10 @@ static inline void exit_task_namespaces(
13925                 put_nsproxy(ns);
13926         }
13927  }
13928 +
13929 +static inline void get_nsproxy(struct nsproxy *ns)
13930 +{
13931 +       atomic_inc(&ns->count);
13932 +}
13933 +
13934  #endif
13935 diff -NurpP --minimal linux-2.6.19.1/include/linux/percpu.h linux-2.6.19.1-vs2.3.0.6/include/linux/percpu.h
13936 --- linux-2.6.19.1/include/linux/percpu.h       2006-11-30 21:19:39 +0100
13937 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/percpu.h     2006-11-08 04:57:40 +0100
13938 @@ -11,7 +11,7 @@
13939  
13940  /* Enough to cover all DEFINE_PER_CPUs in kernel, including modules. */
13941  #ifndef PERCPU_ENOUGH_ROOM
13942 -#define PERCPU_ENOUGH_ROOM 32768
13943 +#define PERCPU_ENOUGH_ROOM 65536
13944  #endif
13945  
13946  /*
13947 diff -NurpP --minimal linux-2.6.19.1/include/linux/pid.h linux-2.6.19.1-vs2.3.0.6/include/linux/pid.h
13948 --- linux-2.6.19.1/include/linux/pid.h  2006-11-30 21:19:39 +0100
13949 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/pid.h        2006-11-08 04:57:52 +0100
13950 @@ -8,7 +8,8 @@ enum pid_type
13951         PIDTYPE_PID,
13952         PIDTYPE_PGID,
13953         PIDTYPE_SID,
13954 -       PIDTYPE_MAX
13955 +       PIDTYPE_MAX,
13956 +       PIDTYPE_REALPID
13957  };
13958  
13959  /*
13960 diff -NurpP --minimal linux-2.6.19.1/include/linux/proc_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/proc_fs.h
13961 --- linux-2.6.19.1/include/linux/proc_fs.h      2006-11-30 21:19:39 +0100
13962 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/proc_fs.h    2006-12-09 03:46:57 +0100
13963 @@ -54,6 +54,7 @@ struct proc_dir_entry {
13964         nlink_t nlink;
13965         uid_t uid;
13966         gid_t gid;
13967 +       int vx_flags;
13968         loff_t size;
13969         struct inode_operations * proc_iops;
13970         const struct file_operations * proc_fops;
13971 @@ -247,10 +248,14 @@ extern void kclist_add(struct kcore_list
13972  union proc_op {
13973         int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
13974         int (*proc_read)(struct task_struct *task, char *page);
13975 +       int (*proc_vs_read)(char *page);
13976 +       int (*proc_vxi_read)(struct vx_info *vxi, char *page);
13977 +       int (*proc_nxi_read)(struct nx_info *nxi, char *page);
13978  };
13979  
13980  struct proc_inode {
13981         struct pid *pid;
13982 +       int vx_flags;
13983         int fd;
13984         union proc_op op;
13985         struct proc_dir_entry *pde;
13986 diff -NurpP --minimal linux-2.6.19.1/include/linux/quota.h linux-2.6.19.1-vs2.3.0.6/include/linux/quota.h
13987 --- linux-2.6.19.1/include/linux/quota.h        2006-09-20 16:58:44 +0200
13988 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/quota.h      2006-11-08 04:57:51 +0100
13989 @@ -55,6 +55,13 @@ extern spinlock_t dq_data_lock;
13990  #define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10))
13991  #define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
13992  
13993 +/* are NULL dqhash ptrs valid? */
13994 +#ifdef HANDLE_DQHASH_NULL
13995 +#define        dqhash_valid(hash)      ((hash) != NULL)
13996 +#else
13997 +#define        dqhash_valid(hash)      (0 == 0)
13998 +#endif
13999 +
14000  #define MAXQUOTAS 2
14001  #define USRQUOTA  0            /* element used for user quotas */
14002  #define GRPQUOTA  1            /* element used for group quotas */
14003 @@ -176,19 +183,20 @@ struct mem_dqinfo {
14004         } u;
14005  };
14006  
14007 -struct super_block;
14008 +struct dqhash;
14009  
14010  #define DQF_MASK 0xffff                /* Mask for format specific flags */
14011  #define DQF_INFO_DIRTY_B 16
14012  #define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B) /* Is info dirty? */
14013  
14014 -extern void mark_info_dirty(struct super_block *sb, int type);
14015 +extern void mark_info_dirty(struct dqhash *hash, int type);
14016 +
14017  #define info_dirty(info) test_bit(DQF_INFO_DIRTY_B, &(info)->dqi_flags)
14018  #define info_any_dquot_dirty(info) (!list_empty(&(info)->dqi_dirty_list))
14019  #define info_any_dirty(info) (info_dirty(info) || info_any_dquot_dirty(info))
14020  
14021 -#define sb_dqopt(sb) (&(sb)->s_dquot)
14022 -#define sb_dqinfo(sb, type) (sb_dqopt(sb)->info+(type))
14023 +#define dqh_dqopt(hash) (&(hash)->dqh_dqopt)
14024 +#define dqh_dqinfo(hash, type) (dqh_dqopt(hash)->info+(type))
14025  
14026  struct dqstats {
14027         int lookups;
14028 @@ -218,7 +226,7 @@ struct dquot {
14029         struct mutex dq_lock;           /* dquot IO lock */
14030         atomic_t dq_count;              /* Use count */
14031         wait_queue_head_t dq_wait_unused;       /* Wait queue for dquot to become unused */
14032 -       struct super_block *dq_sb;      /* superblock this applies to */
14033 +       struct dqhash *dq_dqh;          /* quota hash backpointer */
14034         unsigned int dq_id;             /* ID this applies to (uid, gid) */
14035         loff_t dq_off;                  /* Offset of dquot on disk */
14036         unsigned long dq_flags;         /* See DQ_* */
14037 @@ -233,13 +241,14 @@ struct dquot {
14038  
14039  /* Operations which must be implemented by each quota format */
14040  struct quota_format_ops {
14041 -       int (*check_quota_file)(struct super_block *sb, int type);      /* Detect whether file is in our format */
14042 -       int (*read_file_info)(struct super_block *sb, int type);        /* Read main info about file - called on quotaon() */
14043 -       int (*write_file_info)(struct super_block *sb, int type);       /* Write main info about file */
14044 -       int (*free_file_info)(struct super_block *sb, int type);        /* Called on quotaoff() */
14045 -       int (*read_dqblk)(struct dquot *dquot);         /* Read structure for one user */
14046 -       int (*commit_dqblk)(struct dquot *dquot);       /* Write structure for one user */
14047 -       int (*release_dqblk)(struct dquot *dquot);      /* Called when last reference to dquot is being dropped */
14048 +       int (*check_quota_file)(struct dqhash *, int);  /* Detect whether file is in our format */
14049 +       int (*read_file_info)(struct dqhash *, int);    /* Read main info about file - called on quotaon() */
14050 +       int (*write_file_info)(struct dqhash *, int);   /* Write main info about file */
14051 +       int (*free_file_info)(struct dqhash *, int);    /* Called on quotaoff() */
14052 +
14053 +       int (*read_dqblk)(struct dquot *);      /* Read structure for one user */
14054 +       int (*commit_dqblk)(struct dquot *);    /* Write structure for one user */
14055 +       int (*release_dqblk)(struct dquot *);   /* Called when last reference to dquot is being dropped */
14056  };
14057  
14058  /* Operations working with dquots */
14059 @@ -255,22 +264,22 @@ struct dquot_operations {
14060         int (*acquire_dquot) (struct dquot *);          /* Quota is going to be created on disk */
14061         int (*release_dquot) (struct dquot *);          /* Quota is going to be deleted from disk */
14062         int (*mark_dirty) (struct dquot *);             /* Dquot is marked dirty */
14063 -       int (*write_info) (struct super_block *, int);  /* Write of quota "superblock" */
14064 +       int (*write_info) (struct dqhash *, int);       /* Write of quota "superblock" */
14065  };
14066  
14067  /* Operations handling requests from userspace */
14068  struct quotactl_ops {
14069 -       int (*quota_on)(struct super_block *, int, int, char *);
14070 -       int (*quota_off)(struct super_block *, int);
14071 -       int (*quota_sync)(struct super_block *, int);
14072 -       int (*get_info)(struct super_block *, int, struct if_dqinfo *);
14073 -       int (*set_info)(struct super_block *, int, struct if_dqinfo *);
14074 -       int (*get_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
14075 -       int (*set_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *);
14076 -       int (*get_xstate)(struct super_block *, struct fs_quota_stat *);
14077 -       int (*set_xstate)(struct super_block *, unsigned int, int);
14078 -       int (*get_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
14079 -       int (*set_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *);
14080 +       int (*quota_on)(struct dqhash *, int, int, char *);
14081 +       int (*quota_off)(struct dqhash *, int);
14082 +       int (*quota_sync)(struct dqhash *, int);
14083 +       int (*get_info)(struct dqhash *, int, struct if_dqinfo *);
14084 +       int (*set_info)(struct dqhash *, int, struct if_dqinfo *);
14085 +       int (*get_dqblk)(struct dqhash *, int, qid_t, struct if_dqblk *);
14086 +       int (*set_dqblk)(struct dqhash *, int, qid_t, struct if_dqblk *);
14087 +       int (*get_xstate)(struct dqhash *, struct fs_quota_stat *);
14088 +       int (*set_xstate)(struct dqhash *, unsigned int, int);
14089 +       int (*get_xquota)(struct dqhash *, int, qid_t, struct fs_disk_quota *);
14090 +       int (*set_xquota)(struct dqhash *, int, qid_t, struct fs_disk_quota *);
14091  };
14092  
14093  struct quota_format_type {
14094 @@ -293,16 +302,15 @@ struct quota_info {
14095         struct quota_format_ops *ops[MAXQUOTAS];        /* Operations for each type */
14096  };
14097  
14098 -/* Inline would be better but we need to dereference super_block which is not defined yet */
14099 -int mark_dquot_dirty(struct dquot *dquot);
14100  
14101  #define dquot_dirty(dquot) test_bit(DQ_MOD_B, &(dquot)->dq_flags)
14102  
14103 -#define sb_has_quota_enabled(sb, type) ((type)==USRQUOTA ? \
14104 -       (sb_dqopt(sb)->flags & DQUOT_USR_ENABLED) : (sb_dqopt(sb)->flags & DQUOT_GRP_ENABLED))
14105 +#define dqh_has_quota_enabled(hash, type) (dqhash_valid(hash) && ((type)==USRQUOTA ? \
14106 +       (dqh_dqopt(hash)->flags & DQUOT_USR_ENABLED) : (dqh_dqopt(hash)->flags & DQUOT_GRP_ENABLED)))
14107 +
14108 +#define dqh_any_quota_enabled(hash) (dqhash_valid(hash) && \
14109 +       (dqh_has_quota_enabled(hash, USRQUOTA) || dqh_has_quota_enabled(hash, GRPQUOTA)))
14110  
14111 -#define sb_any_quota_enabled(sb) (sb_has_quota_enabled(sb, USRQUOTA) | \
14112 -                                 sb_has_quota_enabled(sb, GRPQUOTA))
14113  
14114  int register_quota_format(struct quota_format_type *fmt);
14115  void unregister_quota_format(struct quota_format_type *fmt);
14116 @@ -317,6 +325,50 @@ struct quota_module_name {
14117         {QFMT_VFS_V0, "quota_v2"},\
14118         {0, NULL}}
14119  
14120 +struct dqhash {
14121 +       struct list_head dqh_list;      /* List of all quota hashes */
14122 +       unsigned int dqh_id;            /* ID for hash */
14123 +       atomic_t dqh_count;             /* Use count */
14124 +       struct quota_info dqh_dqopt;    /* Diskquota specific options */
14125 +       struct dquot_operations *dqh_qop;
14126 +       struct quotactl_ops *dqh_qcop;
14127 +       struct super_block *dqh_sb;     /* super block */
14128 +       unsigned int dqh_hash_bits;
14129 +       unsigned int dqh_hash_mask;
14130 +       struct hlist_head *dqh_hash;
14131 +};
14132 +
14133 +#ifdef CONFIG_QUOTACTL
14134 +
14135 +struct dqhash *new_dqhash(struct super_block *, unsigned int);
14136 +void destroy_dqhash(struct dqhash *);
14137 +struct dqhash *find_dqhash(unsigned int);
14138 +
14139 +static inline void dqhput(struct dqhash *hash)
14140 +{
14141 +       if (dqhash_valid(hash))
14142 +               if (atomic_dec_and_test(&hash->dqh_count))
14143 +                       destroy_dqhash(hash);
14144 +}
14145 +
14146 +static inline struct dqhash *dqhget(struct dqhash *hash)
14147 +{
14148 +       if (dqhash_valid(hash))
14149 +               atomic_inc(&hash->dqh_count);
14150 +       return hash;
14151 +}
14152 +
14153 +#else /* CONFIG_QUOTACTL */
14154 +
14155 +#define new_dqhash(sb, dqdom)          (0)
14156 +#define find_dqhash(dqdom)             (0)
14157 +#define destroy_dqhash(hash)           do { } while(0)
14158 +
14159 +#define dqhput(hash)                   do { } while(0)
14160 +#define dqhget(hash)                   (hash)
14161 +
14162 +#endif /* CONFIG_QUOTACTL */
14163 +
14164  #else
14165  
14166  # /* nodep */ include <sys/cdefs.h>
14167 diff -NurpP --minimal linux-2.6.19.1/include/linux/quotaops.h linux-2.6.19.1-vs2.3.0.6/include/linux/quotaops.h
14168 --- linux-2.6.19.1/include/linux/quotaops.h     2006-09-20 16:58:44 +0200
14169 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/quotaops.h   2006-11-08 04:57:51 +0100
14170 @@ -19,7 +19,7 @@
14171  /*
14172   * declaration of quota_function calls in kernel.
14173   */
14174 -extern void sync_dquots(struct super_block *sb, int type);
14175 +extern void sync_dquots(struct dqhash *hash, int type);
14176  
14177  extern int dquot_initialize(struct inode *inode, int type);
14178  extern int dquot_drop(struct inode *inode);
14179 @@ -34,19 +34,19 @@ extern int dquot_transfer(struct inode *
14180  extern int dquot_commit(struct dquot *dquot);
14181  extern int dquot_acquire(struct dquot *dquot);
14182  extern int dquot_release(struct dquot *dquot);
14183 -extern int dquot_commit_info(struct super_block *sb, int type);
14184 +extern int dquot_commit_info(struct dqhash *hash, int type);
14185  extern int dquot_mark_dquot_dirty(struct dquot *dquot);
14186  
14187 -extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path);
14188 -extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
14189 +extern int vfs_quota_on(struct dqhash *hash, int type, int format_id, char *path);
14190 +extern int vfs_quota_on_mount(struct dqhash *hash, char *qf_name,
14191                 int format_id, int type);
14192 -extern int vfs_quota_off(struct super_block *sb, int type);
14193 -#define vfs_quota_off_mount(sb, type) vfs_quota_off(sb, type)
14194 -extern int vfs_quota_sync(struct super_block *sb, int type);
14195 -extern int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
14196 -extern int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
14197 -extern int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
14198 -extern int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di);
14199 +extern int vfs_quota_off(struct dqhash *hash, int type);
14200 +#define vfs_quota_off_mount(dqh, type) vfs_quota_off(dqh, type)
14201 +extern int vfs_quota_sync(struct dqhash *hash, int type);
14202 +extern int vfs_get_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii);
14203 +extern int vfs_set_dqinfo(struct dqhash *hash, int type, struct if_dqinfo *ii);
14204 +extern int vfs_get_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di);
14205 +extern int vfs_set_dqblk(struct dqhash *hash, int type, qid_t id, struct if_dqblk *di);
14206  
14207  /*
14208   * Operations supported for diskquotas.
14209 @@ -61,9 +61,12 @@ extern struct quotactl_ops vfs_quotactl_
14210   * need a lot of space in journal for dquot structure allocation. */
14211  static __inline__ void DQUOT_INIT(struct inode *inode)
14212  {
14213 -       BUG_ON(!inode->i_sb);
14214 -       if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode))
14215 -               inode->i_sb->dq_op->initialize(inode, -1);
14216 +       if (!dqhash_valid(inode->i_dqh))
14217 +               return;
14218 +       BUG_ON(!inode->i_dqh);
14219 +       // printk("DQUOT_INIT(%p,%p,%d)\n", inode, inode->i_dqh, dqh_any_quota_enabled(inode->i_dqh));
14220 +       if (dqh_any_quota_enabled(inode->i_dqh) && !IS_NOQUOTA(inode))
14221 +               inode->i_dqh->dqh_qop->initialize(inode, -1);
14222  }
14223  
14224  /* The same as with DQUOT_INIT */
14225 @@ -72,8 +75,8 @@ static __inline__ void DQUOT_DROP(struct
14226         /* Here we can get arbitrary inode from clear_inode() so we have
14227          * to be careful. OTOH we don't need locking as quota operations
14228          * are allowed to change only at mount time */
14229 -       if (!IS_NOQUOTA(inode) && inode->i_sb && inode->i_sb->dq_op
14230 -           && inode->i_sb->dq_op->drop) {
14231 +       if (!IS_NOQUOTA(inode) && inode->i_dqh && inode->i_dqh->dqh_qop
14232 +           && inode->i_dqh->dqh_qop->drop) {
14233                 int cnt;
14234                 /* Test before calling to rule out calls from proc and such
14235                   * where we are not allowed to block. Note that this is
14236 @@ -84,7 +87,7 @@ static __inline__ void DQUOT_DROP(struct
14237                         if (inode->i_dquot[cnt] != NODQUOT)
14238                                 break;
14239                 if (cnt < MAXQUOTAS)
14240 -                       inode->i_sb->dq_op->drop(inode);
14241 +                       inode->i_dqh->dqh_qop->drop(inode);
14242         }
14243  }
14244  
14245 @@ -92,9 +95,9 @@ static __inline__ void DQUOT_DROP(struct
14246   * a transaction (deadlocks possible otherwise) */
14247  static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14248  {
14249 -       if (sb_any_quota_enabled(inode->i_sb)) {
14250 +       if (dqh_any_quota_enabled(inode->i_dqh)) {
14251                 /* Used space is updated in alloc_space() */
14252 -               if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA)
14253 +               if (inode->i_dqh->dqh_qop->alloc_space(inode, nr, 1) == NO_QUOTA)
14254                         return 1;
14255         }
14256         else
14257 @@ -112,9 +115,9 @@ static __inline__ int DQUOT_PREALLOC_SPA
14258  
14259  static __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14260  {
14261 -       if (sb_any_quota_enabled(inode->i_sb)) {
14262 +       if (dqh_any_quota_enabled(inode->i_dqh)) {
14263                 /* Used space is updated in alloc_space() */
14264 -               if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA)
14265 +               if (inode->i_dqh->dqh_qop->alloc_space(inode, nr, 0) == NO_QUOTA)
14266                         return 1;
14267         }
14268         else
14269 @@ -132,9 +135,9 @@ static __inline__ int DQUOT_ALLOC_SPACE(
14270  
14271  static __inline__ int DQUOT_ALLOC_INODE(struct inode *inode)
14272  {
14273 -       if (sb_any_quota_enabled(inode->i_sb)) {
14274 +       if (dqh_any_quota_enabled(inode->i_dqh)) {
14275                 DQUOT_INIT(inode);
14276 -               if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA)
14277 +               if (inode->i_dqh->dqh_qop->alloc_inode(inode, 1) == NO_QUOTA)
14278                         return 1;
14279         }
14280         return 0;
14281 @@ -142,8 +145,8 @@ static __inline__ int DQUOT_ALLOC_INODE(
14282  
14283  static __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14284  {
14285 -       if (sb_any_quota_enabled(inode->i_sb))
14286 -               inode->i_sb->dq_op->free_space(inode, nr);
14287 +       if (dqh_any_quota_enabled(inode->i_dqh))
14288 +               inode->i_dqh->dqh_qop->free_space(inode, nr);
14289         else
14290                 inode_sub_bytes(inode, nr);
14291  }
14292 @@ -156,29 +159,30 @@ static __inline__ void DQUOT_FREE_SPACE(
14293  
14294  static __inline__ void DQUOT_FREE_INODE(struct inode *inode)
14295  {
14296 -       if (sb_any_quota_enabled(inode->i_sb))
14297 -               inode->i_sb->dq_op->free_inode(inode, 1);
14298 +       if (dqh_any_quota_enabled(inode->i_dqh))
14299 +               inode->i_dqh->dqh_qop->free_inode(inode, 1);
14300  }
14301  
14302  static __inline__ int DQUOT_TRANSFER(struct inode *inode, struct iattr *iattr)
14303  {
14304 -       if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) {
14305 +       if (dqh_any_quota_enabled(inode->i_dqh) && !IS_NOQUOTA(inode)) {
14306                 DQUOT_INIT(inode);
14307 -               if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA)
14308 +               if (inode->i_dqh->dqh_qop->transfer(inode, iattr) == NO_QUOTA)
14309                         return 1;
14310         }
14311         return 0;
14312  }
14313  
14314  /* The following two functions cannot be called inside a transaction */
14315 -#define DQUOT_SYNC(sb) sync_dquots(sb, -1)
14316 +#define DQUOT_SYNC(hash)       sync_dquots(hash, -1)
14317  
14318 -static __inline__ int DQUOT_OFF(struct super_block *sb)
14319 +static __inline__ int DQUOT_OFF(struct dqhash *hash)
14320  {
14321         int ret = -ENOSYS;
14322  
14323 -       if (sb_any_quota_enabled(sb) && sb->s_qcop && sb->s_qcop->quota_off)
14324 -               ret = sb->s_qcop->quota_off(sb, -1);
14325 +       if (dqh_any_quota_enabled(hash) && hash->dqh_qcop &&
14326 +               hash->dqh_qcop->quota_off)
14327 +               ret = hash->dqh_qcop->quota_off(hash, -1);
14328         return ret;
14329  }
14330  
14331 @@ -193,8 +197,8 @@ static __inline__ int DQUOT_OFF(struct s
14332  #define DQUOT_DROP(inode)                      do { } while(0)
14333  #define DQUOT_ALLOC_INODE(inode)               (0)
14334  #define DQUOT_FREE_INODE(inode)                        do { } while(0)
14335 -#define DQUOT_SYNC(sb)                         do { } while(0)
14336 -#define DQUOT_OFF(sb)                          do { } while(0)
14337 +#define DQUOT_SYNC(hash)                       do { } while(0)
14338 +#define DQUOT_OFF(hash)                                do { } while(0)
14339  #define DQUOT_TRANSFER(inode, iattr)           (0)
14340  static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
14341  {
14342 diff -NurpP --minimal linux-2.6.19.1/include/linux/reiserfs_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/reiserfs_fs.h
14343 --- linux-2.6.19.1/include/linux/reiserfs_fs.h  2006-11-30 21:19:39 +0100
14344 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/reiserfs_fs.h        2006-12-17 04:16:56 +0100
14345 @@ -821,6 +821,10 @@ struct stat_data_v1 {
14346  #define REISERFS_COMPR_FL     FS_COMPR_FL
14347  #define REISERFS_NOTAIL_FL    FS_NOTAIL_FL
14348  
14349 +/* unfortunately reiserfs sdattr is only 16 bit */
14350 +#define REISERFS_BARRIER_FL   (FS_BARRIER_FL >> 16)
14351 +#define REISERFS_IUNLINK_FL   (FS_IUNLINK_FL >> 16)
14352 +
14353  /* persistent flags that file inherits from the parent directory */
14354  #define REISERFS_INHERIT_MASK ( REISERFS_IMMUTABLE_FL |        \
14355                                 REISERFS_SYNC_FL |      \
14356 @@ -830,6 +834,9 @@ struct stat_data_v1 {
14357                                 REISERFS_COMPR_FL |     \
14358                                 REISERFS_NOTAIL_FL )
14359  
14360 +#define REISERFS_FL_USER_VISIBLE       0x80FF
14361 +#define REISERFS_FL_USER_MODIFIABLE    0x80FF
14362 +
14363  /* Stat Data on disk (reiserfs version of UFS disk inode minus the
14364     address blocks) */
14365  struct stat_data {
14366 @@ -1901,6 +1908,7 @@ static inline void reiserfs_update_sd(st
14367  void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode);
14368  void i_attrs_to_sd_attrs(struct inode *inode, __u16 * sd_attrs);
14369  int reiserfs_setattr(struct dentry *dentry, struct iattr *attr);
14370 +int reiserfs_sync_flags(struct inode *inode);
14371  
14372  /* namei.c */
14373  void set_de_name_and_namelen(struct reiserfs_dir_entry *de);
14374 diff -NurpP --minimal linux-2.6.19.1/include/linux/reiserfs_fs_sb.h linux-2.6.19.1-vs2.3.0.6/include/linux/reiserfs_fs_sb.h
14375 --- linux-2.6.19.1/include/linux/reiserfs_fs_sb.h       2006-11-30 21:19:39 +0100
14376 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/reiserfs_fs_sb.h     2006-11-08 04:57:46 +0100
14377 @@ -456,6 +456,7 @@ enum reiserfs_mount_options {
14378         REISERFS_POSIXACL,
14379         REISERFS_BARRIER_NONE,
14380         REISERFS_BARRIER_FLUSH,
14381 +       REISERFS_TAGGED,
14382  
14383         /* Actions on error */
14384         REISERFS_ERROR_PANIC,
14385 diff -NurpP --minimal linux-2.6.19.1/include/linux/sched.h linux-2.6.19.1-vs2.3.0.6/include/linux/sched.h
14386 --- linux-2.6.19.1/include/linux/sched.h        2006-11-30 21:19:39 +0100
14387 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/sched.h      2006-12-13 09:15:23 +0100
14388 @@ -26,6 +26,7 @@
14389  #define CLONE_STOPPED          0x02000000      /* Start in stopped state */
14390  #define CLONE_NEWUTS           0x04000000      /* New utsname group? */
14391  #define CLONE_NEWIPC           0x08000000      /* New ipcs */
14392 +#define CLONE_KTHREAD          0x10000000      /* clone a kernel thread */
14393  
14394  /*
14395   * Scheduling policies
14396 @@ -54,6 +55,7 @@ struct sched_param {
14397  #include <linux/cpumask.h>
14398  #include <linux/errno.h>
14399  #include <linux/nodemask.h>
14400 +// #include <linux/vs_base.h>
14401  
14402  #include <asm/system.h>
14403  #include <asm/semaphore.h>
14404 @@ -92,7 +94,7 @@ struct futex_pi_state;
14405   * List of flags we want to share for kernel threads,
14406   * if only because they are not used by them anyway.
14407   */
14408 -#define CLONE_KERNEL   (CLONE_FS | CLONE_FILES | CLONE_SIGHAND)
14409 +#define CLONE_KERNEL   (CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_KTHREAD)
14410  
14411  /*
14412   * These are the constant used to fake the fixed-point load-average
14413 @@ -144,12 +146,13 @@ extern unsigned long weighted_cpuload(co
14414  #define TASK_UNINTERRUPTIBLE   2
14415  #define TASK_STOPPED           4
14416  #define TASK_TRACED            8
14417 +#define TASK_ONHOLD            16
14418  /* in tsk->exit_state */
14419 -#define EXIT_ZOMBIE            16
14420 -#define EXIT_DEAD              32
14421 +#define EXIT_ZOMBIE            32
14422 +#define EXIT_DEAD              64
14423  /* in tsk->state again */
14424 -#define TASK_NONINTERACTIVE    64
14425 -#define TASK_DEAD              128
14426 +#define TASK_NONINTERACTIVE    128
14427 +#define TASK_DEAD              256
14428  
14429  #define __set_task_state(tsk, state_value)             \
14430         do { (tsk)->state = (state_value); } while (0)
14431 @@ -264,27 +267,30 @@ extern void arch_unmap_area_topdown(stru
14432   * The mm counters are not protected by its page_table_lock,
14433   * so must be incremented atomically.
14434   */
14435 -#define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value)
14436 -#define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member))
14437 -#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member)
14438 -#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)
14439 -#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)
14440  typedef atomic_long_t mm_counter_t;
14441 +#define __set_mm_counter(mm, member, value) \
14442 +       atomic_long_set(&(mm)->_##member, value)
14443 +#define get_mm_counter(mm, member) \
14444 +       ((unsigned long)atomic_long_read(&(mm)->_##member))
14445  
14446  #else  /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
14447  /*
14448   * The mm counters are protected by its page_table_lock,
14449   * so can be incremented directly.
14450   */
14451 -#define set_mm_counter(mm, member, value) (mm)->_##member = (value)
14452 -#define get_mm_counter(mm, member) ((mm)->_##member)
14453 -#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
14454 -#define inc_mm_counter(mm, member) (mm)->_##member++
14455 -#define dec_mm_counter(mm, member) (mm)->_##member--
14456  typedef unsigned long mm_counter_t;
14457 +#define __set_mm_counter(mm, member, value) (mm)->_##member = (value)
14458 +#define get_mm_counter(mm, member) ((mm)->_##member)
14459  
14460  #endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
14461  
14462 +#define set_mm_counter(mm, member, value) \
14463 +       vx_ ## member ## pages_sub((mm), (get_mm_counter(mm, member) - value))
14464 +#define add_mm_counter(mm, member, value) \
14465 +       vx_ ## member ## pages_add((mm), (value))
14466 +#define inc_mm_counter(mm, member) vx_ ## member ## pages_inc((mm))
14467 +#define dec_mm_counter(mm, member) vx_ ## member ## pages_dec((mm))
14468 +
14469  #define get_mm_rss(mm)                                 \
14470         (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))
14471  #define update_hiwater_rss(mm) do {                    \
14472 @@ -343,6 +349,7 @@ struct mm_struct {
14473  
14474         /* Architecture-specific MM context */
14475         mm_context_t context;
14476 +       struct vx_info *mm_vx_info;
14477  
14478         /* Token based thrashing protection. */
14479         unsigned long swap_token_time;
14480 @@ -532,9 +539,10 @@ struct user_struct {
14481         /* Hash table maintenance information */
14482         struct list_head uidhash_list;
14483         uid_t uid;
14484 +       xid_t xid;
14485  };
14486  
14487 -extern struct user_struct *find_user(uid_t);
14488 +extern struct user_struct *find_user(xid_t, uid_t);
14489  
14490  extern struct user_struct root_user;
14491  #define INIT_USER (&root_user)
14492 @@ -925,6 +933,14 @@ struct task_struct {
14493         
14494         void *security;
14495         struct audit_context *audit_context;
14496 +
14497 +/* vserver context data */
14498 +       struct vx_info *vx_info;
14499 +       struct nx_info *nx_info;
14500 +
14501 +       xid_t xid;
14502 +       nid_t nid;
14503 +
14504         seccomp_t seccomp;
14505  
14506  /* Thread group tracking */
14507 @@ -1221,13 +1237,18 @@ extern struct task_struct init_task;
14508  
14509  extern struct   mm_struct init_mm;
14510  
14511 -#define find_task_by_pid(nr)   find_task_by_pid_type(PIDTYPE_PID, nr)
14512 +
14513 +#define find_task_by_real_pid(nr) \
14514 +       find_task_by_pid_type(PIDTYPE_REALPID, nr)
14515 +#define find_task_by_pid(nr) \
14516 +       find_task_by_pid_type(PIDTYPE_PID, nr)
14517 +
14518  extern struct task_struct *find_task_by_pid_type(int type, int pid);
14519  extern void set_special_pids(pid_t session, pid_t pgrp);
14520  extern void __set_special_pids(pid_t session, pid_t pgrp);
14521  
14522  /* per-UID process charging. */
14523 -extern struct user_struct * alloc_uid(uid_t);
14524 +extern struct user_struct * alloc_uid(xid_t, uid_t);
14525  static inline struct user_struct *get_uid(struct user_struct *u)
14526  {
14527         atomic_inc(&u->__count);
14528 diff -NurpP --minimal linux-2.6.19.1/include/linux/security.h linux-2.6.19.1-vs2.3.0.6/include/linux/security.h
14529 --- linux-2.6.19.1/include/linux/security.h     2006-11-30 21:19:39 +0100
14530 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/security.h   2006-11-08 04:57:51 +0100
14531 @@ -1172,7 +1172,7 @@ struct security_operations {
14532         int (*capable) (struct task_struct * tsk, int cap);
14533         int (*acct) (struct file * file);
14534         int (*sysctl) (struct ctl_table * table, int op);
14535 -       int (*quotactl) (int cmds, int type, int id, struct super_block * sb);
14536 +       int (*quotactl) (int cmds, int type, int id, struct dqhash *);
14537         int (*quota_on) (struct dentry * dentry);
14538         int (*syslog) (int type);
14539         int (*settime) (struct timespec *ts, struct timezone *tz);
14540 @@ -1456,9 +1456,9 @@ static inline int security_sysctl(struct
14541  }
14542  
14543  static inline int security_quotactl (int cmds, int type, int id,
14544 -                                    struct super_block *sb)
14545 +                                    struct dqhash *hash)
14546  {
14547 -       return security_ops->quotactl (cmds, type, id, sb);
14548 +       return security_ops->quotactl (cmds, type, id, hash);
14549  }
14550  
14551  static inline int security_quota_on (struct dentry * dentry)
14552 @@ -2201,7 +2201,7 @@ static inline int security_sysctl(struct
14553  }
14554  
14555  static inline int security_quotactl (int cmds, int type, int id,
14556 -                                    struct super_block * sb)
14557 +                                    struct dqhash * hash)
14558  {
14559         return 0;
14560  }
14561 diff -NurpP --minimal linux-2.6.19.1/include/linux/shmem_fs.h linux-2.6.19.1-vs2.3.0.6/include/linux/shmem_fs.h
14562 --- linux-2.6.19.1/include/linux/shmem_fs.h     2006-11-30 21:19:39 +0100
14563 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/shmem_fs.h   2006-11-08 04:57:53 +0100
14564 @@ -8,6 +8,9 @@
14565  
14566  #define SHMEM_NR_DIRECT 16
14567  
14568 +#define TMPFS_SUPER_MAGIC      0x01021994
14569 +
14570 +
14571  struct shmem_inode_info {
14572         spinlock_t              lock;
14573         unsigned long           flags;
14574 diff -NurpP --minimal linux-2.6.19.1/include/linux/stat.h linux-2.6.19.1-vs2.3.0.6/include/linux/stat.h
14575 --- linux-2.6.19.1/include/linux/stat.h 2006-11-30 21:19:40 +0100
14576 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/stat.h       2006-11-08 04:57:46 +0100
14577 @@ -63,6 +63,7 @@ struct kstat {
14578         unsigned int    nlink;
14579         uid_t           uid;
14580         gid_t           gid;
14581 +       tag_t           tag;
14582         dev_t           rdev;
14583         loff_t          size;
14584         struct timespec  atime;
14585 diff -NurpP --minimal linux-2.6.19.1/include/linux/sunrpc/auth.h linux-2.6.19.1-vs2.3.0.6/include/linux/sunrpc/auth.h
14586 --- linux-2.6.19.1/include/linux/sunrpc/auth.h  2006-11-30 21:19:40 +0100
14587 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/sunrpc/auth.h        2006-11-08 04:57:47 +0100
14588 @@ -24,6 +24,7 @@
14589  struct auth_cred {
14590         uid_t   uid;
14591         gid_t   gid;
14592 +       tag_t   tag;
14593         struct group_info *group_info;
14594  };
14595  
14596 diff -NurpP --minimal linux-2.6.19.1/include/linux/sunrpc/clnt.h linux-2.6.19.1-vs2.3.0.6/include/linux/sunrpc/clnt.h
14597 --- linux-2.6.19.1/include/linux/sunrpc/clnt.h  2006-11-30 21:19:40 +0100
14598 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/sunrpc/clnt.h        2006-11-08 04:57:47 +0100
14599 @@ -42,7 +42,8 @@ struct rpc_clnt {
14600                                 cl_intr     : 1,/* interruptible */
14601                                 cl_autobind : 1,/* use getport() */
14602                                 cl_oneshot  : 1,/* dispose after use */
14603 -                               cl_dead     : 1;/* abandoned */
14604 +                               cl_dead     : 1,/* abandoned */
14605 +                               cl_tag      : 1;/* context tagging */
14606  
14607         struct rpc_rtt *        cl_rtt;         /* RTO estimator data */
14608  
14609 diff -NurpP --minimal linux-2.6.19.1/include/linux/syscalls.h linux-2.6.19.1-vs2.3.0.6/include/linux/syscalls.h
14610 --- linux-2.6.19.1/include/linux/syscalls.h     2006-11-30 21:19:40 +0100
14611 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/syscalls.h   2006-11-08 04:57:51 +0100
14612 @@ -294,6 +294,8 @@ asmlinkage long sys_symlink(const char _
14613  asmlinkage long sys_unlink(const char __user *pathname);
14614  asmlinkage long sys_rename(const char __user *oldname,
14615                                 const char __user *newname);
14616 +asmlinkage long sys_copyfile(const char __user *from, const char __user *to,
14617 +                               umode_t mode);
14618  asmlinkage long sys_chmod(const char __user *filename, mode_t mode);
14619  asmlinkage long sys_fchmod(unsigned int fd, mode_t mode);
14620  
14621 diff -NurpP --minimal linux-2.6.19.1/include/linux/sysctl.h linux-2.6.19.1-vs2.3.0.6/include/linux/sysctl.h
14622 --- linux-2.6.19.1/include/linux/sysctl.h       2006-11-30 21:19:40 +0100
14623 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/sysctl.h     2006-11-08 21:52:09 +0100
14624 @@ -101,6 +101,7 @@ enum
14625         KERN_CAP_BSET=14,       /* int: capability bounding set */
14626         KERN_PANIC=15,          /* int: panic timeout */
14627         KERN_REALROOTDEV=16,    /* real root device to mount after initrd */
14628 +       KERN_VSHELPER=17,       /* string: path to vshelper policy agent */
14629  
14630         KERN_SPARC_REBOOT=21,   /* reboot command on Sparc */
14631         KERN_CTLALTDEL=22,      /* int: allow ctl-alt-del to reboot */
14632 @@ -932,6 +933,9 @@ typedef int ctl_handler (ctl_table *tabl
14633  typedef int proc_handler (ctl_table *ctl, int write, struct file * filp,
14634                           void __user *buffer, size_t *lenp, loff_t *ppos);
14635  
14636 +typedef int virt_handler (struct ctl_table *ctl, int write, xid_t xid,
14637 +                         void **datap, size_t *lenp);
14638 +
14639  extern int proc_dostring(ctl_table *, int, struct file *,
14640                          void __user *, size_t *, loff_t *);
14641  extern int proc_dointvec(ctl_table *, int, struct file *,
14642 @@ -1016,6 +1020,7 @@ struct ctl_table 
14643         mode_t mode;
14644         ctl_table *child;
14645         proc_handler *proc_handler;     /* Callback for text formatting */
14646 +       virt_handler *virt_handler;     /* Context virtualization */
14647         ctl_handler *strategy;          /* Callback function for all r/w */
14648         struct proc_dir_entry *de;      /* /proc control block */
14649         void *extra1;
14650 diff -NurpP --minimal linux-2.6.19.1/include/linux/sysfs.h linux-2.6.19.1-vs2.3.0.6/include/linux/sysfs.h
14651 --- linux-2.6.19.1/include/linux/sysfs.h        2006-11-30 21:19:40 +0100
14652 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/sysfs.h      2006-11-08 04:57:53 +0100
14653 @@ -13,6 +13,8 @@
14654  #include <linux/compiler.h>
14655  #include <asm/atomic.h>
14656  
14657 +#define SYSFS_SUPER_MAGIC      0x62656572
14658 +
14659  struct kobject;
14660  struct module;
14661  
14662 diff -NurpP --minimal linux-2.6.19.1/include/linux/time.h linux-2.6.19.1-vs2.3.0.6/include/linux/time.h
14663 --- linux-2.6.19.1/include/linux/time.h 2006-09-20 16:58:44 +0200
14664 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/time.h       2006-11-08 04:57:40 +0100
14665 @@ -174,6 +174,9 @@ static inline void timespec_add_ns(struc
14666         }
14667         a->tv_nsec = ns;
14668  }
14669 +
14670 +#include <linux/vs_time.h>
14671 +
14672  #endif /* __KERNEL__ */
14673  
14674  #define NFDBITS                        __NFDBITS
14675 diff -NurpP --minimal linux-2.6.19.1/include/linux/types.h linux-2.6.19.1-vs2.3.0.6/include/linux/types.h
14676 --- linux-2.6.19.1/include/linux/types.h        2006-11-30 21:19:40 +0100
14677 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/types.h      2006-11-08 04:57:40 +0100
14678 @@ -39,6 +39,9 @@ typedef __kernel_uid32_t      uid_t;
14679  typedef __kernel_gid32_t       gid_t;
14680  typedef __kernel_uid16_t        uid16_t;
14681  typedef __kernel_gid16_t        gid16_t;
14682 +typedef unsigned int           xid_t;
14683 +typedef unsigned int           nid_t;
14684 +typedef unsigned int           tag_t;
14685  
14686  #ifdef CONFIG_UID16
14687  /* This is defined by include/asm-{arch}/posix_types.h */
14688 diff -NurpP --minimal linux-2.6.19.1/include/linux/vroot.h linux-2.6.19.1-vs2.3.0.6/include/linux/vroot.h
14689 --- linux-2.6.19.1/include/linux/vroot.h        1970-01-01 01:00:00 +0100
14690 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vroot.h      2006-11-08 04:57:51 +0100
14691 @@ -0,0 +1,51 @@
14692 +
14693 +/*
14694 + * include/linux/vroot.h
14695 + *
14696 + * written by Herbert Pötzl, 9/11/2002
14697 + * ported to 2.6 by Herbert Pötzl, 30/12/2004
14698 + *
14699 + * Copyright (C) 2002-2005 by Herbert Pötzl.
14700 + * Redistribution of this file is permitted under the
14701 + * GNU General Public License.
14702 + */
14703 +
14704 +#ifndef _LINUX_VROOT_H
14705 +#define _LINUX_VROOT_H
14706 +
14707 +
14708 +#ifdef __KERNEL__
14709 +
14710 +/* Possible states of device */
14711 +enum {
14712 +       Vr_unbound,
14713 +       Vr_bound,
14714 +};
14715 +
14716 +struct vroot_device {
14717 +       int             vr_number;
14718 +       int             vr_refcnt;
14719 +
14720 +       struct semaphore        vr_ctl_mutex;
14721 +       struct block_device    *vr_device;
14722 +       int                     vr_state;
14723 +};
14724 +
14725 +
14726 +typedef struct block_device *(vroot_grb_func)(struct block_device *);
14727 +
14728 +extern int register_vroot_grb(vroot_grb_func *);
14729 +extern int unregister_vroot_grb(vroot_grb_func *);
14730 +
14731 +#endif /* __KERNEL__ */
14732 +
14733 +#define MAX_VROOT_DEFAULT      8
14734 +
14735 +/*
14736 + * IOCTL commands --- we will commandeer 0x56 ('V')
14737 + */
14738 +
14739 +#define VROOT_SET_DEV          0x5600
14740 +#define VROOT_CLR_DEV          0x5601
14741 +
14742 +#endif /* _LINUX_VROOT_H */
14743 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_base.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_base.h
14744 --- linux-2.6.19.1/include/linux/vs_base.h      1970-01-01 01:00:00 +0100
14745 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_base.h    2006-11-30 19:39:09 +0100
14746 @@ -0,0 +1,9 @@
14747 +#ifndef _VS_BASE_H
14748 +#define _VS_BASE_H
14749 +
14750 +#include "vserver/base.h"
14751 +#include "vserver/debug.h"
14752 +
14753 +#else
14754 +#warning duplicate inclusion
14755 +#endif
14756 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_context.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_context.h
14757 --- linux-2.6.19.1/include/linux/vs_context.h   1970-01-01 01:00:00 +0100
14758 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_context.h 2006-11-30 18:53:18 +0100
14759 @@ -0,0 +1,244 @@
14760 +#ifndef _VS_CONTEXT_H
14761 +#define _VS_CONTEXT_H
14762 +
14763 +#include "vserver/base.h"
14764 +#include "vserver/context.h"
14765 +#include "vserver/history.h"
14766 +#include "vserver/debug.h"
14767 +
14768 +
14769 +#define get_vx_info(i) __get_vx_info(i,__FILE__,__LINE__,__HERE__)
14770 +
14771 +static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
14772 +       const char *_file, int _line, void *_here)
14773 +{
14774 +       if (!vxi)
14775 +               return NULL;
14776 +
14777 +       vxlprintk(VXD_CBIT(xid, 2), "get_vx_info(%p[#%d.%d])",
14778 +               vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_usecnt):0,
14779 +               _file, _line);
14780 +       __vxh_get_vx_info(vxi, _here);
14781 +
14782 +       atomic_inc(&vxi->vx_usecnt);
14783 +       return vxi;
14784 +}
14785 +
14786 +
14787 +extern void free_vx_info(struct vx_info *);
14788 +
14789 +#define put_vx_info(i) __put_vx_info(i,__FILE__,__LINE__,__HERE__)
14790 +
14791 +static inline void __put_vx_info(struct vx_info *vxi,
14792 +       const char *_file, int _line, void *_here)
14793 +{
14794 +       if (!vxi)
14795 +               return;
14796 +
14797 +       vxlprintk(VXD_CBIT(xid, 2), "put_vx_info(%p[#%d.%d])",
14798 +               vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_usecnt):0,
14799 +               _file, _line);
14800 +       __vxh_put_vx_info(vxi, _here);
14801 +
14802 +       if (atomic_dec_and_test(&vxi->vx_usecnt))
14803 +               free_vx_info(vxi);
14804 +}
14805 +
14806 +
14807 +#define init_vx_info(p,i) __init_vx_info(p,i,__FILE__,__LINE__,__HERE__)
14808 +
14809 +static inline void __init_vx_info(struct vx_info **vxp, struct vx_info *vxi,
14810 +       const char *_file, int _line, void *_here)
14811 +{
14812 +       if (vxi) {
14813 +               vxlprintk(VXD_CBIT(xid, 3),
14814 +                       "init_vx_info(%p[#%d.%d])",
14815 +                       vxi, vxi?vxi->vx_id:0,
14816 +                       vxi?atomic_read(&vxi->vx_usecnt):0,
14817 +                       _file, _line);
14818 +               __vxh_init_vx_info(vxi, vxp, _here);
14819 +
14820 +               atomic_inc(&vxi->vx_usecnt);
14821 +       }
14822 +       *vxp = vxi;
14823 +}
14824 +
14825 +
14826 +#define set_vx_info(p,i) __set_vx_info(p,i,__FILE__,__LINE__,__HERE__)
14827 +
14828 +static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
14829 +       const char *_file, int _line, void *_here)
14830 +{
14831 +       struct vx_info *vxo;
14832 +
14833 +       if (!vxi)
14834 +               return;
14835 +
14836 +       vxlprintk(VXD_CBIT(xid, 3), "set_vx_info(%p[#%d.%d])",
14837 +               vxi, vxi?vxi->vx_id:0,
14838 +               vxi?atomic_read(&vxi->vx_usecnt):0,
14839 +               _file, _line);
14840 +       __vxh_set_vx_info(vxi, vxp, _here);
14841 +
14842 +       atomic_inc(&vxi->vx_usecnt);
14843 +       vxo = xchg(vxp, vxi);
14844 +       BUG_ON(vxo);
14845 +}
14846 +
14847 +
14848 +#define clr_vx_info(p) __clr_vx_info(p,__FILE__,__LINE__,__HERE__)
14849 +
14850 +static inline void __clr_vx_info(struct vx_info **vxp,
14851 +       const char *_file, int _line, void *_here)
14852 +{
14853 +       struct vx_info *vxo;
14854 +
14855 +       vxo = xchg(vxp, NULL);
14856 +       if (!vxo)
14857 +               return;
14858 +
14859 +       vxlprintk(VXD_CBIT(xid, 3), "clr_vx_info(%p[#%d.%d])",
14860 +               vxo, vxo?vxo->vx_id:0,
14861 +               vxo?atomic_read(&vxo->vx_usecnt):0,
14862 +               _file, _line);
14863 +       __vxh_clr_vx_info(vxo, vxp, _here);
14864 +
14865 +       if (atomic_dec_and_test(&vxo->vx_usecnt))
14866 +               free_vx_info(vxo);
14867 +}
14868 +
14869 +
14870 +#define claim_vx_info(v,p) \
14871 +       __claim_vx_info(v,p,__FILE__,__LINE__,__HERE__)
14872 +
14873 +static inline void __claim_vx_info(struct vx_info *vxi,
14874 +       struct task_struct *task,
14875 +       const char *_file, int _line, void *_here)
14876 +{
14877 +       vxlprintk(VXD_CBIT(xid, 3), "claim_vx_info(%p[#%d.%d.%d]) %p",
14878 +               vxi, vxi?vxi->vx_id:0,
14879 +               vxi?atomic_read(&vxi->vx_usecnt):0,
14880 +               vxi?atomic_read(&vxi->vx_tasks):0,
14881 +               task, _file, _line);
14882 +       __vxh_claim_vx_info(vxi, task, _here);
14883 +
14884 +       atomic_inc(&vxi->vx_tasks);
14885 +}
14886 +
14887 +
14888 +extern void unhash_vx_info(struct vx_info *);
14889 +
14890 +#define release_vx_info(v,p) \
14891 +       __release_vx_info(v,p,__FILE__,__LINE__,__HERE__)
14892 +
14893 +static inline void __release_vx_info(struct vx_info *vxi,
14894 +       struct task_struct *task,
14895 +       const char *_file, int _line, void *_here)
14896 +{
14897 +       vxlprintk(VXD_CBIT(xid, 3), "release_vx_info(%p[#%d.%d.%d]) %p",
14898 +               vxi, vxi?vxi->vx_id:0,
14899 +               vxi?atomic_read(&vxi->vx_usecnt):0,
14900 +               vxi?atomic_read(&vxi->vx_tasks):0,
14901 +               task, _file, _line);
14902 +       __vxh_release_vx_info(vxi, task, _here);
14903 +
14904 +       might_sleep();
14905 +
14906 +       if (atomic_dec_and_test(&vxi->vx_tasks))
14907 +               unhash_vx_info(vxi);
14908 +}
14909 +
14910 +
14911 +#define task_get_vx_info(p) \
14912 +       __task_get_vx_info(p,__FILE__,__LINE__,__HERE__)
14913 +
14914 +static inline struct vx_info *__task_get_vx_info(struct task_struct *p,
14915 +       const char *_file, int _line, void *_here)
14916 +{
14917 +       struct vx_info *vxi;
14918 +
14919 +       task_lock(p);
14920 +       vxlprintk(VXD_CBIT(xid, 5), "task_get_vx_info(%p)",
14921 +               p, _file, _line);
14922 +       vxi = __get_vx_info(p->vx_info, _file, _line, _here);
14923 +       task_unlock(p);
14924 +       return vxi;
14925 +}
14926 +
14927 +
14928 +static inline void __wakeup_vx_info(struct vx_info *vxi)
14929 +{
14930 +       if (waitqueue_active(&vxi->vx_wait))
14931 +               wake_up_interruptible(&vxi->vx_wait);
14932 +}
14933 +
14934 +
14935 +#define enter_vx_info(v,s)     __enter_vx_info(v,s,__FILE__,__LINE__)
14936 +
14937 +static inline void __enter_vx_info(struct vx_info *vxi,
14938 +       struct vx_info_save *vxis, const char *_file, int _line)
14939 +{
14940 +       vxlprintk(VXD_CBIT(xid, 5), "enter_vx_info(%p[#%d],%p) %p[#%d,%p]",
14941 +               vxi, vxi ? vxi->vx_id : 0, vxis, current,
14942 +               current->xid, current->vx_info, _file, _line);
14943 +       vxis->vxi = xchg(&current->vx_info, vxi);
14944 +       vxis->xid = current->xid;
14945 +       current->xid = vxi ? vxi->vx_id : 0;
14946 +}
14947 +
14948 +#define leave_vx_info(s)       __leave_vx_info(s,__FILE__,__LINE__)
14949 +
14950 +static inline void __leave_vx_info(struct vx_info_save *vxis,
14951 +       const char *_file, int _line)
14952 +{
14953 +       vxlprintk(VXD_CBIT(xid, 5), "leave_vx_info(%p[#%d,%p]) %p[#%d,%p]",
14954 +               vxis, vxis->xid, vxis->vxi, current,
14955 +               current->xid, current->vx_info, _file, _line);
14956 +       (void)xchg(&current->vx_info, vxis->vxi);
14957 +       current->xid = vxis->xid;
14958 +}
14959 +
14960 +
14961 +static inline void __enter_vx_admin(struct vx_info_save *vxis)
14962 +{
14963 +       vxis->vxi = xchg(&current->vx_info, NULL);
14964 +       vxis->xid = xchg(&current->xid, (xid_t)0);
14965 +}
14966 +
14967 +static inline void __leave_vx_admin(struct vx_info_save *vxis)
14968 +{
14969 +       (void)xchg(&current->xid, vxis->xid);
14970 +       (void)xchg(&current->vx_info, vxis->vxi);
14971 +}
14972 +
14973 +extern void exit_vx_info(struct task_struct *, int);
14974 +extern void exit_vx_info_early(struct task_struct *, int);
14975 +
14976 +
14977 +static inline
14978 +struct task_struct *vx_child_reaper(struct task_struct *p)
14979 +{
14980 +       struct vx_info *vxi = p->vx_info;
14981 +       struct task_struct *reaper = child_reaper;
14982 +
14983 +       if (!vxi)
14984 +               goto out;
14985 +
14986 +       BUG_ON(!p->vx_info->vx_reaper);
14987 +
14988 +       /* child reaper for the guest reaper */
14989 +       if (vxi->vx_reaper == p)
14990 +               goto out;
14991 +
14992 +       reaper = vxi->vx_reaper;
14993 +out:
14994 +       vxdprintk(VXD_CBIT(xid, 3),
14995 +               "vx_child_reaper(%p[#%u,%u]) = %p[#%u,%u]\n",
14996 +               p, p->xid, p->pid, reaper, reaper->xid, reaper->pid);
14997 +       return reaper;
14998 +}
14999 +
15000 +
15001 +#else
15002 +#warning duplicate inclusion
15003 +#endif
15004 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_cowbl.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_cowbl.h
15005 --- linux-2.6.19.1/include/linux/vs_cowbl.h     1970-01-01 01:00:00 +0100
15006 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_cowbl.h   2006-11-30 18:53:18 +0100
15007 @@ -0,0 +1,44 @@
15008 +#ifndef _VS_COWBL_H
15009 +#define _VS_COWBL_H
15010 +
15011 +#include <linux/fs.h>
15012 +#include <linux/dcache.h>
15013 +#include <linux/namei.h>
15014 +
15015 +extern struct dentry *cow_break_link(const char *pathname);
15016 +
15017 +static inline int cow_check_and_break(struct nameidata *nd)
15018 +{
15019 +       struct inode *inode = nd->dentry->d_inode;
15020 +       int error = 0;
15021 +       if (IS_RDONLY(inode) || MNT_IS_RDONLY(nd->mnt))
15022 +               return -EROFS;
15023 +       if (IS_COW(inode)) {
15024 +               if (IS_COW_LINK(inode)) {
15025 +                       struct dentry *new_dentry, *old_dentry = nd->dentry;
15026 +                       char *path, *buf;
15027 +
15028 +                       buf = kmalloc(PATH_MAX, GFP_KERNEL);
15029 +                       if (!buf) {
15030 +                               return -ENOMEM;
15031 +                       }
15032 +                       path = d_path(nd->dentry, nd->mnt, buf, PATH_MAX);
15033 +                       new_dentry = cow_break_link(path);
15034 +                       kfree(buf);
15035 +                       if (!IS_ERR(new_dentry)) {
15036 +                               nd->dentry = new_dentry;
15037 +                               dput(old_dentry);
15038 +                       } else
15039 +                               error = PTR_ERR(new_dentry);
15040 +               } else {
15041 +                       inode->i_flags &= ~(S_IUNLINK|S_IMMUTABLE);
15042 +                       inode->i_ctime = CURRENT_TIME;
15043 +                       mark_inode_dirty(inode);
15044 +               }
15045 +       }
15046 +       return error;
15047 +}
15048 +
15049 +#else
15050 +#warning duplicate inclusion
15051 +#endif
15052 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_cvirt.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_cvirt.h
15053 --- linux-2.6.19.1/include/linux/vs_cvirt.h     1970-01-01 01:00:00 +0100
15054 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_cvirt.h   2006-11-30 19:12:40 +0100
15055 @@ -0,0 +1,49 @@
15056 +#ifndef _VS_CVIRT_H
15057 +#define _VS_CVIRT_H
15058 +
15059 +#include "vserver/cvirt.h"
15060 +#include "vserver/context.h"
15061 +#include "vserver/base.h"
15062 +#include "vserver/debug.h"
15063 +
15064 +
15065 +static inline void vx_activate_task(struct task_struct *p)
15066 +{
15067 +       struct vx_info *vxi;
15068 +
15069 +       if ((vxi = p->vx_info)) {
15070 +               vx_update_load(vxi);
15071 +               atomic_inc(&vxi->cvirt.nr_running);
15072 +       }
15073 +}
15074 +
15075 +static inline void vx_deactivate_task(struct task_struct *p)
15076 +{
15077 +       struct vx_info *vxi;
15078 +
15079 +       if ((vxi = p->vx_info)) {
15080 +               vx_update_load(vxi);
15081 +               atomic_dec(&vxi->cvirt.nr_running);
15082 +       }
15083 +}
15084 +
15085 +static inline void vx_uninterruptible_inc(struct task_struct *p)
15086 +{
15087 +       struct vx_info *vxi;
15088 +
15089 +       if ((vxi = p->vx_info))
15090 +               atomic_inc(&vxi->cvirt.nr_uninterruptible);
15091 +}
15092 +
15093 +static inline void vx_uninterruptible_dec(struct task_struct *p)
15094 +{
15095 +       struct vx_info *vxi;
15096 +
15097 +       if ((vxi = p->vx_info))
15098 +               atomic_dec(&vxi->cvirt.nr_uninterruptible);
15099 +}
15100 +
15101 +
15102 +#else
15103 +#warning duplicate inclusion
15104 +#endif
15105 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_dlimit.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_dlimit.h
15106 --- linux-2.6.19.1/include/linux/vs_dlimit.h    1970-01-01 01:00:00 +0100
15107 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_dlimit.h  2006-12-01 23:37:57 +0100
15108 @@ -0,0 +1,214 @@
15109 +#ifndef _VS_DLIMIT_H
15110 +#define _VS_DLIMIT_H
15111 +
15112 +#include "vserver/dlimit.h"
15113 +#include "vserver/base.h"
15114 +#include "vserver/debug.h"
15115 +
15116 +
15117 +#define get_dl_info(i) __get_dl_info(i,__FILE__,__LINE__)
15118 +
15119 +static inline struct dl_info *__get_dl_info(struct dl_info *dli,
15120 +       const char *_file, int _line)
15121 +{
15122 +       if (!dli)
15123 +               return NULL;
15124 +       vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
15125 +               dli, dli?dli->dl_tag:0, dli?atomic_read(&dli->dl_usecnt):0,
15126 +               _file, _line);
15127 +       atomic_inc(&dli->dl_usecnt);
15128 +       return dli;
15129 +}
15130 +
15131 +
15132 +#define free_dl_info(i) \
15133 +       call_rcu(&i->dl_rcu, rcu_free_dl_info);
15134 +
15135 +#define put_dl_info(i) __put_dl_info(i,__FILE__,__LINE__)
15136 +
15137 +static inline void __put_dl_info(struct dl_info *dli,
15138 +       const char *_file, int _line)
15139 +{
15140 +       if (!dli)
15141 +               return;
15142 +       vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
15143 +               dli, dli?dli->dl_tag:0, dli?atomic_read(&dli->dl_usecnt):0,
15144 +               _file, _line);
15145 +       if (atomic_dec_and_test(&dli->dl_usecnt))
15146 +               free_dl_info(dli);
15147 +}
15148 +
15149 +
15150 +#define __dlimit_char(d)       ((d)?'*':' ')
15151 +
15152 +static inline int __dl_alloc_space(struct super_block *sb,
15153 +       tag_t tag, dlsize_t nr, const char *file, int line)
15154 +{
15155 +       struct dl_info *dli = NULL;
15156 +       int ret = 0;
15157 +
15158 +       if (nr == 0)
15159 +               goto out;
15160 +       dli = locate_dl_info(sb, tag);
15161 +       if (!dli)
15162 +               goto out;
15163 +
15164 +       spin_lock(&dli->dl_lock);
15165 +       ret = (dli->dl_space_used + nr > dli->dl_space_total);
15166 +       if (!ret)
15167 +               dli->dl_space_used += nr;
15168 +       spin_unlock(&dli->dl_lock);
15169 +       put_dl_info(dli);
15170 +out:
15171 +       vxlprintk(VXD_CBIT(dlim, 1),
15172 +               "ALLOC (%p,#%d)%c %lld bytes (%d)",
15173 +               sb, tag, __dlimit_char(dli), (long long)nr,
15174 +               ret, file, line);
15175 +       return ret;
15176 +}
15177 +
15178 +static inline void __dl_free_space(struct super_block *sb,
15179 +       tag_t tag, dlsize_t nr, const char *_file, int _line)
15180 +{
15181 +       struct dl_info *dli = NULL;
15182 +
15183 +       if (nr == 0)
15184 +               goto out;
15185 +       dli = locate_dl_info(sb, tag);
15186 +       if (!dli)
15187 +               goto out;
15188 +
15189 +       spin_lock(&dli->dl_lock);
15190 +       if (dli->dl_space_used > nr)
15191 +               dli->dl_space_used -= nr;
15192 +       else
15193 +               dli->dl_space_used = 0;
15194 +       spin_unlock(&dli->dl_lock);
15195 +       put_dl_info(dli);
15196 +out:
15197 +       vxlprintk(VXD_CBIT(dlim, 1),
15198 +               "FREE  (%p,#%d)%c %lld bytes",
15199 +               sb, tag, __dlimit_char(dli), (long long)nr,
15200 +               _file, _line);
15201 +}
15202 +
15203 +static inline int __dl_alloc_inode(struct super_block *sb,
15204 +       tag_t tag, const char *_file, int _line)
15205 +{
15206 +       struct dl_info *dli;
15207 +       int ret = 0;
15208 +
15209 +       dli = locate_dl_info(sb, tag);
15210 +       if (!dli)
15211 +               goto out;
15212 +
15213 +       spin_lock(&dli->dl_lock);
15214 +       ret = (dli->dl_inodes_used >= dli->dl_inodes_total);
15215 +       if (!ret)
15216 +               dli->dl_inodes_used++;
15217 +#if 0
15218 +       else
15219 +               vxwprintk("DLIMIT hit (%p,#%d), inode %d>=%d @ %s:%d",
15220 +                       sb, tag,
15221 +                       dli->dl_inodes_used, dli->dl_inodes_total,
15222 +                       file, line);
15223 +#endif
15224 +       spin_unlock(&dli->dl_lock);
15225 +       put_dl_info(dli);
15226 +out:
15227 +       vxlprintk(VXD_CBIT(dlim, 0),
15228 +               "ALLOC (%p,#%d)%c inode (%d)",
15229 +               sb, tag, __dlimit_char(dli), ret, _file, _line);
15230 +       return ret;
15231 +}
15232 +
15233 +static inline void __dl_free_inode(struct super_block *sb,
15234 +       tag_t tag, const char *_file, int _line)
15235 +{
15236 +       struct dl_info *dli;
15237 +
15238 +       dli = locate_dl_info(sb, tag);
15239 +       if (!dli)
15240 +               goto out;
15241 +
15242 +       spin_lock(&dli->dl_lock);
15243 +       if (dli->dl_inodes_used > 1)
15244 +               dli->dl_inodes_used--;
15245 +       else
15246 +               dli->dl_inodes_used = 0;
15247 +       spin_unlock(&dli->dl_lock);
15248 +       put_dl_info(dli);
15249 +out:
15250 +       vxlprintk(VXD_CBIT(dlim, 0),
15251 +               "FREE  (%p,#%d)%c inode",
15252 +               sb, tag, __dlimit_char(dli), _file, _line);
15253 +}
15254 +
15255 +static inline void __dl_adjust_block(struct super_block *sb, tag_t tag,
15256 +       unsigned long long *free_blocks, unsigned long long *root_blocks,
15257 +       const char *_file, int _line)
15258 +{
15259 +       struct dl_info *dli;
15260 +       uint64_t broot, bfree;
15261 +
15262 +       dli = locate_dl_info(sb, tag);
15263 +       if (!dli)
15264 +               return;
15265 +
15266 +       spin_lock(&dli->dl_lock);
15267 +       broot = (dli->dl_space_total -
15268 +               (dli->dl_space_total >> 10) * dli->dl_nrlmult)
15269 +               >> sb->s_blocksize_bits;
15270 +       bfree = (dli->dl_space_total - dli->dl_space_used)
15271 +                       >> sb->s_blocksize_bits;
15272 +       spin_unlock(&dli->dl_lock);
15273 +
15274 +       vxlprintk(VXD_CBIT(dlim, 2),
15275 +               "ADJUST: %lld,%lld on %lld,%lld [mult=%d]",
15276 +               (long long)bfree, (long long)broot,
15277 +               *free_blocks, *root_blocks, dli->dl_nrlmult,
15278 +               _file, _line);
15279 +       if (free_blocks) {
15280 +               if (*free_blocks > bfree)
15281 +                       *free_blocks = bfree;
15282 +       }
15283 +       if (root_blocks) {
15284 +               if (*root_blocks > broot)
15285 +                       *root_blocks = broot;
15286 +       }
15287 +       put_dl_info(dli);
15288 +}
15289 +
15290 +#define DLIMIT_ALLOC_SPACE(in, bytes) \
15291 +       __dl_alloc_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
15292 +               __FILE__, __LINE__ )
15293 +
15294 +#define DLIMIT_FREE_SPACE(in, bytes) \
15295 +       __dl_free_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
15296 +               __FILE__, __LINE__ )
15297 +
15298 +#define DLIMIT_ALLOC_BLOCK(in, nr) \
15299 +       __dl_alloc_space((in)->i_sb, (in)->i_tag, \
15300 +               ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
15301 +               __FILE__, __LINE__ )
15302 +
15303 +#define DLIMIT_FREE_BLOCK(in, nr) \
15304 +       __dl_free_space((in)->i_sb, (in)->i_tag, \
15305 +               ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
15306 +               __FILE__, __LINE__ )
15307 +
15308 +
15309 +#define DLIMIT_ALLOC_INODE(in) \
15310 +       __dl_alloc_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
15311 +
15312 +#define DLIMIT_FREE_INODE(in) \
15313 +       __dl_free_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
15314 +
15315 +
15316 +#define DLIMIT_ADJUST_BLOCK(sb, tag, fb, rb) \
15317 +       __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
15318 +
15319 +
15320 +#else
15321 +#warning duplicate inclusion
15322 +#endif
15323 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_inet.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_inet.h
15324 --- linux-2.6.19.1/include/linux/vs_inet.h      1970-01-01 01:00:00 +0100
15325 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_inet.h    2006-12-17 03:46:17 +0100
15326 @@ -0,0 +1,155 @@
15327 +#ifndef _VS_INET_H
15328 +#define _VS_INET_H
15329 +
15330 +#include <linux/vs_network.h>
15331 +
15332 +#define IPI_LOOPBACK   htonl(INADDR_LOOPBACK)
15333 +
15334 +
15335 +static inline int addr_in_nx_info(struct nx_info *nxi, uint32_t addr)
15336 +{
15337 +       int n,i;
15338 +
15339 +       if (!nxi)
15340 +               return 1;
15341 +
15342 +       n = nxi->nbipv4;
15343 +       if (n && (nxi->ipv4[0] == 0))
15344 +               return 1;
15345 +       for (i=0; i<n; i++) {
15346 +               if (nxi->ipv4[i] == addr)
15347 +                       return 1;
15348 +       }
15349 +       return 0;
15350 +}
15351 +
15352 +
15353 +/*
15354 + *     Check if a given address matches for a socket
15355 + *
15356 + *     nxi:            the socket's nx_info if any
15357 + *     addr:           to be verified address
15358 + *     saddr/baddr:    socket addresses
15359 + */
15360 +static inline int raw_addr_match (
15361 +       struct nx_info *nxi,
15362 +       uint32_t addr,
15363 +       uint32_t saddr,
15364 +       uint32_t baddr)
15365 +{
15366 +       if (addr && (saddr == addr || baddr == addr))
15367 +               return 1;
15368 +       if (!saddr)
15369 +               return addr_in_nx_info(nxi, addr);
15370 +       return 0;
15371 +}
15372 +
15373 +
15374 +/* inet related checks and helpers */
15375 +
15376 +
15377 +struct in_ifaddr;
15378 +struct net_device;
15379 +struct sock;
15380 +
15381 +#ifdef CONFIG_INET
15382 +
15383 +#include <linux/netdevice.h>
15384 +#include <linux/inetdevice.h>
15385 +#include <net/inet_timewait_sock.h>
15386 +
15387 +
15388 +int dev_in_nx_info(struct net_device *, struct nx_info *);
15389 +int nx_addr_conflict(struct nx_info *, uint32_t, struct sock *);
15390 +
15391 +
15392 +/*
15393 + *     check if address is covered by socket
15394 + *
15395 + *     sk:     the socket to check against
15396 + *     addr:   the address in question (must be != 0)
15397 + */
15398 +
15399 +static inline
15400 +int __addr_in_socket(struct sock *sk, uint32_t addr)
15401 +{
15402 +       struct nx_info *nxi = sk->sk_nx_info;
15403 +       uint32_t saddr = inet_rcv_saddr(sk);
15404 +
15405 +       vxdprintk(VXD_CBIT(net, 5),
15406 +               "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx",
15407 +               sk, VXD_QUAD(addr), nxi, VXD_QUAD(saddr), sk->sk_socket,
15408 +               (sk->sk_socket?sk->sk_socket->flags:0));
15409 +
15410 +       if (saddr) {
15411 +               /* direct address match */
15412 +               return (saddr == addr);
15413 +       } else if (nxi) {
15414 +               /* match against nx_info */
15415 +               return addr_in_nx_info(nxi, addr);
15416 +       } else {
15417 +               /* unrestricted any socket */
15418 +               return 1;
15419 +       }
15420 +}
15421 +
15422 +
15423 +
15424 +static inline
15425 +int nx_dev_visible(struct nx_info *nxi, struct net_device *dev)
15426 +{
15427 +       if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
15428 +               return 1;
15429 +       if (dev_in_nx_info(dev, nxi))
15430 +               return 1;
15431 +       return 0;
15432 +}
15433 +
15434 +
15435 +static inline
15436 +int ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
15437 +{
15438 +       if (!nxi)
15439 +               return 1;
15440 +       if (!ifa)
15441 +               return 0;
15442 +       return addr_in_nx_info(nxi, ifa->ifa_local);
15443 +}
15444 +
15445 +static inline
15446 +int nx_ifa_visible(struct nx_info *nxi, struct in_ifaddr *ifa)
15447 +{
15448 +       if (!nx_info_flags(nxi, NXF_HIDE_NETIF, 0))
15449 +               return 1;
15450 +       if (ifa_in_nx_info(ifa, nxi))
15451 +               return 1;
15452 +       return 0;
15453 +}
15454 +
15455 +#else /* CONFIG_INET */
15456 +
15457 +static inline
15458 +int nx_dev_visible(struct nx_info *n, struct net_device *d)
15459 +{
15460 +       return 1;
15461 +}
15462 +
15463 +
15464 +static inline
15465 +int nx_addr_conflict(struct nx_info *n, uint32_t a, struct sock *s)
15466 +{
15467 +       return 1;
15468 +}
15469 +
15470 +static inline
15471 +int ifa_in_nx_info(struct in_ifaddr *a, struct nx_info *n)
15472 +{
15473 +       return 1;
15474 +}
15475 +
15476 +#endif /* CONFIG_INET */
15477 +
15478 +
15479 +#else
15480 +#warning duplicate inclusion
15481 +#endif
15482 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_limit.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_limit.h
15483 --- linux-2.6.19.1/include/linux/vs_limit.h     1970-01-01 01:00:00 +0100
15484 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_limit.h   2006-11-30 18:53:18 +0100
15485 @@ -0,0 +1,140 @@
15486 +#ifndef _VS_LIMIT_H
15487 +#define _VS_LIMIT_H
15488 +
15489 +#include "vserver/limit.h"
15490 +#include "vserver/base.h"
15491 +#include "vserver/context.h"
15492 +#include "vserver/debug.h"
15493 +#include "vserver/context.h"
15494 +#include "vserver/limit_int.h"
15495 +
15496 +
15497 +#define vx_acc_cres(v,d,p,r) \
15498 +       __vx_acc_cres(v, r, d, p, __FILE__, __LINE__)
15499 +
15500 +#define vx_acc_cres_cond(x,d,p,r) \
15501 +       __vx_acc_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \
15502 +       r, d, p, __FILE__, __LINE__)
15503 +
15504 +
15505 +#define vx_add_cres(v,a,p,r) \
15506 +       __vx_add_cres(v, r, a, p, __FILE__, __LINE__)
15507 +#define vx_sub_cres(v,a,p,r)           vx_add_cres(v,-(a),p,r)
15508 +
15509 +#define vx_add_cres_cond(x,a,p,r) \
15510 +       __vx_add_cres(((x) == vx_current_xid()) ? current->vx_info : 0, \
15511 +       r, a, p, __FILE__, __LINE__)
15512 +#define vx_sub_cres_cond(x,a,p,r)      vx_add_cres_cond(x,-(a),p,r)
15513 +
15514 +
15515 +/* process and file limits */
15516 +
15517 +#define vx_nproc_inc(p) \
15518 +       vx_acc_cres((p)->vx_info, 1, p, RLIMIT_NPROC)
15519 +
15520 +#define vx_nproc_dec(p) \
15521 +       vx_acc_cres((p)->vx_info,-1, p, RLIMIT_NPROC)
15522 +
15523 +#define vx_files_inc(f) \
15524 +       vx_acc_cres_cond((f)->f_xid, 1, f, RLIMIT_NOFILE)
15525 +
15526 +#define vx_files_dec(f) \
15527 +       vx_acc_cres_cond((f)->f_xid,-1, f, RLIMIT_NOFILE)
15528 +
15529 +#define vx_locks_inc(l) \
15530 +       vx_acc_cres_cond((l)->fl_xid, 1, l, RLIMIT_LOCKS)
15531 +
15532 +#define vx_locks_dec(l) \
15533 +       vx_acc_cres_cond((l)->fl_xid,-1, l, RLIMIT_LOCKS)
15534 +
15535 +#define vx_openfd_inc(f) \
15536 +       vx_acc_cres(current->vx_info, 1, (void *)(long)(f), VLIMIT_OPENFD)
15537 +
15538 +#define vx_openfd_dec(f) \
15539 +       vx_acc_cres(current->vx_info,-1, (void *)(long)(f), VLIMIT_OPENFD)
15540 +
15541 +
15542 +#define vx_cres_avail(v,n,r) \
15543 +       __vx_cres_avail(v, r, n, __FILE__, __LINE__)
15544 +
15545 +
15546 +#define vx_nproc_avail(n) \
15547 +       vx_cres_avail(current->vx_info, n, RLIMIT_NPROC)
15548 +
15549 +#define vx_files_avail(n) \
15550 +       vx_cres_avail(current->vx_info, n, RLIMIT_NOFILE)
15551 +
15552 +#define vx_locks_avail(n) \
15553 +       vx_cres_avail(current->vx_info, n, RLIMIT_LOCKS)
15554 +
15555 +#define vx_openfd_avail(n) \
15556 +       vx_cres_avail(current->vx_info, n, VLIMIT_OPENFD)
15557 +
15558 +
15559 +/* dentry limits */
15560 +
15561 +#define vx_dentry_inc(d) do {                                          \
15562 +       if (atomic_read(&d->d_count) == 1)                              \
15563 +               vx_acc_cres(current->vx_info, 1, d, VLIMIT_DENTRY);     \
15564 +       } while (0)
15565 +
15566 +#define vx_dentry_dec(d) do {                                          \
15567 +       if (atomic_read(&d->d_count) == 0)                              \
15568 +               vx_acc_cres(current->vx_info,-1, d, VLIMIT_DENTRY);     \
15569 +       } while (0)
15570 +
15571 +#define vx_dentry_avail(n) \
15572 +       vx_cres_avail(current->vx_info, n, VLIMIT_DENTRY)
15573 +
15574 +
15575 +/* socket limits */
15576 +
15577 +#define vx_sock_inc(s) \
15578 +       vx_acc_cres((s)->sk_vx_info, 1, s, VLIMIT_NSOCK)
15579 +
15580 +#define vx_sock_dec(s) \
15581 +       vx_acc_cres((s)->sk_vx_info,-1, s, VLIMIT_NSOCK)
15582 +
15583 +#define vx_sock_avail(n) \
15584 +       vx_cres_avail(current->vx_info, n, VLIMIT_NSOCK)
15585 +
15586 +
15587 +/* ipc resource limits */
15588 +
15589 +#define vx_ipcmsg_add(v,u,a) \
15590 +       vx_add_cres(v, a, u, RLIMIT_MSGQUEUE)
15591 +
15592 +#define vx_ipcmsg_sub(v,u,a) \
15593 +       vx_sub_cres(v, a, u, RLIMIT_MSGQUEUE)
15594 +
15595 +#define vx_ipcmsg_avail(v,a) \
15596 +       vx_cres_avail(v, a, RLIMIT_MSGQUEUE)
15597 +
15598 +
15599 +#define vx_ipcshm_add(v,k,a) \
15600 +       vx_add_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
15601 +
15602 +#define vx_ipcshm_sub(v,k,a) \
15603 +       vx_sub_cres(v, a, (void *)(long)(k), VLIMIT_SHMEM)
15604 +
15605 +#define vx_ipcshm_avail(v,a) \
15606 +       vx_cres_avail(v, a, VLIMIT_SHMEM)
15607 +
15608 +
15609 +#define vx_semary_inc(a) \
15610 +       vx_acc_cres(current->vx_info, 1, a, VLIMIT_SEMARY)
15611 +
15612 +#define vx_semary_dec(a) \
15613 +       vx_acc_cres(current->vx_info,-1, a, VLIMIT_SEMARY)
15614 +
15615 +
15616 +#define vx_nsems_add(a,n) \
15617 +       vx_add_cres(current->vx_info, n, a, VLIMIT_NSEMS)
15618 +
15619 +#define vx_nsems_sub(a,n) \
15620 +       vx_sub_cres(current->vx_info, n, a, VLIMIT_NSEMS)
15621 +
15622 +
15623 +#else
15624 +#warning duplicate inclusion
15625 +#endif
15626 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_memory.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_memory.h
15627 --- linux-2.6.19.1/include/linux/vs_memory.h    1970-01-01 01:00:00 +0100
15628 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_memory.h  2006-11-30 19:31:41 +0100
15629 @@ -0,0 +1,159 @@
15630 +#ifndef _VS_MEMORY_H
15631 +#define _VS_MEMORY_H
15632 +
15633 +#include "vserver/limit.h"
15634 +#include "vserver/base.h"
15635 +#include "vserver/context.h"
15636 +#include "vserver/debug.h"
15637 +#include "vserver/context.h"
15638 +#include "vserver/limit_int.h"
15639 +
15640 +
15641 +#define __acc_add_long(a,v)    (*(v) += (a))
15642 +#define __acc_inc_long(v)      (++*(v))
15643 +#define __acc_dec_long(v)      (--*(v))
15644 +
15645 +#if    NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
15646 +#define __acc_add_atomic(a,v)  atomic_long_add(a,v)
15647 +#define __acc_inc_atomic(v)    atomic_long_inc(v)
15648 +#define __acc_dec_atomic(v)    atomic_long_dec(v)
15649 +#else  /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
15650 +#define __acc_add_atomic(a,v)  __acc_add_long(a,v)
15651 +#define __acc_inc_atomic(v)    __acc_inc_long(v)
15652 +#define __acc_dec_atomic(v)    __acc_dec_long(v)
15653 +#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
15654 +
15655 +
15656 +#define vx_acc_page(m,d,v,r) do {                                      \
15657 +       if ((d) > 0)                                                    \
15658 +               __acc_inc_long(&(m->v));                                \
15659 +       else                                                            \
15660 +               __acc_dec_long(&(m->v));                                \
15661 +       __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__);      \
15662 +} while (0)
15663 +
15664 +#define vx_acc_page_atomic(m,d,v,r) do {                               \
15665 +       if ((d) > 0)                                                    \
15666 +               __acc_inc_atomic(&(m->v));                              \
15667 +       else                                                            \
15668 +               __acc_dec_atomic(&(m->v));                              \
15669 +       __vx_acc_cres(m->mm_vx_info, r, d, m, __FILE__, __LINE__);      \
15670 +} while (0)
15671 +
15672 +
15673 +#define vx_acc_pages(m,p,v,r) do {                                     \
15674 +       unsigned long __p = (p);                                        \
15675 +       __acc_add_long(__p, &(m->v));                                   \
15676 +       __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__);    \
15677 +} while (0)
15678 +
15679 +#define vx_acc_pages_atomic(m,p,v,r) do {                              \
15680 +       unsigned long __p = (p);                                        \
15681 +       __acc_add_atomic(__p, &(m->v));                                 \
15682 +       __vx_add_cres(m->mm_vx_info, r, __p, m, __FILE__, __LINE__);    \
15683 +} while (0)
15684 +
15685 +
15686 +
15687 +#define vx_acc_vmpage(m,d) \
15688 +       vx_acc_page(m, d, total_vm,  RLIMIT_AS)
15689 +#define vx_acc_vmlpage(m,d) \
15690 +       vx_acc_page(m, d, locked_vm, RLIMIT_MEMLOCK)
15691 +#define vx_acc_file_rsspage(m,d) \
15692 +       vx_acc_page_atomic(m, d, _file_rss, VLIMIT_MAPPED)
15693 +#define vx_acc_anon_rsspage(m,d) \
15694 +       vx_acc_page_atomic(m, d, _anon_rss, VLIMIT_ANON)
15695 +
15696 +#define vx_acc_vmpages(m,p) \
15697 +       vx_acc_pages(m, p, total_vm,  RLIMIT_AS)
15698 +#define vx_acc_vmlpages(m,p) \
15699 +       vx_acc_pages(m, p, locked_vm, RLIMIT_MEMLOCK)
15700 +#define vx_acc_file_rsspages(m,p) \
15701 +       vx_acc_pages_atomic(m, p, _file_rss, VLIMIT_MAPPED)
15702 +#define vx_acc_anon_rsspages(m,p) \
15703 +       vx_acc_pages_atomic(m, p, _anon_rss, VLIMIT_ANON)
15704 +
15705 +#define vx_pages_add(s,r,p)    __vx_add_cres(s, r, p, 0, __FILE__, __LINE__)
15706 +#define vx_pages_sub(s,r,p)    vx_pages_add(s, r, -(p))
15707 +
15708 +#define vx_vmpages_inc(m)              vx_acc_vmpage(m, 1)
15709 +#define vx_vmpages_dec(m)              vx_acc_vmpage(m,-1)
15710 +#define vx_vmpages_add(m,p)            vx_acc_vmpages(m, p)
15711 +#define vx_vmpages_sub(m,p)            vx_acc_vmpages(m,-(p))
15712 +
15713 +#define vx_vmlocked_inc(m)             vx_acc_vmlpage(m, 1)
15714 +#define vx_vmlocked_dec(m)             vx_acc_vmlpage(m,-1)
15715 +#define vx_vmlocked_add(m,p)           vx_acc_vmlpages(m, p)
15716 +#define vx_vmlocked_sub(m,p)           vx_acc_vmlpages(m,-(p))
15717 +
15718 +#define vx_file_rsspages_inc(m)                vx_acc_file_rsspage(m, 1)
15719 +#define vx_file_rsspages_dec(m)                vx_acc_file_rsspage(m,-1)
15720 +#define vx_file_rsspages_add(m,p)      vx_acc_file_rsspages(m, p)
15721 +#define vx_file_rsspages_sub(m,p)      vx_acc_file_rsspages(m,-(p))
15722 +
15723 +#define vx_anon_rsspages_inc(m)                vx_acc_anon_rsspage(m, 1)
15724 +#define vx_anon_rsspages_dec(m)                vx_acc_anon_rsspage(m,-1)
15725 +#define vx_anon_rsspages_add(m,p)      vx_acc_anon_rsspages(m, p)
15726 +#define vx_anon_rsspages_sub(m,p)      vx_acc_anon_rsspages(m,-(p))
15727 +
15728 +
15729 +#define vx_pages_avail(m,p,r) \
15730 +       __vx_cres_avail((m)->mm_vx_info, r, p, __FILE__, __LINE__)
15731 +
15732 +#define vx_vmpages_avail(m,p)  vx_pages_avail(m, p, RLIMIT_AS)
15733 +#define vx_vmlocked_avail(m,p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)
15734 +#define vx_anon_avail(m,p)     vx_pages_avail(m, p, VLIMIT_ANON)
15735 +#define vx_mapped_avail(m,p)   vx_pages_avail(m, p, VLIMIT_MAPPED)
15736 +
15737 +#define vx_rss_avail(m,p) \
15738 +       __vx_cres_array_avail((m)->mm_vx_info, VLA_RSS, p, __FILE__, __LINE__)
15739 +
15740 +
15741 +enum {
15742 +       VXPT_UNKNOWN = 0,
15743 +       VXPT_ANON,
15744 +       VXPT_NONE,
15745 +       VXPT_FILE,
15746 +       VXPT_SWAP,
15747 +       VXPT_WRITE
15748 +};
15749 +
15750 +#if 0
15751 +#define        vx_page_fault(mm,vma,type,ret)
15752 +#else
15753 +
15754 +static inline
15755 +void __vx_page_fault(struct mm_struct *mm,
15756 +       struct vm_area_struct *vma, int type, int ret)
15757 +{
15758 +       struct vx_info *vxi = mm->mm_vx_info;
15759 +       int what;
15760 +/*
15761 +       static char *page_type[6] =
15762 +               { "UNKNOWN", "ANON","NONE", "FILE", "SWAP", "WRITE" };
15763 +       static char *page_what[4] =
15764 +               { "FAULT_OOM", "FAULT_SIGBUS", "FAULT_MINOR", "FAULT_MAJOR" };
15765 +*/
15766 +
15767 +       if (!vxi)
15768 +               return;
15769 +
15770 +       what = (ret & 0x3);
15771 +
15772 +/*     printk("[%d] page[%d][%d] %2x %s %s\n", vxi->vx_id,
15773 +               type, what, ret, page_type[type], page_what[what]);
15774 +*/
15775 +       if (ret & VM_FAULT_WRITE)
15776 +               what |= 0x4;
15777 +       atomic_inc(&vxi->cacct.page[type][what]);
15778 +}
15779 +
15780 +#define        vx_page_fault(mm,vma,type,ret)  __vx_page_fault(mm,vma,type,ret)
15781 +#endif
15782 +
15783 +
15784 +extern unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm);
15785 +
15786 +#else
15787 +#warning duplicate inclusion
15788 +#endif
15789 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_network.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_network.h
15790 --- linux-2.6.19.1/include/linux/vs_network.h   1970-01-01 01:00:00 +0100
15791 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_network.h 2006-12-17 03:46:02 +0100
15792 @@ -0,0 +1,165 @@
15793 +#ifndef _NX_VS_NETWORK_H
15794 +#define _NX_VS_NETWORK_H
15795 +
15796 +#include "vserver/context.h"
15797 +#include "vserver/network.h"
15798 +#include "vserver/base.h"
15799 +#include "vserver/debug.h"
15800 +
15801 +
15802 +#define get_nx_info(i) __get_nx_info(i,__FILE__,__LINE__)
15803 +
15804 +static inline struct nx_info *__get_nx_info(struct nx_info *nxi,
15805 +       const char *_file, int _line)
15806 +{
15807 +       if (!nxi)
15808 +               return NULL;
15809 +
15810 +       vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
15811 +               nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0,
15812 +               _file, _line);
15813 +
15814 +       atomic_inc(&nxi->nx_usecnt);
15815 +       return nxi;
15816 +}
15817 +
15818 +
15819 +extern void free_nx_info(struct nx_info *);
15820 +
15821 +#define put_nx_info(i) __put_nx_info(i,__FILE__,__LINE__)
15822 +
15823 +static inline void __put_nx_info(struct nx_info *nxi, const char *_file, int _line)
15824 +{
15825 +       if (!nxi)
15826 +               return;
15827 +
15828 +       vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
15829 +               nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0,
15830 +               _file, _line);
15831 +
15832 +       if (atomic_dec_and_test(&nxi->nx_usecnt))
15833 +               free_nx_info(nxi);
15834 +}
15835 +
15836 +
15837 +#define init_nx_info(p,i) __init_nx_info(p,i,__FILE__,__LINE__)
15838 +
15839 +static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
15840 +               const char *_file, int _line)
15841 +{
15842 +       if (nxi) {
15843 +               vxlprintk(VXD_CBIT(nid, 3),
15844 +                       "init_nx_info(%p[#%d.%d])",
15845 +                       nxi, nxi?nxi->nx_id:0,
15846 +                       nxi?atomic_read(&nxi->nx_usecnt):0,
15847 +                       _file, _line);
15848 +
15849 +               atomic_inc(&nxi->nx_usecnt);
15850 +       }
15851 +       *nxp = nxi;
15852 +}
15853 +
15854 +
15855 +#define set_nx_info(p,i) __set_nx_info(p,i,__FILE__,__LINE__)
15856 +
15857 +static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
15858 +       const char *_file, int _line)
15859 +{
15860 +       struct nx_info *nxo;
15861 +
15862 +       if (!nxi)
15863 +               return;
15864 +
15865 +       vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
15866 +               nxi, nxi?nxi->nx_id:0,
15867 +               nxi?atomic_read(&nxi->nx_usecnt):0,
15868 +               _file, _line);
15869 +
15870 +       atomic_inc(&nxi->nx_usecnt);
15871 +       nxo = xchg(nxp, nxi);
15872 +       BUG_ON(nxo);
15873 +}
15874 +
15875 +#define clr_nx_info(p) __clr_nx_info(p,__FILE__,__LINE__)
15876 +
15877 +static inline void __clr_nx_info(struct nx_info **nxp,
15878 +       const char *_file, int _line)
15879 +{
15880 +       struct nx_info *nxo;
15881 +
15882 +       nxo = xchg(nxp, NULL);
15883 +       if (!nxo)
15884 +               return;
15885 +
15886 +       vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
15887 +               nxo, nxo?nxo->nx_id:0,
15888 +               nxo?atomic_read(&nxo->nx_usecnt):0,
15889 +               _file, _line);
15890 +
15891 +       if (atomic_dec_and_test(&nxo->nx_usecnt))
15892 +               free_nx_info(nxo);
15893 +}
15894 +
15895 +
15896 +#define claim_nx_info(v,p) __claim_nx_info(v,p,__FILE__,__LINE__)
15897 +
15898 +static inline void __claim_nx_info(struct nx_info *nxi,
15899 +       struct task_struct *task, const char *_file, int _line)
15900 +{
15901 +       vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
15902 +               nxi, nxi?nxi->nx_id:0,
15903 +               nxi?atomic_read(&nxi->nx_usecnt):0,
15904 +               nxi?atomic_read(&nxi->nx_tasks):0,
15905 +               task, _file, _line);
15906 +
15907 +       atomic_inc(&nxi->nx_tasks);
15908 +}
15909 +
15910 +
15911 +extern void unhash_nx_info(struct nx_info *);
15912 +
15913 +#define release_nx_info(v,p) __release_nx_info(v,p,__FILE__,__LINE__)
15914 +
15915 +static inline void __release_nx_info(struct nx_info *nxi,
15916 +       struct task_struct *task, const char *_file, int _line)
15917 +{
15918 +       vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
15919 +               nxi, nxi?nxi->nx_id:0,
15920 +               nxi?atomic_read(&nxi->nx_usecnt):0,
15921 +               nxi?atomic_read(&nxi->nx_tasks):0,
15922 +               task, _file, _line);
15923 +
15924 +       might_sleep();
15925 +
15926 +       if (atomic_dec_and_test(&nxi->nx_tasks))
15927 +               unhash_nx_info(nxi);
15928 +}
15929 +
15930 +
15931 +#define task_get_nx_info(i)    __task_get_nx_info(i,__FILE__,__LINE__)
15932 +
15933 +static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
15934 +       const char *_file, int _line)
15935 +{
15936 +       struct nx_info *nxi;
15937 +
15938 +       task_lock(p);
15939 +       vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
15940 +               p, _file, _line);
15941 +       nxi = __get_nx_info(p->nx_info, _file, _line);
15942 +       task_unlock(p);
15943 +       return nxi;
15944 +}
15945 +
15946 +
15947 +
15948 +static inline void exit_nx_info(struct task_struct *p)
15949 +{
15950 +       if (p->nx_info)
15951 +               release_nx_info(p->nx_info, p);
15952 +}
15953 +
15954 +
15955 +#else
15956 +#warning duplicate inclusion
15957 +#endif
15958 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_pid.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_pid.h
15959 --- linux-2.6.19.1/include/linux/vs_pid.h       1970-01-01 01:00:00 +0100
15960 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_pid.h     2006-12-04 05:21:53 +0100
15961 @@ -0,0 +1,108 @@
15962 +#ifndef _VS_PID_H
15963 +#define _VS_PID_H
15964 +
15965 +#include "vserver/base.h"
15966 +#include "vserver/context.h"
15967 +#include "vserver/debug.h"
15968 +
15969 +
15970 +/* pid faking stuff */
15971 +
15972 +
15973 +#define vx_info_map_pid(v,p) \
15974 +       __vx_info_map_pid((v), (p), __FUNC__, __FILE__, __LINE__)
15975 +#define vx_info_map_tgid(v,p)  vx_info_map_pid(v,p)
15976 +#define vx_map_pid(p)  vx_info_map_pid(current->vx_info, p)
15977 +#define vx_map_tgid(p) vx_map_pid(p)
15978 +
15979 +static inline int __vx_info_map_pid(struct vx_info *vxi, int pid,
15980 +       const char *func, const char *file, int line)
15981 +{
15982 +       if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
15983 +               vxfprintk(VXD_CBIT(cvirt, 2),
15984 +                       "vx_map_tgid: %p/%llx: %d -> %d",
15985 +                       vxi, (long long)vxi->vx_flags, pid,
15986 +                       (pid && pid == vxi->vx_initpid)?1:pid,
15987 +                       func, file, line);
15988 +               if (pid == 0)
15989 +                       return 0;
15990 +               if (pid == vxi->vx_initpid)
15991 +                       return 1;
15992 +       }
15993 +       return pid;
15994 +}
15995 +
15996 +#define vx_info_rmap_pid(v,p) \
15997 +       __vx_info_rmap_pid((v), (p), __FUNC__, __FILE__, __LINE__)
15998 +#define vx_rmap_pid(p) vx_info_rmap_pid(current->vx_info, p)
15999 +#define vx_rmap_tgid(p) vx_rmap_pid(p)
16000 +
16001 +static inline int __vx_info_rmap_pid(struct vx_info *vxi, int pid,
16002 +       const char *func, const char *file, int line)
16003 +{
16004 +       if (vx_info_flags(vxi, VXF_INFO_INIT, 0)) {
16005 +               vxfprintk(VXD_CBIT(cvirt, 2),
16006 +                       "vx_rmap_tgid: %p/%llx: %d -> %d",
16007 +                       vxi, (long long)vxi->vx_flags, pid,
16008 +                       (pid == 1)?vxi->vx_initpid:pid,
16009 +                       func, file, line);
16010 +               if ((pid == 1) && vxi->vx_initpid)
16011 +                       return vxi->vx_initpid;
16012 +               if (pid == vxi->vx_initpid)
16013 +                       return ~0U;
16014 +       }
16015 +       return pid;
16016 +}
16017 +
16018 +
16019 +#define VXF_FAKE_INIT  (VXF_INFO_INIT|VXF_STATE_INIT)
16020 +
16021 +static inline
16022 +int vx_proc_task_visible(struct task_struct *task)
16023 +{
16024 +       if ((task->pid == 1) &&
16025 +               !vx_flags(VXF_FAKE_INIT, VXF_FAKE_INIT))
16026 +               /* show a blend through init */
16027 +               goto visible;
16028 +       if (vx_check(vx_task_xid(task), VS_WATCH|VS_IDENT))
16029 +               goto visible;
16030 +       return 0;
16031 +visible:
16032 +       return 1;
16033 +}
16034 +
16035 +static inline
16036 +struct task_struct *vx_find_proc_task_by_pid(int pid)
16037 +{
16038 +       struct task_struct *task = find_task_by_pid(pid);
16039 +
16040 +       if (task && !vx_proc_task_visible(task)) {
16041 +               vxdprintk(VXD_CBIT(misc, 6),
16042 +                       "dropping task (find) %p[#%u,%u] for %p[#%u,%u]",
16043 +                       task, task->xid, task->pid,
16044 +                       current, current->xid, current->pid);
16045 +               task = NULL;
16046 +       }
16047 +       return task;
16048 +}
16049 +
16050 +static inline
16051 +struct task_struct *vx_get_proc_task(struct inode *inode, struct pid *pid)
16052 +{
16053 +       struct task_struct *task = get_pid_task(pid, PIDTYPE_PID);
16054 +
16055 +       if (task && !vx_proc_task_visible(task)) {
16056 +               vxdprintk(VXD_CBIT(misc, 6),
16057 +                       "dropping task (get) %p[#%u,%u] for %p[#%u,%u]",
16058 +                       task, task->xid, task->pid,
16059 +                       current, current->xid, current->pid);
16060 +               put_task_struct(task);
16061 +               task = NULL;
16062 +       }
16063 +       return task;
16064 +}
16065 +
16066 +
16067 +#else
16068 +#warning duplicate inclusion
16069 +#endif
16070 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_sched.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_sched.h
16071 --- linux-2.6.19.1/include/linux/vs_sched.h     1970-01-01 01:00:00 +0100
16072 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_sched.h   2006-11-30 18:53:18 +0100
16073 @@ -0,0 +1,109 @@
16074 +#ifndef _VS_SCHED_H
16075 +#define _VS_SCHED_H
16076 +
16077 +#include "vserver/base.h"
16078 +#include "vserver/context.h"
16079 +#include "vserver/sched.h"
16080 +
16081 +
16082 +#define VAVAVOOM_RATIO          50
16083 +
16084 +#define MAX_PRIO_BIAS           20
16085 +#define MIN_PRIO_BIAS          -20
16086 +
16087 +
16088 +#ifdef CONFIG_VSERVER_HARDCPU
16089 +
16090 +/*
16091 + * effective_prio - return the priority that is based on the static
16092 + * priority but is modified by bonuses/penalties.
16093 + *
16094 + * We scale the actual sleep average [0 .... MAX_SLEEP_AVG]
16095 + * into a -4 ... 0 ... +4 bonus/penalty range.
16096 + *
16097 + * Additionally, we scale another amount based on the number of
16098 + * CPU tokens currently held by the context, if the process is
16099 + * part of a context (and the appropriate SCHED flag is set).
16100 + * This ranges from -5 ... 0 ... +15, quadratically.
16101 + *
16102 + * So, the total bonus is -9 .. 0 .. +19
16103 + * We use ~50% of the full 0...39 priority range so that:
16104 + *
16105 + * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs.
16106 + * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks.
16107 + *    unless that context is far exceeding its CPU allocation.
16108 + *
16109 + * Both properties are important to certain workloads.
16110 + */
16111 +static inline
16112 +int vx_effective_vavavoom(struct _vx_sched_pc *sched_pc, int max_prio)
16113 +{
16114 +       int vavavoom, max;
16115 +
16116 +       /* lots of tokens = lots of vavavoom
16117 +        *      no tokens = no vavavoom      */
16118 +       if ((vavavoom = sched_pc->tokens) >= 0) {
16119 +               max = sched_pc->tokens_max;
16120 +               vavavoom = max - vavavoom;
16121 +               max = max * max;
16122 +               vavavoom = max_prio * VAVAVOOM_RATIO / 100
16123 +                       * (vavavoom*vavavoom - (max >> 2)) / max;
16124 +               return vavavoom;
16125 +       }
16126 +       return 0;
16127 +}
16128 +
16129 +
16130 +static inline
16131 +int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
16132 +{
16133 +       struct vx_info *vxi = p->vx_info;
16134 +
16135 +       if (!vxi)
16136 +               return prio;
16137 +
16138 +       if (vx_info_flags(vxi, VXF_SCHED_PRIO, 0)) {
16139 +               struct _vx_sched_pc *sched_pc = &vx_cpu(vxi, sched_pc);
16140 +               int vavavoom = vx_effective_vavavoom(sched_pc, max_user);
16141 +
16142 +               vxi->sched.vavavoom = vavavoom;
16143 +               prio += vavavoom;
16144 +       }
16145 +       prio += vxi->sched.prio_bias;
16146 +       return prio;
16147 +}
16148 +
16149 +#else /* !CONFIG_VSERVER_HARDCPU */
16150 +
16151 +static inline
16152 +int vx_adjust_prio(struct task_struct *p, int prio, int max_user)
16153 +{
16154 +       struct vx_info *vxi = p->vx_info;
16155 +
16156 +       if (vxi)
16157 +               prio += vxi->sched.prio_bias;
16158 +       return prio;
16159 +}
16160 +
16161 +#endif /* CONFIG_VSERVER_HARDCPU */
16162 +
16163 +
16164 +static inline void vx_account_user(struct vx_info *vxi,
16165 +       cputime_t cputime, int nice)
16166 +{
16167 +       if (!vxi)
16168 +               return;
16169 +       vx_cpu(vxi, sched_pc).user_ticks += cputime;
16170 +}
16171 +
16172 +static inline void vx_account_system(struct vx_info *vxi,
16173 +       cputime_t cputime, int idle)
16174 +{
16175 +       if (!vxi)
16176 +               return;
16177 +       vx_cpu(vxi, sched_pc).sys_ticks += cputime;
16178 +}
16179 +
16180 +#else
16181 +#warning duplicate inclusion
16182 +#endif
16183 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_socket.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_socket.h
16184 --- linux-2.6.19.1/include/linux/vs_socket.h    1970-01-01 01:00:00 +0100
16185 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_socket.h  2006-11-30 19:13:42 +0100
16186 @@ -0,0 +1,67 @@
16187 +#ifndef _VS_SOCKET_H
16188 +#define _VS_SOCKET_H
16189 +
16190 +#include "vserver/debug.h"
16191 +#include "vserver/base.h"
16192 +#include "vserver/cacct.h"
16193 +#include "vserver/context.h"
16194 +
16195 +
16196 +/* socket accounting */
16197 +
16198 +#include <linux/socket.h>
16199 +
16200 +static inline int vx_sock_type(int family)
16201 +{
16202 +       switch (family) {
16203 +       case PF_UNSPEC:
16204 +               return VXA_SOCK_UNSPEC;
16205 +       case PF_UNIX:
16206 +               return VXA_SOCK_UNIX;
16207 +       case PF_INET:
16208 +               return VXA_SOCK_INET;
16209 +       case PF_INET6:
16210 +               return VXA_SOCK_INET6;
16211 +       case PF_PACKET:
16212 +               return VXA_SOCK_PACKET;
16213 +       default:
16214 +               return VXA_SOCK_OTHER;
16215 +       }
16216 +}
16217 +
16218 +#define vx_acc_sock(v,f,p,s) \
16219 +       __vx_acc_sock((v), (f), (p), (s), __FILE__, __LINE__)
16220 +
16221 +static inline void __vx_acc_sock(struct vx_info *vxi,
16222 +       int family, int pos, int size, char *file, int line)
16223 +{
16224 +       if (vxi) {
16225 +               int type = vx_sock_type(family);
16226 +
16227 +               atomic_inc(&vxi->cacct.sock[type][pos].count);
16228 +               atomic_add(size, &vxi->cacct.sock[type][pos].total);
16229 +       }
16230 +}
16231 +
16232 +#define vx_sock_recv(sk,s) \
16233 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, (s))
16234 +#define vx_sock_send(sk,s) \
16235 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, (s))
16236 +#define vx_sock_fail(sk,s) \
16237 +       vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, (s))
16238 +
16239 +
16240 +#define sock_vx_init(s) do {           \
16241 +       (s)->sk_xid = 0;                \
16242 +       (s)->sk_vx_info = NULL;         \
16243 +       } while (0)
16244 +
16245 +#define sock_nx_init(s) do {           \
16246 +       (s)->sk_nid = 0;                \
16247 +       (s)->sk_nx_info = NULL;         \
16248 +       } while (0)
16249 +
16250 +
16251 +#else
16252 +#warning duplicate inclusion
16253 +#endif
16254 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_tag.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_tag.h
16255 --- linux-2.6.19.1/include/linux/vs_tag.h       1970-01-01 01:00:00 +0100
16256 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_tag.h     2006-11-30 18:53:18 +0100
16257 @@ -0,0 +1,44 @@
16258 +#ifndef _VS_TAG_H
16259 +#define _VS_TAG_H
16260 +
16261 +#include <linux/vserver/tag.h>
16262 +
16263 +/* check conditions */
16264 +
16265 +#define DX_ADMIN       0x0001
16266 +#define DX_WATCH       0x0002
16267 +#define DX_HOSTID      0x0008
16268 +
16269 +#define DX_IDENT       0x0010
16270 +
16271 +#define DX_ARG_MASK    0x0010
16272 +
16273 +
16274 +#define dx_task_tag(t) ((t)->xid)
16275 +
16276 +#define dx_current_tag() dx_task_tag(current)
16277 +
16278 +#define dx_check(c,m)  __dx_check(dx_current_tag(),c,m)
16279 +
16280 +#define dx_weak_check(c,m)     ((m) ? dx_check(c,m) : 1)
16281 +
16282 +
16283 +/*
16284 + * check current context for ADMIN/WATCH and
16285 + * optionally against supplied argument
16286 + */
16287 +static inline int __dx_check(tag_t cid, tag_t id, unsigned int mode)
16288 +{
16289 +       if (mode & DX_ARG_MASK) {
16290 +               if ((mode & DX_IDENT) &&
16291 +                       (id == cid))
16292 +                       return 1;
16293 +       }
16294 +       return (((mode & DX_ADMIN) && (cid == 0)) ||
16295 +               ((mode & DX_WATCH) && (cid == 1)) ||
16296 +               ((mode & DX_HOSTID) && (id == 0)));
16297 +}
16298 +
16299 +#else
16300 +#warning duplicate inclusion
16301 +#endif
16302 diff -NurpP --minimal linux-2.6.19.1/include/linux/vs_time.h linux-2.6.19.1-vs2.3.0.6/include/linux/vs_time.h
16303 --- linux-2.6.19.1/include/linux/vs_time.h      1970-01-01 01:00:00 +0100
16304 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vs_time.h    2006-11-30 18:53:18 +0100
16305 @@ -0,0 +1,19 @@
16306 +#ifndef _VS_TIME_H
16307 +#define _VS_TIME_H
16308 +
16309 +
16310 +/* time faking stuff */
16311 +
16312 +#ifdef CONFIG_VSERVER_VTIME
16313 +
16314 +extern void vx_gettimeofday(struct timeval *tv);
16315 +extern int vx_settimeofday(struct timespec *ts);
16316 +
16317 +#else
16318 +#define        vx_gettimeofday(t)      do_gettimeofday(t)
16319 +#define        vx_settimeofday(t)      do_settimeofday(t)
16320 +#endif
16321 +
16322 +#else
16323 +#warning duplicate inclusion
16324 +#endif
16325 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/Kbuild linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/Kbuild
16326 --- linux-2.6.19.1/include/linux/vserver/Kbuild 1970-01-01 01:00:00 +0100
16327 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/Kbuild       2006-12-17 04:40:51 +0100
16328 @@ -0,0 +1,7 @@
16329 +
16330 +unifdef-y += context_cmd.h network_cmd.h space_cmd.h \
16331 +       cacct_cmd.h cvirt_cmd.h limit_cmd.h dlimit_cmd.h \
16332 +       inode_cmd.h sched_cmd.h signal_cmd.h debug_cmd.h
16333 +
16334 +unifdef-y += switch.h network.h monitor.h
16335 +
16336 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/base.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/base.h
16337 --- linux-2.6.19.1/include/linux/vserver/base.h 1970-01-01 01:00:00 +0100
16338 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/base.h       2006-12-17 05:26:45 +0100
16339 @@ -0,0 +1,217 @@
16340 +#ifndef _VX_BASE_H
16341 +#define _VX_BASE_H
16342 +
16343 +
16344 +/* context state changes */
16345 +
16346 +enum {
16347 +       VSC_STARTUP = 1,
16348 +       VSC_SHUTDOWN,
16349 +
16350 +       VSC_NETUP,
16351 +       VSC_NETDOWN,
16352 +};
16353 +
16354 +
16355 +#define MAX_S_CONTEXT  65535   /* Arbitrary limit */
16356 +
16357 +/* check conditions */
16358 +
16359 +#define VS_ADMIN       0x0001
16360 +#define VS_WATCH       0x0002
16361 +#define VS_HIDE                0x0004
16362 +#define VS_HOSTID      0x0008
16363 +
16364 +#define VS_IDENT       0x0010
16365 +#define VS_EQUIV       0x0020
16366 +#define VS_PARENT      0x0040
16367 +#define VS_CHILD       0x0080
16368 +
16369 +#define VS_ARG_MASK    0x00F0
16370 +
16371 +#ifdef CONFIG_VSERVER_PRIVACY
16372 +#define VS_ADMIN_P     (0)
16373 +#define VS_WATCH_P     (0)
16374 +#else
16375 +#define VS_ADMIN_P     VS_ADMIN
16376 +#define VS_WATCH_P     VS_WATCH
16377 +#endif
16378 +
16379 +#define VS_HARDIRQ     0x1000
16380 +#define VS_SOFTIRQ     0x2000
16381 +#define VS_IRQ         0x4000
16382 +
16383 +#define VS_IRQ_MASK    0xF000
16384 +
16385 +#include <linux/hardirq.h>
16386 +
16387 +/*
16388 + * check current context for ADMIN/WATCH and
16389 + * optionally against supplied argument
16390 + */
16391 +static inline int __vs_check(int cid, int id, unsigned int mode)
16392 +{
16393 +       if (mode & VS_ARG_MASK) {
16394 +               if ((mode & VS_IDENT) &&
16395 +                       (id == cid))
16396 +                       return 1;
16397 +       }
16398 +       if (mode & VS_IRQ_MASK) {
16399 +               if ((mode & VS_IRQ) && unlikely(in_interrupt()))
16400 +                       return 1;
16401 +               if ((mode & VS_HARDIRQ) && unlikely(in_irq()))
16402 +                       return 1;
16403 +               if ((mode & VS_SOFTIRQ) && unlikely(in_softirq()))
16404 +                       return 1;
16405 +       }
16406 +       return (((mode & VS_ADMIN) && (cid == 0)) ||
16407 +               ((mode & VS_WATCH) && (cid == 1)) ||
16408 +               ((mode & VS_HOSTID) && (id == 0)));
16409 +}
16410 +
16411 +#define vx_task_xid(t) ((t)->xid)
16412 +
16413 +#define vx_current_xid() vx_task_xid(current)
16414 +
16415 +#define current_vx_info() (current->vx_info)
16416 +
16417 +
16418 +#define vx_check(c,m)  __vs_check(vx_current_xid(),c,(m)|VS_IRQ)
16419 +
16420 +#define vx_weak_check(c,m)     ((m) ? vx_check(c,m) : 1)
16421 +
16422 +
16423 +#define nx_task_nid(t) ((t)->nid)
16424 +
16425 +#define nx_current_nid() nx_task_nid(current)
16426 +
16427 +#define current_nx_info() (current->nx_info)
16428 +
16429 +
16430 +#define nx_check(c,m)  __vs_check(nx_current_nid(),c,m)
16431 +
16432 +#define nx_weak_check(c,m)     ((m) ? nx_check(c,m) : 1)
16433 +
16434 +
16435 +
16436 +/* generic flag merging */
16437 +
16438 +#define vs_check_flags(v,m,f)  (((v) & (m)) ^ (f))
16439 +
16440 +#define vs_mask_flags(v,f,m)   (((v) & ~(m)) | ((f) & (m)))
16441 +
16442 +#define vs_mask_mask(v,f,m)    (((v) & ~(m)) | ((v) & (f) & (m)))
16443 +
16444 +#define vs_check_bit(v,n)      ((v) & (1LL << (n)))
16445 +
16446 +
16447 +/* context flags */
16448 +
16449 +#define __vx_flags(v)  ((v) ? (v)->vx_flags : 0)
16450 +
16451 +#define vx_current_flags()     __vx_flags(current->vx_info)
16452 +
16453 +#define vx_info_flags(v,m,f) \
16454 +       vs_check_flags(__vx_flags(v),(m),(f))
16455 +
16456 +#define task_vx_flags(t,m,f) \
16457 +       ((t) && vx_info_flags((t)->vx_info, (m), (f)))
16458 +
16459 +#define vx_flags(m,f)  vx_info_flags(current->vx_info,(m),(f))
16460 +
16461 +
16462 +/* context caps */
16463 +
16464 +#define __vx_ccaps(v)  ((v) ? (v)->vx_ccaps : 0)
16465 +
16466 +#define vx_current_ccaps()     __vx_ccaps(current->vx_info)
16467 +
16468 +#define vx_info_ccaps(v,c)     (__vx_ccaps(v) & (c))
16469 +
16470 +#define vx_ccaps(c)    vx_info_ccaps(current->vx_info,(c))
16471 +
16472 +
16473 +
16474 +/* network flags */
16475 +
16476 +#define __nx_flags(v)  ((v) ? (v)->nx_flags : 0)
16477 +
16478 +#define nx_current_flags()     __nx_flags(current->nx_info)
16479 +
16480 +#define nx_info_flags(v,m,f) \
16481 +       vs_check_flags(__nx_flags(v),(m),(f))
16482 +
16483 +#define task_nx_flags(t,m,f) \
16484 +       ((t) && nx_info_flags((t)->nx_info, (m), (f)))
16485 +
16486 +#define nx_flags(m,f)  nx_info_flags(current->nx_info,(m),(f))
16487 +
16488 +
16489 +/* network caps */
16490 +
16491 +#define __nx_ncaps(v)  ((v) ? (v)->nx_ncaps : 0)
16492 +
16493 +#define nx_current_ncaps()     __nx_ncaps(current->nx_info)
16494 +
16495 +#define nx_info_ncaps(v,c)     (__nx_ncaps(v) & (c))
16496 +
16497 +#define nx_ncaps(c)    nx_info_ncaps(current->nx_info,(c))
16498 +
16499 +
16500 +/* context mask capabilities */
16501 +
16502 +#define __vx_mcaps(v)  ((v) ? (v)->vx_ccaps >> 32UL : ~0 )
16503 +
16504 +#define vx_info_mcaps(v,c)     (__vx_mcaps(v) & (c))
16505 +
16506 +#define vx_mcaps(c)    vx_info_mcaps(current->vx_info,(c))
16507 +
16508 +
16509 +/* context bcap mask */
16510 +
16511 +#define __vx_bcaps(v)  ((v) ? (v)->vx_bcaps : ~0 )
16512 +
16513 +#define vx_current_bcaps()     __vx_bcaps(current->vx_info)
16514 +
16515 +#define vx_info_bcaps(v,c)     (__vx_bcaps(v) & (c))
16516 +
16517 +#define vx_bcaps(c)    vx_info_bcaps(current->vx_info,(c))
16518 +
16519 +
16520 +#define vx_info_cap_bset(v)    ((v) ? (v)->vx_cap_bset : cap_bset)
16521 +
16522 +#define vx_current_cap_bset()  vx_info_cap_bset(current->vx_info)
16523 +
16524 +
16525 +#define __vx_info_mbcap(v,b) \
16526 +       (!vx_info_flags(v, VXF_STATE_SETUP, 0) ? \
16527 +       vx_info_bcaps(v, b) : (b))
16528 +
16529 +#define vx_info_mbcap(v,b)     __vx_info_mbcap(v,cap_t(b))
16530 +
16531 +#define task_vx_mbcap(t,b) \
16532 +       vx_info_mbcap((t)->vx_info, (t)->b)
16533 +
16534 +#define vx_mbcap(b)    task_vx_mbcap(current,b)
16535 +
16536 +#define vx_cap_raised(v,c,f)   (vx_info_mbcap(v,c) & CAP_TO_MASK(f))
16537 +
16538 +#define vx_capable(b,c) (capable(b) || \
16539 +       (cap_raised(current->cap_effective,b) && vx_ccaps(c)))
16540 +
16541 +
16542 +#define vx_current_initpid(n) \
16543 +       (current->vx_info && \
16544 +       (current->vx_info->vx_initpid == (n)))
16545 +
16546 +
16547 +#define __vx_state(v)  ((v) ? ((v)->vx_state) : 0)
16548 +
16549 +#define vx_info_state(v,m)     (__vx_state(v) & (m))
16550 +
16551 +
16552 +#define __nx_state(v)  ((v) ? ((v)->nx_state) : 0)
16553 +
16554 +#define nx_info_state(v,m)     (__nx_state(v) & (m))
16555 +
16556 +#endif
16557 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cacct.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct.h
16558 --- linux-2.6.19.1/include/linux/vserver/cacct.h        1970-01-01 01:00:00 +0100
16559 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct.h      2006-11-08 04:57:44 +0100
16560 @@ -0,0 +1,15 @@
16561 +#ifndef _VX_CACCT_H
16562 +#define _VX_CACCT_H
16563 +
16564 +
16565 +enum sock_acc_field {
16566 +       VXA_SOCK_UNSPEC = 0,
16567 +       VXA_SOCK_UNIX,
16568 +       VXA_SOCK_INET,
16569 +       VXA_SOCK_INET6,
16570 +       VXA_SOCK_PACKET,
16571 +       VXA_SOCK_OTHER,
16572 +       VXA_SOCK_SIZE   /* array size */
16573 +};
16574 +
16575 +#endif /* _VX_CACCT_H */
16576 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cacct_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_cmd.h
16577 --- linux-2.6.19.1/include/linux/vserver/cacct_cmd.h    1970-01-01 01:00:00 +0100
16578 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_cmd.h  2006-11-08 04:57:49 +0100
16579 @@ -0,0 +1,23 @@
16580 +#ifndef _VX_CACCT_CMD_H
16581 +#define _VX_CACCT_CMD_H
16582 +
16583 +
16584 +/* virtual host info name commands */
16585 +
16586 +#define VCMD_sock_stat         VC_CMD(VSTAT, 5, 0)
16587 +
16588 +struct vcmd_sock_stat_v0 {
16589 +       uint32_t field;
16590 +       uint32_t count[3];
16591 +       uint64_t total[3];
16592 +};
16593 +
16594 +
16595 +#ifdef __KERNEL__
16596 +
16597 +#include <linux/compiler.h>
16598 +
16599 +extern int vc_sock_stat(struct vx_info *, void __user *);
16600 +
16601 +#endif /* __KERNEL__ */
16602 +#endif /* _VX_CACCT_CMD_H */
16603 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cacct_def.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_def.h
16604 --- linux-2.6.19.1/include/linux/vserver/cacct_def.h    1970-01-01 01:00:00 +0100
16605 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_def.h  2006-11-08 04:57:49 +0100
16606 @@ -0,0 +1,43 @@
16607 +#ifndef _VX_CACCT_DEF_H
16608 +#define _VX_CACCT_DEF_H
16609 +
16610 +#include <asm/atomic.h>
16611 +#include <linux/vserver/cacct.h>
16612 +
16613 +
16614 +struct _vx_sock_acc {
16615 +       atomic_t count;
16616 +       atomic_t total;
16617 +};
16618 +
16619 +/* context sub struct */
16620 +
16621 +struct _vx_cacct {
16622 +       struct _vx_sock_acc sock[VXA_SOCK_SIZE][3];
16623 +       atomic_t slab[8];
16624 +       atomic_t page[6][8];
16625 +};
16626 +
16627 +#ifdef CONFIG_VSERVER_DEBUG
16628 +
16629 +static inline void __dump_vx_cacct(struct _vx_cacct *cacct)
16630 +{
16631 +       int i,j;
16632 +
16633 +       printk("\t_vx_cacct:");
16634 +       for (i=0; i<6; i++) {
16635 +               struct _vx_sock_acc *ptr = cacct->sock[i];
16636 +
16637 +               printk("\t [%d] =", i);
16638 +               for (j=0; j<3; j++) {
16639 +                       printk(" [%d] = %8d, %8d", j,
16640 +                               atomic_read(&ptr[j].count),
16641 +                               atomic_read(&ptr[j].total));
16642 +               }
16643 +               printk("\n");
16644 +       }
16645 +}
16646 +
16647 +#endif
16648 +
16649 +#endif /* _VX_CACCT_DEF_H */
16650 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cacct_int.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_int.h
16651 --- linux-2.6.19.1/include/linux/vserver/cacct_int.h    1970-01-01 01:00:00 +0100
16652 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cacct_int.h  2006-11-08 04:57:44 +0100
16653 @@ -0,0 +1,21 @@
16654 +#ifndef _VX_CACCT_INT_H
16655 +#define _VX_CACCT_INT_H
16656 +
16657 +
16658 +#ifdef __KERNEL__
16659 +
16660 +static inline
16661 +unsigned long vx_sock_count(struct _vx_cacct *cacct, int type, int pos)
16662 +{
16663 +       return atomic_read(&cacct->sock[type][pos].count);
16664 +}
16665 +
16666 +
16667 +static inline
16668 +unsigned long vx_sock_total(struct _vx_cacct *cacct, int type, int pos)
16669 +{
16670 +       return atomic_read(&cacct->sock[type][pos].total);
16671 +}
16672 +
16673 +#endif /* __KERNEL__ */
16674 +#endif /* _VX_CACCT_INT_H */
16675 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/context.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/context.h
16676 --- linux-2.6.19.1/include/linux/vserver/context.h      1970-01-01 01:00:00 +0100
16677 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/context.h    2006-12-17 05:24:26 +0100
16678 @@ -0,0 +1,170 @@
16679 +#ifndef _VX_CONTEXT_H
16680 +#define _VX_CONTEXT_H
16681 +
16682 +#include <linux/types.h>
16683 +#include <linux/capability.h>
16684 +
16685 +
16686 +/* context flags */
16687 +
16688 +#define VXF_INFO_SCHED         0x00000002
16689 +#define VXF_INFO_NPROC         0x00000004
16690 +#define VXF_INFO_PRIVATE       0x00000008
16691 +
16692 +#define VXF_INFO_INIT          0x00000010
16693 +#define VXF_INFO_HIDE          0x00000020
16694 +#define VXF_INFO_ULIMIT                0x00000040
16695 +#define VXF_INFO_NSPACE                0x00000080
16696 +
16697 +#define VXF_SCHED_HARD         0x00000100
16698 +#define VXF_SCHED_PRIO         0x00000200
16699 +#define VXF_SCHED_PAUSE                0x00000400
16700 +
16701 +#define VXF_VIRT_MEM           0x00010000
16702 +#define VXF_VIRT_UPTIME                0x00020000
16703 +#define VXF_VIRT_CPU           0x00040000
16704 +#define VXF_VIRT_LOAD          0x00080000
16705 +#define VXF_VIRT_TIME          0x00100000
16706 +
16707 +#define VXF_HIDE_MOUNT         0x01000000
16708 +/* was VXF_HIDE_NETIF          0x02000000 */
16709 +#define VXF_HIDE_VINFO         0x04000000
16710 +
16711 +#define VXF_STATE_SETUP                (1ULL<<32)
16712 +#define VXF_STATE_INIT         (1ULL<<33)
16713 +#define VXF_STATE_ADMIN                (1ULL<<34)
16714 +
16715 +#define VXF_SC_HELPER          (1ULL<<36)
16716 +#define VXF_REBOOT_KILL                (1ULL<<37)
16717 +#define VXF_PERSISTENT         (1ULL<<38)
16718 +
16719 +#define VXF_FORK_RSS           (1ULL<<48)
16720 +#define VXF_PROLIFIC           (1ULL<<49)
16721 +
16722 +#define VXF_IGNEG_NICE         (1ULL<<52)
16723 +
16724 +#define VXF_ONE_TIME           (0x0007ULL<<32)
16725 +
16726 +#define VXF_INIT_SET           (VXF_STATE_SETUP|VXF_STATE_INIT|VXF_STATE_ADMIN)
16727 +
16728 +
16729 +/* context migration */
16730 +
16731 +#define VXM_SET_INIT           0x00000001
16732 +#define VXM_SET_REAPER         0x00000002
16733 +
16734 +/* context caps */
16735 +
16736 +#define VXC_CAP_MASK           0x00000000
16737 +
16738 +#define VXC_SET_UTSNAME                0x00000001
16739 +#define VXC_SET_RLIMIT         0x00000002
16740 +
16741 +#define VXC_RAW_ICMP           0x00000100
16742 +#define VXC_SYSLOG             0x00001000
16743 +
16744 +#define VXC_SECURE_MOUNT       0x00010000
16745 +#define VXC_SECURE_REMOUNT     0x00020000
16746 +#define VXC_BINARY_MOUNT       0x00040000
16747 +
16748 +#define VXC_QUOTA_CTL          0x00100000
16749 +#define VXC_ADMIN_MAPPER       0x00200000
16750 +#define VXC_ADMIN_CLOOP                0x00400000
16751 +
16752 +
16753 +#ifdef __KERNEL__
16754 +
16755 +#include <linux/list.h>
16756 +#include <linux/spinlock.h>
16757 +#include <linux/rcupdate.h>
16758 +
16759 +#include "limit_def.h"
16760 +#include "sched_def.h"
16761 +#include "cvirt_def.h"
16762 +#include "cacct_def.h"
16763 +
16764 +struct _vx_info_pc {
16765 +       struct _vx_sched_pc sched_pc;
16766 +       struct _vx_cvirt_pc cvirt_pc;
16767 +};
16768 +
16769 +struct vx_info {
16770 +       struct hlist_node vx_hlist;             /* linked list of contexts */
16771 +       xid_t vx_id;                            /* context id */
16772 +       atomic_t vx_usecnt;                     /* usage count */
16773 +       atomic_t vx_tasks;                      /* tasks count */
16774 +       struct vx_info *vx_parent;              /* parent context */
16775 +       int vx_state;                           /* context state */
16776 +
16777 +       unsigned long vx_nsmask;                /* assignment mask */
16778 +       struct nsproxy *vx_nsproxy;             /* private namespace */
16779 +       struct fs_struct *vx_fs;                /* private namespace fs */
16780 +
16781 +       uint64_t vx_flags;                      /* context flags */
16782 +       uint64_t vx_bcaps;                      /* bounding caps (system) */
16783 +       uint64_t vx_ccaps;                      /* context caps (vserver) */
16784 +       kernel_cap_t vx_cap_bset;               /* the guest's bset */
16785 +
16786 +       struct task_struct *vx_reaper;          /* guest reaper process */
16787 +       pid_t vx_initpid;                       /* PID of guest init */
16788 +
16789 +       struct _vx_limit limit;                 /* vserver limits */
16790 +       struct _vx_sched sched;                 /* vserver scheduler */
16791 +       struct _vx_cvirt cvirt;                 /* virtual/bias stuff */
16792 +       struct _vx_cacct cacct;                 /* context accounting */
16793 +
16794 +#ifndef CONFIG_SMP
16795 +       struct _vx_info_pc info_pc;             /* per cpu data */
16796 +#else
16797 +       struct _vx_info_pc *ptr_pc;             /* per cpu array */
16798 +#endif
16799 +
16800 +       wait_queue_head_t vx_wait;              /* context exit waitqueue */
16801 +       int reboot_cmd;                         /* last sys_reboot() cmd */
16802 +       int exit_code;                          /* last process exit code */
16803 +
16804 +       char vx_name[65];                       /* vserver name */
16805 +};
16806 +
16807 +#ifndef CONFIG_SMP
16808 +#define        vx_ptr_pc(vxi)          (&(vxi)->info_pc)
16809 +#define        vx_per_cpu(vxi, v, id)  vx_ptr_pc(vxi)->v
16810 +#else
16811 +#define        vx_ptr_pc(vxi)          ((vxi)->ptr_pc)
16812 +#define        vx_per_cpu(vxi, v, id)  per_cpu_ptr(vx_ptr_pc(vxi), id)->v
16813 +#endif
16814 +
16815 +#define        vx_cpu(vxi, v)          vx_per_cpu(vxi, v, smp_processor_id())
16816 +
16817 +
16818 +struct vx_info_save {
16819 +       struct vx_info *vxi;
16820 +       xid_t xid;
16821 +};
16822 +
16823 +
16824 +/* status flags */
16825 +
16826 +#define VXS_HASHED     0x0001
16827 +#define VXS_PAUSED     0x0010
16828 +#define VXS_SHUTDOWN   0x0100
16829 +#define VXS_HELPER     0x1000
16830 +#define VXS_RELEASED   0x8000
16831 +
16832 +
16833 +extern void claim_vx_info(struct vx_info *, struct task_struct *);
16834 +extern void release_vx_info(struct vx_info *, struct task_struct *);
16835 +
16836 +extern struct vx_info *lookup_vx_info(int);
16837 +extern struct vx_info *lookup_or_create_vx_info(int);
16838 +
16839 +extern int get_xid_list(int, unsigned int *, int);
16840 +extern int xid_is_hashed(xid_t);
16841 +
16842 +extern int vx_migrate_task(struct task_struct *, struct vx_info *, int);
16843 +
16844 +extern long vs_state_change(struct vx_info *, unsigned int);
16845 +
16846 +
16847 +#endif /* __KERNEL__ */
16848 +#endif /* _VX_CONTEXT_H */
16849 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/context_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/context_cmd.h
16850 --- linux-2.6.19.1/include/linux/vserver/context_cmd.h  1970-01-01 01:00:00 +0100
16851 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/context_cmd.h        2006-11-08 04:57:49 +0100
16852 @@ -0,0 +1,123 @@
16853 +#ifndef _VX_CONTEXT_CMD_H
16854 +#define _VX_CONTEXT_CMD_H
16855 +
16856 +
16857 +/* vinfo commands */
16858 +
16859 +#define VCMD_task_xid          VC_CMD(VINFO, 1, 0)
16860 +
16861 +#ifdef __KERNEL__
16862 +extern int vc_task_xid(uint32_t, void __user *);
16863 +
16864 +#endif /* __KERNEL__ */
16865 +
16866 +#define VCMD_vx_info           VC_CMD(VINFO, 5, 0)
16867 +
16868 +struct vcmd_vx_info_v0 {
16869 +       uint32_t xid;
16870 +       uint32_t initpid;
16871 +       /* more to come */
16872 +};
16873 +
16874 +#ifdef __KERNEL__
16875 +extern int vc_vx_info(struct vx_info *, void __user *);
16876 +
16877 +#endif /* __KERNEL__ */
16878 +
16879 +#define VCMD_ctx_stat          VC_CMD(VSTAT, 0, 0)
16880 +
16881 +struct vcmd_ctx_stat_v0 {
16882 +       uint32_t usecnt;
16883 +       uint32_t tasks;
16884 +       /* more to come */
16885 +};
16886 +
16887 +#ifdef __KERNEL__
16888 +extern int vc_ctx_stat(struct vx_info *, void __user *);
16889 +
16890 +#endif /* __KERNEL__ */
16891 +
16892 +/* context commands */
16893 +
16894 +#define VCMD_ctx_create_v0     VC_CMD(VPROC, 1, 0)
16895 +#define VCMD_ctx_create                VC_CMD(VPROC, 1, 1)
16896 +
16897 +struct vcmd_ctx_create {
16898 +       uint64_t flagword;
16899 +};
16900 +
16901 +#define VCMD_ctx_migrate_v0    VC_CMD(PROCMIG, 1, 0)
16902 +#define VCMD_ctx_migrate       VC_CMD(PROCMIG, 1, 1)
16903 +
16904 +struct vcmd_ctx_migrate {
16905 +       uint64_t flagword;
16906 +};
16907 +
16908 +#ifdef __KERNEL__
16909 +extern int vc_ctx_create(uint32_t, void __user *);
16910 +extern int vc_ctx_migrate(struct vx_info *, void __user *);
16911 +
16912 +#endif /* __KERNEL__ */
16913 +
16914 +
16915 +/* flag commands */
16916 +
16917 +#define VCMD_get_cflags                VC_CMD(FLAGS, 1, 0)
16918 +#define VCMD_set_cflags                VC_CMD(FLAGS, 2, 0)
16919 +
16920 +struct vcmd_ctx_flags_v0 {
16921 +       uint64_t flagword;
16922 +       uint64_t mask;
16923 +};
16924 +
16925 +#ifdef __KERNEL__
16926 +extern int vc_get_cflags(struct vx_info *, void __user *);
16927 +extern int vc_set_cflags(struct vx_info *, void __user *);
16928 +
16929 +#endif /* __KERNEL__ */
16930 +
16931 +
16932 +/* context caps commands */
16933 +
16934 +#define VCMD_get_ccaps_v0      VC_CMD(FLAGS, 3, 0)
16935 +#define VCMD_set_ccaps_v0      VC_CMD(FLAGS, 4, 0)
16936 +
16937 +struct vcmd_ctx_caps_v0 {
16938 +       uint64_t bcaps;
16939 +       uint64_t ccaps;
16940 +       uint64_t cmask;
16941 +};
16942 +
16943 +#define VCMD_get_ccaps         VC_CMD(FLAGS, 3, 1)
16944 +#define VCMD_set_ccaps         VC_CMD(FLAGS, 4, 1)
16945 +
16946 +struct vcmd_ctx_caps_v1 {
16947 +       uint64_t ccaps;
16948 +       uint64_t cmask;
16949 +};
16950 +
16951 +#ifdef __KERNEL__
16952 +extern int vc_get_ccaps_v0(struct vx_info *, void __user *);
16953 +extern int vc_set_ccaps_v0(struct vx_info *, void __user *);
16954 +extern int vc_get_ccaps(struct vx_info *, void __user *);
16955 +extern int vc_set_ccaps(struct vx_info *, void __user *);
16956 +
16957 +#endif /* __KERNEL__ */
16958 +
16959 +
16960 +/* bcaps commands */
16961 +
16962 +#define VCMD_get_bcaps         VC_CMD(FLAGS, 9, 0)
16963 +#define VCMD_set_bcaps         VC_CMD(FLAGS,10, 0)
16964 +
16965 +struct vcmd_bcaps {
16966 +       uint64_t bcaps;
16967 +       uint64_t bmask;
16968 +};
16969 +
16970 +#ifdef __KERNEL__
16971 +extern int vc_get_bcaps(struct vx_info *, void __user *);
16972 +extern int vc_set_bcaps(struct vx_info *, void __user *);
16973 +
16974 +#endif /* __KERNEL__ */
16975 +#endif /* _VX_CONTEXT_CMD_H */
16976 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cvirt.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt.h
16977 --- linux-2.6.19.1/include/linux/vserver/cvirt.h        1970-01-01 01:00:00 +0100
16978 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt.h      2006-11-14 02:23:11 +0100
16979 @@ -0,0 +1,20 @@
16980 +#ifndef _VX_CVIRT_H
16981 +#define _VX_CVIRT_H
16982 +
16983 +
16984 +#ifdef __KERNEL__
16985 +
16986 +struct timespec;
16987 +
16988 +void vx_vsi_uptime(struct timespec *, struct timespec *);
16989 +
16990 +
16991 +struct vx_info;
16992 +
16993 +void vx_update_load(struct vx_info *);
16994 +
16995 +
16996 +int vx_do_syslog(int, char __user *, int);
16997 +
16998 +#endif /* __KERNEL__ */
16999 +#endif /* _VX_CVIRT_H */
17000 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cvirt_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt_cmd.h
17001 --- linux-2.6.19.1/include/linux/vserver/cvirt_cmd.h    1970-01-01 01:00:00 +0100
17002 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt_cmd.h  2006-11-08 04:57:49 +0100
17003 @@ -0,0 +1,53 @@
17004 +#ifndef _VX_CVIRT_CMD_H
17005 +#define _VX_CVIRT_CMD_H
17006 +
17007 +
17008 +/* virtual host info name commands */
17009 +
17010 +#define VCMD_set_vhi_name      VC_CMD(VHOST, 1, 0)
17011 +#define VCMD_get_vhi_name      VC_CMD(VHOST, 2, 0)
17012 +
17013 +struct vcmd_vhi_name_v0 {
17014 +       uint32_t field;
17015 +       char name[65];
17016 +};
17017 +
17018 +
17019 +enum vhi_name_field {
17020 +       VHIN_CONTEXT=0,
17021 +       VHIN_SYSNAME,
17022 +       VHIN_NODENAME,
17023 +       VHIN_RELEASE,
17024 +       VHIN_VERSION,
17025 +       VHIN_MACHINE,
17026 +       VHIN_DOMAINNAME,
17027 +};
17028 +
17029 +
17030 +#ifdef __KERNEL__
17031 +
17032 +#include <linux/compiler.h>
17033 +
17034 +extern int vc_set_vhi_name(struct vx_info *, void __user *);
17035 +extern int vc_get_vhi_name(struct vx_info *, void __user *);
17036 +
17037 +#endif /* __KERNEL__ */
17038 +
17039 +#define VCMD_virt_stat         VC_CMD(VSTAT, 3, 0)
17040 +
17041 +struct vcmd_virt_stat_v0 {
17042 +       uint64_t offset;
17043 +       uint64_t uptime;
17044 +       uint32_t nr_threads;
17045 +       uint32_t nr_running;
17046 +       uint32_t nr_uninterruptible;
17047 +       uint32_t nr_onhold;
17048 +       uint32_t nr_forks;
17049 +       uint32_t load[3];
17050 +};
17051 +
17052 +#ifdef __KERNEL__
17053 +extern int vc_virt_stat(struct vx_info *, void __user *);
17054 +
17055 +#endif /* __KERNEL__ */
17056 +#endif /* _VX_CVIRT_CMD_H */
17057 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/cvirt_def.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt_def.h
17058 --- linux-2.6.19.1/include/linux/vserver/cvirt_def.h    1970-01-01 01:00:00 +0100
17059 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/cvirt_def.h  2006-11-14 00:04:36 +0100
17060 @@ -0,0 +1,82 @@
17061 +#ifndef _VX_CVIRT_DEF_H
17062 +#define _VX_CVIRT_DEF_H
17063 +
17064 +#include <linux/jiffies.h>
17065 +#include <linux/spinlock.h>
17066 +#include <linux/wait.h>
17067 +#include <linux/time.h>
17068 +#include <linux/utsname.h>
17069 +#include <asm/atomic.h>
17070 +
17071 +
17072 +struct _vx_usage_stat {
17073 +       uint64_t user;
17074 +       uint64_t nice;
17075 +       uint64_t system;
17076 +       uint64_t softirq;
17077 +       uint64_t irq;
17078 +       uint64_t idle;
17079 +       uint64_t iowait;
17080 +};
17081 +
17082 +struct _vx_syslog {
17083 +       wait_queue_head_t log_wait;
17084 +       spinlock_t logbuf_lock;         /* lock for the log buffer */
17085 +
17086 +       unsigned long log_start;        /* next char to be read by syslog() */
17087 +       unsigned long con_start;        /* next char to be sent to consoles */
17088 +       unsigned long log_end;  /* most-recently-written-char + 1 */
17089 +       unsigned long logged_chars;     /* #chars since last read+clear operation */
17090 +
17091 +       char log_buf[1024];
17092 +};
17093 +
17094 +
17095 +/* context sub struct */
17096 +
17097 +struct _vx_cvirt {
17098 +//     int max_threads;                /* maximum allowed threads */
17099 +       atomic_t nr_threads;            /* number of current threads */
17100 +       atomic_t nr_running;            /* number of running threads */
17101 +       atomic_t nr_uninterruptible;    /* number of uninterruptible threads */
17102 +
17103 +       atomic_t nr_onhold;             /* processes on hold */
17104 +       uint32_t onhold_last;           /* jiffies when put on hold */
17105 +
17106 +       struct timeval bias_tv;         /* time offset to the host */
17107 +       struct timespec bias_idle;
17108 +       struct timespec bias_uptime;    /* context creation point */
17109 +       uint64_t bias_clock;            /* offset in clock_t */
17110 +
17111 +       spinlock_t load_lock;           /* lock for the load averages */
17112 +       atomic_t load_updates;          /* nr of load updates done so far */
17113 +       uint32_t load_last;             /* last time load was calculated */
17114 +       uint32_t load[3];               /* load averages 1,5,15 */
17115 +
17116 +       atomic_t total_forks;           /* number of forks so far */
17117 +
17118 +       struct _vx_syslog syslog;
17119 +};
17120 +
17121 +struct _vx_cvirt_pc {
17122 +       struct _vx_usage_stat cpustat;
17123 +};
17124 +
17125 +
17126 +#ifdef CONFIG_VSERVER_DEBUG
17127 +
17128 +static inline void __dump_vx_cvirt(struct _vx_cvirt *cvirt)
17129 +{
17130 +       printk("\t_vx_cvirt:\n");
17131 +       printk("\t threads: %4d, %4d, %4d, %4d\n",
17132 +               atomic_read(&cvirt->nr_threads),
17133 +               atomic_read(&cvirt->nr_running),
17134 +               atomic_read(&cvirt->nr_uninterruptible),
17135 +               atomic_read(&cvirt->nr_onhold));
17136 +       /* add rest here */
17137 +       printk("\t total_forks = %d\n", atomic_read(&cvirt->total_forks));
17138 +}
17139 +
17140 +#endif
17141 +
17142 +#endif /* _VX_CVIRT_DEF_H */
17143 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/debug.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/debug.h
17144 --- linux-2.6.19.1/include/linux/vserver/debug.h        1970-01-01 01:00:00 +0100
17145 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/debug.h      2006-11-08 04:57:48 +0100
17146 @@ -0,0 +1,112 @@
17147 +#ifndef _VX_DEBUG_H
17148 +#define _VX_DEBUG_H
17149 +
17150 +
17151 +#define VXD_CBIT(n,m)  (vx_debug_ ## n & (1 << (m)))
17152 +#define VXD_CMIN(n,m)  (vx_debug_ ## n > (m))
17153 +#define VXD_MASK(n,m)  (vx_debug_ ## n & (m))
17154 +
17155 +#define VXD_QPOS(v,p)  (((uint32_t)(v) >> ((p)*8)) & 0xFF)
17156 +#define VXD_QUAD(v)    VXD_QPOS(v,0), VXD_QPOS(v,1),           \
17157 +                       VXD_QPOS(v,2), VXD_QPOS(v,3)
17158 +#define VXF_QUAD       "%u.%u.%u.%u"
17159 +
17160 +#define VXD_DEV(d)     (d), (d)->bd_inode->i_ino,              \
17161 +                       imajor((d)->bd_inode), iminor((d)->bd_inode)
17162 +#define VXF_DEV                "%p[%lu,%d:%d]"
17163 +
17164 +
17165 +#define __FUNC__       __func__
17166 +
17167 +
17168 +#ifdef CONFIG_VSERVER_DEBUG
17169 +
17170 +extern unsigned int vx_debug_switch;
17171 +extern unsigned int vx_debug_xid;
17172 +extern unsigned int vx_debug_nid;
17173 +extern unsigned int vx_debug_tag;
17174 +extern unsigned int vx_debug_net;
17175 +extern unsigned int vx_debug_limit;
17176 +extern unsigned int vx_debug_cres;
17177 +extern unsigned int vx_debug_dlim;
17178 +extern unsigned int vx_debug_quota;
17179 +extern unsigned int vx_debug_cvirt;
17180 +extern unsigned int vx_debug_misc;
17181 +
17182 +
17183 +#define VX_LOGLEVEL    "vxD: "
17184 +#define VX_WARNLEVEL   KERN_WARNING "vxW: "
17185 +
17186 +#define vxdprintk(c,f,x...)                                    \
17187 +       do {                                                    \
17188 +               if (c)                                          \
17189 +                       printk(VX_LOGLEVEL f "\n" , ##x);       \
17190 +       } while (0)
17191 +
17192 +#define vxlprintk(c,f,x...)                                    \
17193 +       do {                                                    \
17194 +               if (c)                                          \
17195 +                       printk(VX_LOGLEVEL f " @%s:%d\n", x);   \
17196 +       } while (0)
17197 +
17198 +#define vxfprintk(c,f,x...)                                    \
17199 +       do {                                                    \
17200 +               if (c)                                          \
17201 +                       printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
17202 +       } while (0)
17203 +
17204 +
17205 +#define vxwprintk(c,f,x...)                                    \
17206 +       do {                                                    \
17207 +               if (c)                                          \
17208 +                       printk(VX_WARNLEVEL f "\n" , ##x);      \
17209 +       } while (0)
17210 +
17211 +
17212 +#define vxd_path(d,m)                                          \
17213 +       ({ static char _buffer[PATH_MAX];                       \
17214 +          d_path((d), (m), _buffer, sizeof(_buffer)); })
17215 +
17216 +#define vxd_cond_path(n)                                       \
17217 +       ((n) ? vxd_path((n)->dentry, (n)->mnt) : "<null>" )
17218 +
17219 +
17220 +struct vx_info;
17221 +
17222 +void dump_vx_info(struct vx_info *, int);
17223 +void dump_vx_info_inactive(int);
17224 +
17225 +#else  /* CONFIG_VSERVER_DEBUG */
17226 +
17227 +#define vx_debug_switch 0
17228 +#define vx_debug_xid   0
17229 +#define vx_debug_nid   0
17230 +#define vx_debug_tag   0
17231 +#define vx_debug_net   0
17232 +#define vx_debug_limit 0
17233 +#define vx_debug_cres  0
17234 +#define vx_debug_dlim  0
17235 +#define vx_debug_cvirt 0
17236 +
17237 +#define vxdprintk(x...) do { } while (0)
17238 +#define vxlprintk(x...) do { } while (0)
17239 +#define vxfprintk(x...) do { } while (0)
17240 +#define vxwprintk(x...) do { } while (0)
17241 +
17242 +#define vxd_path       "<none>"
17243 +#define vxd_cond_path  vxd_path
17244 +
17245 +#endif /* CONFIG_VSERVER_DEBUG */
17246 +
17247 +
17248 +#ifdef CONFIG_VSERVER_DEBUG
17249 +#define vxd_assert_lock(l)     assert_spin_locked(l)
17250 +#define vxd_assert(c,f,x...)   vxlprintk(!(c), \
17251 +       "assertion [" f "] failed.", ##x, __FILE__, __LINE__)
17252 +#else
17253 +#define vxd_assert_lock(l)     do { } while (0)
17254 +#define vxd_assert(c,f,x...)   do { } while (0)
17255 +#endif
17256 +
17257 +
17258 +#endif /* _VX_DEBUG_H */
17259 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/debug_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/debug_cmd.h
17260 --- linux-2.6.19.1/include/linux/vserver/debug_cmd.h    1970-01-01 01:00:00 +0100
17261 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/debug_cmd.h  2006-11-08 04:57:49 +0100
17262 @@ -0,0 +1,58 @@
17263 +#ifndef _VX_DEBUG_CMD_H
17264 +#define _VX_DEBUG_CMD_H
17265 +
17266 +
17267 +/* debug commands */
17268 +
17269 +#define VCMD_dump_history      VC_CMD(DEBUG, 1, 0)
17270 +
17271 +#define VCMD_read_history      VC_CMD(DEBUG, 5, 0)
17272 +#define VCMD_read_monitor      VC_CMD(DEBUG, 6, 0)
17273 +
17274 +struct  vcmd_read_history_v0 {
17275 +       uint32_t index;
17276 +       uint32_t count;
17277 +       char __user *data;
17278 +};
17279 +
17280 +struct  vcmd_read_monitor_v0 {
17281 +       uint32_t index;
17282 +       uint32_t count;
17283 +       char __user *data;
17284 +};
17285 +
17286 +
17287 +#ifdef __KERNEL__
17288 +
17289 +#ifdef CONFIG_COMPAT
17290 +
17291 +#include <asm/compat.h>
17292 +
17293 +struct  vcmd_read_history_v0_x32 {
17294 +       uint32_t index;
17295 +       uint32_t count;
17296 +       compat_uptr_t data_ptr;
17297 +};
17298 +
17299 +struct  vcmd_read_monitor_v0_x32 {
17300 +       uint32_t index;
17301 +       uint32_t count;
17302 +       compat_uptr_t data_ptr;
17303 +};
17304 +
17305 +#endif  /* CONFIG_COMPAT */
17306 +
17307 +extern int vc_dump_history(uint32_t);
17308 +
17309 +extern int vc_read_history(uint32_t, void __user *);
17310 +extern int vc_read_monitor(uint32_t, void __user *);
17311 +
17312 +#ifdef CONFIG_COMPAT
17313 +
17314 +extern int vc_read_history_x32(uint32_t, void __user *);
17315 +extern int vc_read_monitor_x32(uint32_t, void __user *);
17316 +
17317 +#endif  /* CONFIG_COMPAT */
17318 +
17319 +#endif /* __KERNEL__ */
17320 +#endif /* _VX_DEBUG_CMD_H */
17321 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/device.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/device.h
17322 --- linux-2.6.19.1/include/linux/vserver/device.h       1970-01-01 01:00:00 +0100
17323 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/device.h     2006-12-09 03:45:16 +0100
17324 @@ -0,0 +1,13 @@
17325 +#ifndef _VX_DEVICE_H
17326 +#define _VX_DEVICE_H
17327 +
17328 +
17329 +#define DATTR_CREATE   0x00000001
17330 +#define DATTR_OPEN     0x00000002
17331 +
17332 +#define DATTR_REMAP    0x00000010
17333 +
17334 +
17335 +#else  /* _VX_DEVICE_H */
17336 +#warning duplicate inclusion
17337 +#endif /* _VX_DEVICE_H */
17338 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/device_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/device_cmd.h
17339 --- linux-2.6.19.1/include/linux/vserver/device_cmd.h   1970-01-01 01:00:00 +0100
17340 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/device_cmd.h 2006-12-09 03:47:06 +0100
17341 @@ -0,0 +1,41 @@
17342 +#ifndef _VX_DEVICE_CMD_H
17343 +#define _VX_DEVICE_CMD_H
17344 +
17345 +
17346 +/*  device vserver commands */
17347 +
17348 +#define VCMD_set_mapping       VC_CMD(DEVICE, 1, 0)
17349 +
17350 +struct vcmd_set_mapping_v0 {
17351 +       const char __user *device;
17352 +       const char __user *target;
17353 +       uint32_t flags;
17354 +};
17355 +
17356 +
17357 +#ifdef __KERNEL__
17358 +
17359 +#ifdef CONFIG_COMPAT
17360 +
17361 +#include <asm/compat.h>
17362 +
17363 +struct vcmd_set_mapping_v0_x32 {
17364 +       compat_uptr_t device_ptr;
17365 +       compat_uptr_t target_ptr;
17366 +       uint32_t flags;
17367 +};
17368 +
17369 +#endif /* CONFIG_COMPAT */
17370 +
17371 +#include <linux/compiler.h>
17372 +
17373 +extern int vc_set_mapping(uint32_t, void __user *);
17374 +
17375 +#ifdef CONFIG_COMPAT
17376 +
17377 +extern int vc_set_mapping_x32(uint32_t, void __user *);
17378 +
17379 +#endif /* CONFIG_COMPAT */
17380 +
17381 +#endif /* __KERNEL__ */
17382 +#endif /* _VX_DEVICE_CMD_H */
17383 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/dlimit.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/dlimit.h
17384 --- linux-2.6.19.1/include/linux/vserver/dlimit.h       1970-01-01 01:00:00 +0100
17385 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/dlimit.h     2006-11-08 04:57:50 +0100
17386 @@ -0,0 +1,53 @@
17387 +#ifndef _VX_DLIMIT_H
17388 +#define _VX_DLIMIT_H
17389 +
17390 +#include "switch.h"
17391 +
17392 +
17393 +#ifdef __KERNEL__
17394 +
17395 +/*      keep in sync with CDLIM_INFINITY       */
17396 +
17397 +#define DLIM_INFINITY          (~0ULL)
17398 +
17399 +#include <linux/spinlock.h>
17400 +
17401 +struct super_block;
17402 +
17403 +struct dl_info {
17404 +       struct hlist_node dl_hlist;             /* linked list of contexts */
17405 +       struct rcu_head dl_rcu;                 /* the rcu head */
17406 +       tag_t dl_tag;                           /* context tag */
17407 +       atomic_t dl_usecnt;                     /* usage count */
17408 +       atomic_t dl_refcnt;                     /* reference count */
17409 +
17410 +       struct super_block *dl_sb;              /* associated superblock */
17411 +
17412 +       spinlock_t dl_lock;                     /* protect the values */
17413 +
17414 +       unsigned long long dl_space_used;       /* used space in bytes */
17415 +       unsigned long long dl_space_total;      /* maximum space in bytes */
17416 +       unsigned long dl_inodes_used;           /* used inodes */
17417 +       unsigned long dl_inodes_total;          /* maximum inodes */
17418 +
17419 +       unsigned int dl_nrlmult;                /* non root limit mult */
17420 +};
17421 +
17422 +struct rcu_head;
17423 +
17424 +extern void rcu_free_dl_info(struct rcu_head *);
17425 +extern void unhash_dl_info(struct dl_info *);
17426 +
17427 +extern struct dl_info *locate_dl_info(struct super_block *, tag_t);
17428 +
17429 +
17430 +struct kstatfs;
17431 +
17432 +extern void vx_vsi_statfs(struct super_block *, struct kstatfs *);
17433 +
17434 +typedef uint64_t dlsize_t;
17435 +
17436 +#endif /* __KERNEL__ */
17437 +#else  /* _VX_DLIMIT_H */
17438 +#warning duplicate inclusion
17439 +#endif /* _VX_DLIMIT_H */
17440 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/dlimit_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/dlimit_cmd.h
17441 --- linux-2.6.19.1/include/linux/vserver/dlimit_cmd.h   1970-01-01 01:00:00 +0100
17442 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/dlimit_cmd.h 2006-11-08 04:57:49 +0100
17443 @@ -0,0 +1,74 @@
17444 +#ifndef _VX_DLIMIT_CMD_H
17445 +#define _VX_DLIMIT_CMD_H
17446 +
17447 +
17448 +/*  dlimit vserver commands */
17449 +
17450 +#define VCMD_add_dlimit                VC_CMD(DLIMIT, 1, 0)
17451 +#define VCMD_rem_dlimit                VC_CMD(DLIMIT, 2, 0)
17452 +
17453 +#define VCMD_set_dlimit                VC_CMD(DLIMIT, 5, 0)
17454 +#define VCMD_get_dlimit                VC_CMD(DLIMIT, 6, 0)
17455 +
17456 +struct vcmd_ctx_dlimit_base_v0 {
17457 +       const char __user *name;
17458 +       uint32_t flags;
17459 +};
17460 +
17461 +struct vcmd_ctx_dlimit_v0 {
17462 +       const char __user *name;
17463 +       uint32_t space_used;                    /* used space in kbytes */
17464 +       uint32_t space_total;                   /* maximum space in kbytes */
17465 +       uint32_t inodes_used;                   /* used inodes */
17466 +       uint32_t inodes_total;                  /* maximum inodes */
17467 +       uint32_t reserved;                      /* reserved for root in % */
17468 +       uint32_t flags;
17469 +};
17470 +
17471 +#define CDLIM_UNSET            ((uint32_t)0UL)
17472 +#define CDLIM_INFINITY         ((uint32_t)~0UL)
17473 +#define CDLIM_KEEP             ((uint32_t)~1UL)
17474 +
17475 +#ifdef __KERNEL__
17476 +
17477 +#ifdef CONFIG_COMPAT
17478 +
17479 +#include <asm/compat.h>
17480 +
17481 +struct vcmd_ctx_dlimit_base_v0_x32 {
17482 +       compat_uptr_t name_ptr;
17483 +       uint32_t flags;
17484 +};
17485 +
17486 +struct vcmd_ctx_dlimit_v0_x32 {
17487 +       compat_uptr_t name_ptr;
17488 +       uint32_t space_used;                    /* used space in kbytes */
17489 +       uint32_t space_total;                   /* maximum space in kbytes */
17490 +       uint32_t inodes_used;                   /* used inodes */
17491 +       uint32_t inodes_total;                  /* maximum inodes */
17492 +       uint32_t reserved;                      /* reserved for root in % */
17493 +       uint32_t flags;
17494 +};
17495 +
17496 +#endif /* CONFIG_COMPAT */
17497 +
17498 +#include <linux/compiler.h>
17499 +
17500 +extern int vc_add_dlimit(uint32_t, void __user *);
17501 +extern int vc_rem_dlimit(uint32_t, void __user *);
17502 +
17503 +extern int vc_set_dlimit(uint32_t, void __user *);
17504 +extern int vc_get_dlimit(uint32_t, void __user *);
17505 +
17506 +#ifdef CONFIG_COMPAT
17507 +
17508 +extern int vc_add_dlimit_x32(uint32_t, void __user *);
17509 +extern int vc_rem_dlimit_x32(uint32_t, void __user *);
17510 +
17511 +extern int vc_set_dlimit_x32(uint32_t, void __user *);
17512 +extern int vc_get_dlimit_x32(uint32_t, void __user *);
17513 +
17514 +#endif /* CONFIG_COMPAT */
17515 +
17516 +#endif /* __KERNEL__ */
17517 +#endif /* _VX_DLIMIT_CMD_H */
17518 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/global.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/global.h
17519 --- linux-2.6.19.1/include/linux/vserver/global.h       1970-01-01 01:00:00 +0100
17520 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/global.h     2006-12-06 21:16:15 +0100
17521 @@ -0,0 +1,11 @@
17522 +#ifndef _VX_GLOBAL_H
17523 +#define _VX_GLOBAL_H
17524 +
17525 +
17526 +extern atomic_t vx_global_ctotal;
17527 +extern atomic_t vx_global_cactive;
17528 +
17529 +extern atomic_t nx_global_ctotal;
17530 +extern atomic_t nx_global_cactive;
17531 +
17532 +#endif /* _VX_GLOBAL_H */
17533 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/history.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/history.h
17534 --- linux-2.6.19.1/include/linux/vserver/history.h      1970-01-01 01:00:00 +0100
17535 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/history.h    2006-11-30 19:59:44 +0100
17536 @@ -0,0 +1,197 @@
17537 +#ifndef _VX_HISTORY_H
17538 +#define _VX_HISTORY_H
17539 +
17540 +
17541 +enum {
17542 +       VXH_UNUSED=0,
17543 +       VXH_THROW_OOPS=1,
17544 +
17545 +       VXH_GET_VX_INFO,
17546 +       VXH_PUT_VX_INFO,
17547 +       VXH_INIT_VX_INFO,
17548 +       VXH_SET_VX_INFO,
17549 +       VXH_CLR_VX_INFO,
17550 +       VXH_CLAIM_VX_INFO,
17551 +       VXH_RELEASE_VX_INFO,
17552 +       VXH_ALLOC_VX_INFO,
17553 +       VXH_DEALLOC_VX_INFO,
17554 +       VXH_HASH_VX_INFO,
17555 +       VXH_UNHASH_VX_INFO,
17556 +       VXH_LOC_VX_INFO,
17557 +       VXH_LOOKUP_VX_INFO,
17558 +       VXH_CREATE_VX_INFO,
17559 +};
17560 +
17561 +struct _vxhe_vxi {
17562 +       struct vx_info *ptr;
17563 +       unsigned xid;
17564 +       unsigned usecnt;
17565 +       unsigned tasks;
17566 +};
17567 +
17568 +struct _vxhe_set_clr {
17569 +       void *data;
17570 +};
17571 +
17572 +struct _vxhe_loc_lookup {
17573 +       unsigned arg;
17574 +};
17575 +
17576 +struct _vx_hist_entry {
17577 +       void *loc;
17578 +       unsigned short seq;
17579 +       unsigned short type;
17580 +       struct _vxhe_vxi vxi;
17581 +       union {
17582 +               struct _vxhe_set_clr sc;
17583 +               struct _vxhe_loc_lookup ll;
17584 +       };
17585 +};
17586 +
17587 +#ifdef CONFIG_VSERVER_HISTORY
17588 +
17589 +extern unsigned volatile int vxh_active;
17590 +
17591 +struct _vx_hist_entry *vxh_advance(void *loc);
17592 +
17593 +
17594 +static inline
17595 +void   __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
17596 +{
17597 +       entry->vxi.ptr = vxi;
17598 +       if (vxi) {
17599 +               entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
17600 +               entry->vxi.tasks = atomic_read(&vxi->vx_tasks);
17601 +               entry->vxi.xid = vxi->vx_id;
17602 +       }
17603 +}
17604 +
17605 +
17606 +#define        __HERE__ current_text_addr()
17607 +
17608 +#define __VXH_BODY(__type, __data, __here)     \
17609 +       struct _vx_hist_entry *entry;           \
17610 +                                               \
17611 +       preempt_disable();                      \
17612 +       entry = vxh_advance(__here);            \
17613 +       __data;                                 \
17614 +       entry->type = __type;                   \
17615 +       preempt_enable();
17616 +
17617 +
17618 +       /* pass vxi only */
17619 +
17620 +#define __VXH_SMPL                             \
17621 +       __vxh_copy_vxi(entry, vxi)
17622 +
17623 +static inline
17624 +void   __vxh_smpl(struct vx_info *vxi, int __type, void *__here)
17625 +{
17626 +       __VXH_BODY(__type, __VXH_SMPL, __here)
17627 +}
17628 +
17629 +       /* pass vxi and data (void *) */
17630 +
17631 +#define __VXH_DATA                             \
17632 +       __vxh_copy_vxi(entry, vxi);             \
17633 +       entry->sc.data = data
17634 +
17635 +static inline
17636 +void   __vxh_data(struct vx_info *vxi, void *data,
17637 +                       int __type, void *__here)
17638 +{
17639 +       __VXH_BODY(__type, __VXH_DATA, __here)
17640 +}
17641 +
17642 +       /* pass vxi and arg (long) */
17643 +
17644 +#define __VXH_LONG                             \
17645 +       __vxh_copy_vxi(entry, vxi);             \
17646 +       entry->ll.arg = arg
17647 +
17648 +static inline
17649 +void   __vxh_long(struct vx_info *vxi, long arg,
17650 +                       int __type, void *__here)
17651 +{
17652 +       __VXH_BODY(__type, __VXH_LONG, __here)
17653 +}
17654 +
17655 +
17656 +static inline
17657 +void   __vxh_throw_oops(void *__here)
17658 +{
17659 +       __VXH_BODY(VXH_THROW_OOPS, {}, __here);
17660 +       /* prevent further acquisition */
17661 +       vxh_active = 0;
17662 +}
17663 +
17664 +
17665 +#define vxh_throw_oops()       __vxh_throw_oops(__HERE__);
17666 +
17667 +#define __vxh_get_vx_info(v,h) __vxh_smpl(v, VXH_GET_VX_INFO, h);
17668 +#define __vxh_put_vx_info(v,h) __vxh_smpl(v, VXH_PUT_VX_INFO, h);
17669 +
17670 +#define __vxh_init_vx_info(v,d,h) \
17671 +       __vxh_data(v,d, VXH_INIT_VX_INFO, h);
17672 +#define __vxh_set_vx_info(v,d,h) \
17673 +       __vxh_data(v,d, VXH_SET_VX_INFO, h);
17674 +#define __vxh_clr_vx_info(v,d,h) \
17675 +       __vxh_data(v,d, VXH_CLR_VX_INFO, h);
17676 +
17677 +#define __vxh_claim_vx_info(v,d,h) \
17678 +       __vxh_data(v,d, VXH_CLAIM_VX_INFO, h);
17679 +#define __vxh_release_vx_info(v,d,h) \
17680 +       __vxh_data(v,d, VXH_RELEASE_VX_INFO, h);
17681 +
17682 +#define vxh_alloc_vx_info(v) \
17683 +       __vxh_smpl(v, VXH_ALLOC_VX_INFO, __HERE__);
17684 +#define vxh_dealloc_vx_info(v) \
17685 +       __vxh_smpl(v, VXH_DEALLOC_VX_INFO, __HERE__);
17686 +
17687 +#define vxh_hash_vx_info(v) \
17688 +       __vxh_smpl(v, VXH_HASH_VX_INFO, __HERE__);
17689 +#define vxh_unhash_vx_info(v) \
17690 +       __vxh_smpl(v, VXH_UNHASH_VX_INFO, __HERE__);
17691 +
17692 +#define vxh_loc_vx_info(v,l) \
17693 +       __vxh_long(v,l, VXH_LOC_VX_INFO, __HERE__);
17694 +#define vxh_lookup_vx_info(v,l) \
17695 +       __vxh_long(v,l, VXH_LOOKUP_VX_INFO, __HERE__);
17696 +#define vxh_create_vx_info(v,l) \
17697 +       __vxh_long(v,l, VXH_CREATE_VX_INFO, __HERE__);
17698 +
17699 +extern void vxh_dump_history(void);
17700 +
17701 +
17702 +#else  /* CONFIG_VSERVER_HISTORY */
17703 +
17704 +#define        __HERE__        0
17705 +
17706 +#define vxh_throw_oops()               do { } while (0)
17707 +
17708 +#define __vxh_get_vx_info(v,h)         do { } while (0)
17709 +#define __vxh_put_vx_info(v,h)         do { } while (0)
17710 +
17711 +#define __vxh_init_vx_info(v,d,h)      do { } while (0)
17712 +#define __vxh_set_vx_info(v,d,h)       do { } while (0)
17713 +#define __vxh_clr_vx_info(v,d,h)       do { } while (0)
17714 +
17715 +#define __vxh_claim_vx_info(v,d,h)     do { } while (0)
17716 +#define __vxh_release_vx_info(v,d,h)   do { } while (0)
17717 +
17718 +#define vxh_alloc_vx_info(v)           do { } while (0)
17719 +#define vxh_dealloc_vx_info(v)         do { } while (0)
17720 +
17721 +#define vxh_hash_vx_info(v)            do { } while (0)
17722 +#define vxh_unhash_vx_info(v)          do { } while (0)
17723 +
17724 +#define vxh_loc_vx_info(a,v)           do { } while (0)
17725 +#define vxh_lookup_vx_info(a,v)                do { } while (0)
17726 +#define vxh_create_vx_info(a,v)                do { } while (0)
17727 +
17728 +#define vxh_dump_history()             do { } while (0)
17729 +
17730 +
17731 +#endif /* CONFIG_VSERVER_HISTORY */
17732 +
17733 +#endif /* _VX_HISTORY_H */
17734 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/inode.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/inode.h
17735 --- linux-2.6.19.1/include/linux/vserver/inode.h        1970-01-01 01:00:00 +0100
17736 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/inode.h      2006-11-08 04:57:45 +0100
17737 @@ -0,0 +1,38 @@
17738 +#ifndef _VX_INODE_H
17739 +#define _VX_INODE_H
17740 +
17741 +
17742 +#define IATTR_TAG      0x01000000
17743 +
17744 +#define IATTR_ADMIN    0x00000001
17745 +#define IATTR_WATCH    0x00000002
17746 +#define IATTR_HIDE     0x00000004
17747 +#define IATTR_FLAGS    0x00000007
17748 +
17749 +#define IATTR_BARRIER  0x00010000
17750 +#define IATTR_IUNLINK  0x00020000
17751 +#define IATTR_IMMUTABLE 0x00040000
17752 +
17753 +#ifdef __KERNEL__
17754 +
17755 +
17756 +#ifdef CONFIG_VSERVER_PROC_SECURE
17757 +#define IATTR_PROC_DEFAULT     ( IATTR_ADMIN | IATTR_HIDE )
17758 +#define IATTR_PROC_SYMLINK     ( IATTR_ADMIN )
17759 +#else
17760 +#define IATTR_PROC_DEFAULT     ( IATTR_ADMIN )
17761 +#define IATTR_PROC_SYMLINK     ( IATTR_ADMIN )
17762 +#endif
17763 +
17764 +#define vx_hide_check(c,m)     (((m) & IATTR_HIDE) ? vx_check(c,m) : 1)
17765 +
17766 +#endif /* __KERNEL__ */
17767 +
17768 +/* inode ioctls */
17769 +
17770 +#define FIOC_GETXFLG   _IOR('x', 5, long)
17771 +#define FIOC_SETXFLG   _IOW('x', 6, long)
17772 +
17773 +#else  /* _VX_INODE_H */
17774 +#warning duplicate inclusion
17775 +#endif /* _VX_INODE_H */
17776 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/inode_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/inode_cmd.h
17777 --- linux-2.6.19.1/include/linux/vserver/inode_cmd.h    1970-01-01 01:00:00 +0100
17778 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/inode_cmd.h  2006-11-08 04:57:49 +0100
17779 @@ -0,0 +1,61 @@
17780 +#ifndef _VX_INODE_CMD_H
17781 +#define _VX_INODE_CMD_H
17782 +
17783 +
17784 +/*  inode vserver commands */
17785 +
17786 +#define VCMD_get_iattr_v0      VC_CMD(INODE, 1, 0)
17787 +#define VCMD_set_iattr_v0      VC_CMD(INODE, 2, 0)
17788 +
17789 +#define VCMD_get_iattr         VC_CMD(INODE, 1, 1)
17790 +#define VCMD_set_iattr         VC_CMD(INODE, 2, 1)
17791 +
17792 +struct vcmd_ctx_iattr_v0 {
17793 +       /* device handle in id */
17794 +       uint64_t ino;
17795 +       uint32_t xid;
17796 +       uint32_t flags;
17797 +       uint32_t mask;
17798 +};
17799 +
17800 +struct vcmd_ctx_iattr_v1 {
17801 +       const char __user *name;
17802 +       uint32_t xid;
17803 +       uint32_t flags;
17804 +       uint32_t mask;
17805 +};
17806 +
17807 +
17808 +#ifdef __KERNEL__
17809 +
17810 +
17811 +#ifdef CONFIG_COMPAT
17812 +
17813 +#include <asm/compat.h>
17814 +
17815 +struct vcmd_ctx_iattr_v1_x32 {
17816 +       compat_uptr_t name_ptr;
17817 +       uint32_t xid;
17818 +       uint32_t flags;
17819 +       uint32_t mask;
17820 +};
17821 +
17822 +#endif /* CONFIG_COMPAT */
17823 +
17824 +#include <linux/compiler.h>
17825 +
17826 +extern int vc_get_iattr_v0(uint32_t, void __user *);
17827 +extern int vc_set_iattr_v0(uint32_t, void __user *);
17828 +
17829 +extern int vc_get_iattr(uint32_t, void __user *);
17830 +extern int vc_set_iattr(uint32_t, void __user *);
17831 +
17832 +#ifdef CONFIG_COMPAT
17833 +
17834 +extern int vc_get_iattr_x32(uint32_t, void __user *);
17835 +extern int vc_set_iattr_x32(uint32_t, void __user *);
17836 +
17837 +#endif /* CONFIG_COMPAT */
17838 +
17839 +#endif /* __KERNEL__ */
17840 +#endif /* _VX_INODE_CMD_H */
17841 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/limit.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit.h
17842 --- linux-2.6.19.1/include/linux/vserver/limit.h        1970-01-01 01:00:00 +0100
17843 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit.h      2006-11-30 19:31:41 +0100
17844 @@ -0,0 +1,68 @@
17845 +#ifndef _VX_LIMIT_H
17846 +#define _VX_LIMIT_H
17847 +
17848 +
17849 +#define VLIMIT_NSOCK   16
17850 +#define VLIMIT_OPENFD  17
17851 +#define VLIMIT_ANON    18
17852 +#define VLIMIT_SHMEM   19
17853 +#define VLIMIT_SEMARY  20
17854 +#define VLIMIT_NSEMS   21
17855 +#define VLIMIT_DENTRY  22
17856 +#define VLIMIT_MAPPED  23
17857 +
17858 +
17859 +#ifdef __KERNEL__
17860 +
17861 +#define        VLIM_NOCHECK    ((1L << VLIMIT_DENTRY) | (1L << RLIMIT_RSS))
17862 +
17863 +/*     keep in sync with CRLIM_INFINITY */
17864 +
17865 +#define        VLIM_INFINITY   (~0ULL)
17866 +
17867 +#ifndef RLIM_INFINITY
17868 +#warning RLIM_INFINITY is undefined
17869 +#endif
17870 +
17871 +#define __rlim_val(l,r,v)      ((l)->res[(r)].v)
17872 +
17873 +#define __rlim_soft(l,r)       __rlim_val(l,r,soft)
17874 +#define __rlim_hard(l,r)       __rlim_val(l,r,hard)
17875 +
17876 +#define __rlim_rcur(l,r)       __rlim_val(l,r,rcur)
17877 +#define __rlim_rmin(l,r)       __rlim_val(l,r,rmin)
17878 +#define __rlim_rmax(l,r)       __rlim_val(l,r,rmax)
17879 +
17880 +#define __rlim_lhit(l,r)       __rlim_val(l,r,lhit)
17881 +#define __rlim_hit(l,r)                atomic_inc(&__rlim_lhit(l,r))
17882 +
17883 +typedef atomic_long_t rlim_atomic_t;
17884 +typedef unsigned long rlim_t;
17885 +
17886 +#define __rlim_get(l,r)                atomic_long_read(&__rlim_rcur(l,r))
17887 +#define __rlim_set(l,r,v)      atomic_long_set(&__rlim_rcur(l,r), v)
17888 +#define __rlim_inc(l,r)                atomic_long_inc(&__rlim_rcur(l,r))
17889 +#define __rlim_dec(l,r)                atomic_long_dec(&__rlim_rcur(l,r))
17890 +#define __rlim_add(l,r,v)      atomic_long_add(v, &__rlim_rcur(l,r))
17891 +#define __rlim_sub(l,r,v)      atomic_long_sub(v, &__rlim_rcur(l,r))
17892 +
17893 +
17894 +#if    (RLIM_INFINITY == VLIM_INFINITY)
17895 +#define        VX_VLIM(r) ((long long)(long)(r))
17896 +#define        VX_RLIM(v) ((rlim_t)(v))
17897 +#else
17898 +#define        VX_VLIM(r) (((r) == RLIM_INFINITY) \
17899 +               ? VLIM_INFINITY : (long long)(r))
17900 +#define        VX_RLIM(v) (((v) == VLIM_INFINITY) \
17901 +               ? RLIM_INFINITY : (rlim_t)(v))
17902 +#endif
17903 +
17904 +struct sysinfo;
17905 +
17906 +void vx_vsi_meminfo(struct sysinfo *);
17907 +void vx_vsi_swapinfo(struct sysinfo *);
17908 +
17909 +#define NUM_LIMITS     24
17910 +
17911 +#endif /* __KERNEL__ */
17912 +#endif /* _VX_LIMIT_H */
17913 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/limit_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_cmd.h
17914 --- linux-2.6.19.1/include/linux/vserver/limit_cmd.h    1970-01-01 01:00:00 +0100
17915 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_cmd.h  2006-11-08 04:57:49 +0100
17916 @@ -0,0 +1,69 @@
17917 +#ifndef _VX_LIMIT_CMD_H
17918 +#define _VX_LIMIT_CMD_H
17919 +
17920 +
17921 +/*  rlimit vserver commands */
17922 +
17923 +#define VCMD_get_rlimit                VC_CMD(RLIMIT, 1, 0)
17924 +#define VCMD_set_rlimit                VC_CMD(RLIMIT, 2, 0)
17925 +#define VCMD_get_rlimit_mask   VC_CMD(RLIMIT, 3, 0)
17926 +#define VCMD_reset_minmax      VC_CMD(RLIMIT, 9, 0)
17927 +
17928 +struct vcmd_ctx_rlimit_v0 {
17929 +       uint32_t id;
17930 +       uint64_t minimum;
17931 +       uint64_t softlimit;
17932 +       uint64_t maximum;
17933 +};
17934 +
17935 +struct vcmd_ctx_rlimit_mask_v0 {
17936 +       uint32_t minimum;
17937 +       uint32_t softlimit;
17938 +       uint32_t maximum;
17939 +};
17940 +
17941 +#define VCMD_rlimit_stat       VC_CMD(VSTAT, 1, 0)
17942 +
17943 +struct vcmd_rlimit_stat_v0 {
17944 +       uint32_t id;
17945 +       uint32_t hits;
17946 +       uint64_t value;
17947 +       uint64_t minimum;
17948 +       uint64_t maximum;
17949 +};
17950 +
17951 +#define CRLIM_UNSET            (0ULL)
17952 +#define CRLIM_INFINITY         (~0ULL)
17953 +#define CRLIM_KEEP             (~1ULL)
17954 +
17955 +#ifdef __KERNEL__
17956 +
17957 +#ifdef CONFIG_IA32_EMULATION
17958 +
17959 +struct vcmd_ctx_rlimit_v0_x32 {
17960 +       uint32_t id;
17961 +       uint64_t minimum;
17962 +       uint64_t softlimit;
17963 +       uint64_t maximum;
17964 +} __attribute__ ((aligned (4)));
17965 +
17966 +#endif /* CONFIG_IA32_EMULATION */
17967 +
17968 +#include <linux/compiler.h>
17969 +
17970 +extern int vc_get_rlimit_mask(uint32_t, void __user *);
17971 +extern int vc_get_rlimit(struct vx_info *, void __user *);
17972 +extern int vc_set_rlimit(struct vx_info *, void __user *);
17973 +extern int vc_reset_minmax(struct vx_info *, void __user *);
17974 +
17975 +extern int vc_rlimit_stat(struct vx_info *, void __user *);
17976 +
17977 +#ifdef CONFIG_IA32_EMULATION
17978 +
17979 +extern int vc_get_rlimit_x32(struct vx_info *, void __user *);
17980 +extern int vc_set_rlimit_x32(struct vx_info *, void __user *);
17981 +
17982 +#endif /* CONFIG_IA32_EMULATION */
17983 +
17984 +#endif /* __KERNEL__ */
17985 +#endif /* _VX_LIMIT_CMD_H */
17986 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/limit_def.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_def.h
17987 --- linux-2.6.19.1/include/linux/vserver/limit_def.h    1970-01-01 01:00:00 +0100
17988 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_def.h  2006-11-08 04:57:49 +0100
17989 @@ -0,0 +1,47 @@
17990 +#ifndef _VX_LIMIT_DEF_H
17991 +#define _VX_LIMIT_DEF_H
17992 +
17993 +#include <asm/atomic.h>
17994 +#include <asm/resource.h>
17995 +
17996 +#include "limit.h"
17997 +
17998 +
17999 +struct _vx_res_limit {
18000 +       rlim_t soft;            /* Context soft limit */
18001 +       rlim_t hard;            /* Context hard limit */
18002 +
18003 +       rlim_atomic_t rcur;     /* Current value */
18004 +       rlim_t rmin;            /* Context minimum */
18005 +       rlim_t rmax;            /* Context maximum */
18006 +
18007 +       atomic_t lhit;          /* Limit hits */
18008 +};
18009 +
18010 +/* context sub struct */
18011 +
18012 +struct _vx_limit {
18013 +       struct _vx_res_limit res[NUM_LIMITS];
18014 +};
18015 +
18016 +#ifdef CONFIG_VSERVER_DEBUG
18017 +
18018 +static inline void __dump_vx_limit(struct _vx_limit *limit)
18019 +{
18020 +       int i;
18021 +
18022 +       printk("\t_vx_limit:");
18023 +       for (i=0; i<NUM_LIMITS; i++) {
18024 +               printk("\t [%2d] = %8lu %8lu/%8lu, %8ld/%8ld, %8d\n",
18025 +                       i, (unsigned long)__rlim_get(limit, i),
18026 +                       (unsigned long)__rlim_rmin(limit, i),
18027 +                       (unsigned long)__rlim_rmax(limit, i),
18028 +                       (long)__rlim_soft(limit, i),
18029 +                       (long)__rlim_hard(limit, i),
18030 +                       atomic_read(&__rlim_lhit(limit, i)));
18031 +       }
18032 +}
18033 +
18034 +#endif
18035 +
18036 +#endif /* _VX_LIMIT_DEF_H */
18037 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/limit_int.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_int.h
18038 --- linux-2.6.19.1/include/linux/vserver/limit_int.h    1970-01-01 01:00:00 +0100
18039 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/limit_int.h  2006-12-04 05:22:12 +0100
18040 @@ -0,0 +1,175 @@
18041 +#ifndef _VX_LIMIT_INT_H
18042 +#define _VX_LIMIT_INT_H
18043 +
18044 +#include "context.h"
18045 +
18046 +#ifdef __KERNEL__
18047 +
18048 +#define VXD_RCRES_COND(r)      VXD_CBIT(cres, (r))
18049 +#define VXD_RLIMIT_COND(r)     VXD_CBIT(limit, (r))
18050 +
18051 +extern const char *vlimit_name[NUM_LIMITS];
18052 +
18053 +static inline void __vx_acc_cres(struct vx_info *vxi,
18054 +       int res, int dir, void *_data, char *_file, int _line)
18055 +{
18056 +       if (VXD_RCRES_COND(res))
18057 +               vxlprintk(1, "vx_acc_cres[%5d,%s,%2d]: %5ld%s (%p)",
18058 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
18059 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
18060 +                       (dir > 0) ? "++" : "--", _data, _file, _line);
18061 +       if (!vxi)
18062 +               return;
18063 +
18064 +       if (dir > 0)
18065 +               __rlim_inc(&vxi->limit, res);
18066 +       else
18067 +               __rlim_dec(&vxi->limit, res);
18068 +}
18069 +
18070 +static inline void __vx_add_cres(struct vx_info *vxi,
18071 +       int res, int amount, void *_data, char *_file, int _line)
18072 +{
18073 +       if (VXD_RCRES_COND(res))
18074 +               vxlprintk(1, "vx_add_cres[%5d,%s,%2d]: %5ld += %5d (%p)",
18075 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
18076 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
18077 +                       amount, _data, _file, _line);
18078 +       if (amount == 0)
18079 +               return;
18080 +       if (!vxi)
18081 +               return;
18082 +       __rlim_add(&vxi->limit, res, amount);
18083 +}
18084 +
18085 +static inline
18086 +int __vx_cres_adjust_max(struct _vx_limit *limit, int res, rlim_t value)
18087 +{
18088 +       int cond = (value > __rlim_rmax(limit, res));
18089 +
18090 +       if (cond)
18091 +               __rlim_rmax(limit, res) = value;
18092 +       return cond;
18093 +}
18094 +
18095 +static inline
18096 +int __vx_cres_adjust_min(struct _vx_limit *limit, int res, rlim_t value)
18097 +{
18098 +       int cond = (value < __rlim_rmin(limit, res));
18099 +
18100 +       if (cond)
18101 +               __rlim_rmin(limit, res) = value;
18102 +       return cond;
18103 +}
18104 +
18105 +static inline
18106 +void __vx_cres_fixup(struct _vx_limit *limit, int res, rlim_t value)
18107 +{
18108 +       if (!__vx_cres_adjust_max(limit, res, value))
18109 +               __vx_cres_adjust_min(limit, res, value);
18110 +}
18111 +
18112 +
18113 +/*     return values:
18114 +        +1 ... no limit hit
18115 +        -1 ... over soft limit
18116 +         0 ... over hard limit         */
18117 +
18118 +static inline int __vx_cres_avail(struct vx_info *vxi,
18119 +       int res, int num, char *_file, int _line)
18120 +{
18121 +       struct _vx_limit *limit;
18122 +       rlim_t value;
18123 +
18124 +       if (VXD_RLIMIT_COND(res))
18125 +               vxlprintk(1, "vx_cres_avail[%5d,%s,%2d]: %5ld/%5ld > %5ld + %5d",
18126 +                       (vxi ? vxi->vx_id : -1), vlimit_name[res], res,
18127 +                       (vxi ? (long)__rlim_soft(&vxi->limit, res) : -1),
18128 +                       (vxi ? (long)__rlim_hard(&vxi->limit, res) : -1),
18129 +                       (vxi ? (long)__rlim_get(&vxi->limit, res) : 0),
18130 +                       num, _file, _line);
18131 +       if (!vxi)
18132 +               return 1;
18133 +
18134 +       limit = &vxi->limit;
18135 +       value = __rlim_get(limit, res);
18136 +
18137 +       if (!__vx_cres_adjust_max(limit, res, value))
18138 +               __vx_cres_adjust_min(limit, res, value);
18139 +
18140 +       if (num == 0)
18141 +               return 1;
18142 +
18143 +       if (__rlim_soft(limit, res) == RLIM_INFINITY)
18144 +               return -1;
18145 +       if (value + num <= __rlim_soft(limit, res))
18146 +               return -1;
18147 +
18148 +       if (__rlim_hard(limit, res) == RLIM_INFINITY)
18149 +               return 1;
18150 +       if (value + num <= __rlim_hard(limit, res))
18151 +               return 1;
18152 +
18153 +       __rlim_hit(limit, res);
18154 +       return 0;
18155 +}
18156 +
18157 +
18158 +static const int VLA_RSS[] = { RLIMIT_RSS, VLIMIT_ANON, VLIMIT_MAPPED, 0 };
18159 +
18160 +static inline
18161 +rlim_t __vx_cres_array_sum(struct _vx_limit *limit, const int *array)
18162 +{
18163 +       rlim_t value, sum = 0;
18164 +       int res;
18165 +
18166 +       while ((res = *array++)) {
18167 +               value = __rlim_get(limit, res);
18168 +               __vx_cres_fixup(limit, res, value);
18169 +               sum += value;
18170 +       }
18171 +       return sum;
18172 +}
18173 +
18174 +static inline
18175 +rlim_t __vx_cres_array_fixup(struct _vx_limit *limit, const int *array)
18176 +{
18177 +       rlim_t value = __vx_cres_array_sum(limit, array + 1);
18178 +       int res = *array;
18179 +
18180 +       if (value == __rlim_get(limit, res))
18181 +               return value;
18182 +
18183 +       __rlim_set(limit, res, value);
18184 +       /* now adjust min/max */
18185 +       if (!__vx_cres_adjust_max(limit, res, value))
18186 +               __vx_cres_adjust_min(limit, res, value);
18187 +
18188 +       return value;
18189 +}
18190 +
18191 +static inline int __vx_cres_array_avail(struct vx_info *vxi,
18192 +       const int *array, int num, char *_file, int _line)
18193 +{
18194 +       struct _vx_limit *limit;
18195 +       rlim_t value = 0;
18196 +       int res;
18197 +
18198 +       if (num == 0)
18199 +               return 1;
18200 +       if (!vxi)
18201 +               return 1;
18202 +
18203 +       limit = &vxi->limit;
18204 +       res = *array;
18205 +       value = __vx_cres_array_sum(limit, array+1);
18206 +
18207 +       __rlim_set(limit, res, value);
18208 +       __vx_cres_fixup(limit, res, value);
18209 +
18210 +       return __vx_cres_avail(vxi, res, num, _file, _line);
18211 +}
18212 +
18213 +
18214 +#endif /* __KERNEL__ */
18215 +#endif /* _VX_LIMIT_INT_H */
18216 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/monitor.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/monitor.h
18217 --- linux-2.6.19.1/include/linux/vserver/monitor.h      1970-01-01 01:00:00 +0100
18218 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/monitor.h    2006-11-08 04:57:48 +0100
18219 @@ -0,0 +1,95 @@
18220 +#ifndef _VX_MONITOR_H
18221 +#define _VX_MONITOR_H
18222 +
18223 +
18224 +enum {
18225 +       VXM_UNUSED = 0,
18226 +
18227 +       VXM_SYNC = 0x10,
18228 +
18229 +       VXM_UPDATE = 0x20,
18230 +       VXM_UPDATE_1,
18231 +       VXM_UPDATE_2,
18232 +
18233 +       VXM_RQINFO_1 = 0x24,
18234 +       VXM_RQINFO_2,
18235 +
18236 +       VXM_ACTIVATE = 0x40,
18237 +       VXM_DEACTIVATE,
18238 +       VXM_IDLE,
18239 +
18240 +       VXM_HOLD = 0x44,
18241 +       VXM_UNHOLD,
18242 +
18243 +       VXM_MIGRATE = 0x48,
18244 +       VXM_RESCHED,
18245 +
18246 +       /* all other bits are flags */
18247 +       VXM_SCHED = 0x80,
18248 +};
18249 +
18250 +struct _vxm_update_1 {
18251 +       uint32_t tokens_max;
18252 +       uint32_t fill_rate;
18253 +       uint32_t interval;
18254 +};
18255 +
18256 +struct _vxm_update_2 {
18257 +       uint32_t tokens_min;
18258 +       uint32_t fill_rate;
18259 +       uint32_t interval;
18260 +};
18261 +
18262 +struct _vxm_rqinfo_1 {
18263 +       uint16_t running;
18264 +       uint16_t onhold;
18265 +       uint16_t iowait;
18266 +       uint16_t uintr;
18267 +       uint32_t idle_tokens;
18268 +};
18269 +
18270 +struct _vxm_rqinfo_2 {
18271 +       uint32_t norm_time;
18272 +       uint32_t idle_time;
18273 +       uint32_t idle_skip;
18274 +};
18275 +
18276 +struct _vxm_sched {
18277 +       uint32_t tokens;
18278 +       uint32_t norm_time;
18279 +       uint32_t idle_time;
18280 +};
18281 +
18282 +struct _vxm_task {
18283 +       uint16_t pid;
18284 +       uint16_t state;
18285 +};
18286 +
18287 +struct _vxm_event {
18288 +       uint32_t jif;
18289 +       union {
18290 +               uint32_t seq;
18291 +               uint32_t sec;
18292 +       };
18293 +       union {
18294 +               uint32_t tokens;
18295 +               uint32_t nsec;
18296 +               struct _vxm_task tsk;
18297 +       };
18298 +};
18299 +
18300 +struct _vx_mon_entry {
18301 +       uint16_t type;
18302 +       uint16_t xid;
18303 +       union {
18304 +               struct _vxm_event ev;
18305 +               struct _vxm_sched sd;
18306 +               struct _vxm_update_1 u1;
18307 +               struct _vxm_update_2 u2;
18308 +               struct _vxm_rqinfo_1 q1;
18309 +               struct _vxm_rqinfo_2 q2;
18310 +       };
18311 +};
18312 +
18313 +
18314 +#endif /* _VX_MONITOR_H */
18315 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/network.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/network.h
18316 --- linux-2.6.19.1/include/linux/vserver/network.h      1970-01-01 01:00:00 +0100
18317 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/network.h    2006-12-17 05:24:42 +0100
18318 @@ -0,0 +1,99 @@
18319 +#ifndef _VX_NETWORK_H
18320 +#define _VX_NETWORK_H
18321 +
18322 +#include <linux/types.h>
18323 +
18324 +
18325 +#define MAX_N_CONTEXT  65535   /* Arbitrary limit */
18326 +
18327 +#define NB_IPV4ROOT    16
18328 +
18329 +
18330 +/* network flags */
18331 +
18332 +#define NXF_INFO_PRIVATE       0x00000008
18333 +
18334 +#define NXF_SINGLE_IP          0x00000100
18335 +
18336 +#define NXF_HIDE_NETIF         0x02000000
18337 +
18338 +#define NXF_STATE_SETUP                (1ULL<<32)
18339 +#define NXF_STATE_ADMIN                (1ULL<<34)
18340 +
18341 +#define NXF_SC_HELPER          (1ULL<<36)
18342 +#define NXF_PERSISTENT         (1ULL<<38)
18343 +
18344 +#define NXF_ONE_TIME           (0x0005ULL<<32)
18345 +
18346 +#define NXF_INIT_SET           (NXF_STATE_ADMIN)
18347 +
18348 +
18349 +/* address types */
18350 +
18351 +#define NXA_TYPE_IPV4          0x0001
18352 +#define NXA_TYPE_IPV6          0x0002
18353 +
18354 +#define NXA_MOD_BCAST          0x0100
18355 +#define NXA_MOD_LBACK          0x0200
18356 +
18357 +#define NXA_TYPE_ANY           ((uint16_t)-1)
18358 +
18359 +#define        NXA_TYPE_ADDR           0x0003
18360 +#define NXA_TYPE_MASK          0x0013
18361 +#define NXA_TYPE_RANGE         0x0023
18362 +
18363 +
18364 +#ifdef __KERNEL__
18365 +
18366 +#include <linux/list.h>
18367 +#include <linux/spinlock.h>
18368 +#include <linux/rcupdate.h>
18369 +#include <asm/atomic.h>
18370 +
18371 +
18372 +struct nx_info {
18373 +       struct hlist_node nx_hlist;     /* linked list of nxinfos */
18374 +       nid_t nx_id;                    /* vnet id */
18375 +       atomic_t nx_usecnt;             /* usage count */
18376 +       atomic_t nx_tasks;              /* tasks count */
18377 +       int nx_state;                   /* context state */
18378 +
18379 +       uint64_t nx_flags;              /* network flag word */
18380 +       uint64_t nx_ncaps;              /* network capabilities */
18381 +
18382 +       int nbipv4;
18383 +       __be32 ipv4[NB_IPV4ROOT];       /* Process can only bind to these IPs */
18384 +                                       /* The first one is used to connect */
18385 +                                       /* and for bind any service */
18386 +                                       /* The other must be used explicity */
18387 +       __be32 mask[NB_IPV4ROOT];       /* Netmask for each ipv4 */
18388 +                                       /* Used to select the proper source */
18389 +                                       /* address for sockets */
18390 +       __be32 v4_bcast;                /* Broadcast address to receive UDP  */
18391 +       __be32 v4_lback;                /* Loopback address */
18392 +
18393 +       char nx_name[65];               /* network context name */
18394 +};
18395 +
18396 +
18397 +/* status flags */
18398 +
18399 +#define NXS_HASHED      0x0001
18400 +#define NXS_SHUTDOWN    0x0100
18401 +#define NXS_RELEASED    0x8000
18402 +
18403 +extern struct nx_info *lookup_nx_info(int);
18404 +
18405 +extern int get_nid_list(int, unsigned int *, int);
18406 +extern int nid_is_hashed(nid_t);
18407 +
18408 +extern int nx_migrate_task(struct task_struct *, struct nx_info *);
18409 +
18410 +extern long vs_net_change(struct nx_info *, unsigned int);
18411 +
18412 +struct sock;
18413 +
18414 +#endif /* __KERNEL__ */
18415 +#else  /* _VX_NETWORK_H */
18416 +#warning duplicate inclusion
18417 +#endif /* _VX_NETWORK_H */
18418 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/network_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/network_cmd.h
18419 --- linux-2.6.19.1/include/linux/vserver/network_cmd.h  1970-01-01 01:00:00 +0100
18420 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/network_cmd.h        2006-12-18 05:02:31 +0100
18421 @@ -0,0 +1,124 @@
18422 +#ifndef _VX_NETWORK_CMD_H
18423 +#define _VX_NETWORK_CMD_H
18424 +
18425 +
18426 +/* vinfo commands */
18427 +
18428 +#define VCMD_task_nid          VC_CMD(VINFO, 2, 0)
18429 +
18430 +#ifdef __KERNEL__
18431 +extern int vc_task_nid(uint32_t, void __user *);
18432 +
18433 +#endif /* __KERNEL__ */
18434 +
18435 +#define VCMD_nx_info           VC_CMD(VINFO, 6, 0)
18436 +
18437 +struct vcmd_nx_info_v0 {
18438 +       uint32_t nid;
18439 +       /* more to come */
18440 +};
18441 +
18442 +#ifdef __KERNEL__
18443 +extern int vc_nx_info(struct nx_info *, void __user *);
18444 +
18445 +#endif /* __KERNEL__ */
18446 +
18447 +#include <linux/in.h>
18448 +#include <linux/in6.h>
18449 +
18450 +#define VCMD_net_create_v0     VC_CMD(VNET, 1, 0)
18451 +#define VCMD_net_create                VC_CMD(VNET, 1, 1)
18452 +
18453 +struct  vcmd_net_create {
18454 +       uint64_t flagword;
18455 +};
18456 +
18457 +#define VCMD_net_migrate       VC_CMD(NETMIG, 1, 0)
18458 +
18459 +#define VCMD_net_add           VC_CMD(NETALT, 1, 0)
18460 +#define VCMD_net_remove                VC_CMD(NETALT, 2, 0)
18461 +
18462 +struct vcmd_net_addr_v0 {
18463 +       uint16_t type;
18464 +       uint16_t count;
18465 +       struct in_addr ip[4];
18466 +       struct in_addr mask[4];
18467 +       /* more to come */
18468 +};
18469 +
18470 +#define VCMD_add_match_ipv4    VC_CMD(NETALT, 4, 0)
18471 +#define VCMD_get_match_ipv4    VC_CMD(NETALT, 5, 0)
18472 +
18473 +struct vcmd_match_ipv4_v0 {
18474 +       uint16_t type;
18475 +       uint16_t flags;
18476 +       uint32_t parent;
18477 +       uint32_t prefix;
18478 +       struct in_addr ip;
18479 +       struct in_addr ip2;
18480 +       struct in_addr mask;
18481 +};
18482 +
18483 +#define VCMD_add_match_ipv6    VC_CMD(NETALT, 6, 0)
18484 +#define VCMD_get_match_ipv6    VC_CMD(NETALT, 7, 0)
18485 +
18486 +struct vcmd_match_ipv6_v0 {
18487 +       uint16_t type;
18488 +       uint16_t flags;
18489 +       uint32_t parent;
18490 +       uint32_t prefix;
18491 +       struct in6_addr ip;
18492 +       struct in6_addr ip2;
18493 +       struct in6_addr mask;
18494 +};
18495 +
18496 +
18497 +#ifdef __KERNEL__
18498 +extern int vc_net_create(uint32_t, void __user *);
18499 +extern int vc_net_migrate(struct nx_info *, void __user *);
18500 +
18501 +extern int vc_net_add(struct nx_info *, void __user *);
18502 +extern int vc_net_remove(struct nx_info *, void __user *);
18503 +
18504 +extern int vc_add_match_ipv4(struct nx_info *, void __user *);
18505 +extern int vc_get_match_ipv4(struct nx_info *, void __user *);
18506 +
18507 +extern int vc_add_match_ipv6(struct nx_info *, void __user *);
18508 +extern int vc_get_match_ipv6(struct nx_info *, void __user *);
18509 +
18510 +#endif /* __KERNEL__ */
18511 +
18512 +
18513 +/* flag commands */
18514 +
18515 +#define VCMD_get_nflags                VC_CMD(FLAGS, 5, 0)
18516 +#define VCMD_set_nflags                VC_CMD(FLAGS, 6, 0)
18517 +
18518 +struct vcmd_net_flags_v0 {
18519 +       uint64_t flagword;
18520 +       uint64_t mask;
18521 +};
18522 +
18523 +#ifdef __KERNEL__
18524 +extern int vc_get_nflags(struct nx_info *, void __user *);
18525 +extern int vc_set_nflags(struct nx_info *, void __user *);
18526 +
18527 +#endif /* __KERNEL__ */
18528 +
18529 +
18530 +/* network caps commands */
18531 +
18532 +#define VCMD_get_ncaps         VC_CMD(FLAGS, 7, 0)
18533 +#define VCMD_set_ncaps         VC_CMD(FLAGS, 8, 0)
18534 +
18535 +struct vcmd_net_caps_v0 {
18536 +       uint64_t ncaps;
18537 +       uint64_t cmask;
18538 +};
18539 +
18540 +#ifdef __KERNEL__
18541 +extern int vc_get_ncaps(struct nx_info *, void __user *);
18542 +extern int vc_set_ncaps(struct nx_info *, void __user *);
18543 +
18544 +#endif /* __KERNEL__ */
18545 +#endif /* _VX_CONTEXT_CMD_H */
18546 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/sched.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched.h
18547 --- linux-2.6.19.1/include/linux/vserver/sched.h        1970-01-01 01:00:00 +0100
18548 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched.h      2006-11-08 04:57:45 +0100
18549 @@ -0,0 +1,26 @@
18550 +#ifndef _VX_SCHED_H
18551 +#define _VX_SCHED_H
18552 +
18553 +
18554 +#ifdef __KERNEL__
18555 +
18556 +struct timespec;
18557 +
18558 +void vx_vsi_uptime(struct timespec *, struct timespec *);
18559 +
18560 +
18561 +struct vx_info;
18562 +
18563 +void vx_update_load(struct vx_info *);
18564 +
18565 +
18566 +int vx_tokens_recalc(struct _vx_sched_pc *,
18567 +       unsigned long *, unsigned long *, int [2]);
18568 +
18569 +void vx_update_sched_param(struct _vx_sched *sched,
18570 +       struct _vx_sched_pc *sched_pc);
18571 +
18572 +#endif /* __KERNEL__ */
18573 +#else  /* _VX_SCHED_H */
18574 +#warning duplicate inclusion
18575 +#endif /* _VX_SCHED_H */
18576 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/sched_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched_cmd.h
18577 --- linux-2.6.19.1/include/linux/vserver/sched_cmd.h    1970-01-01 01:00:00 +0100
18578 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched_cmd.h  2006-11-08 04:57:49 +0100
18579 @@ -0,0 +1,72 @@
18580 +#ifndef _VX_SCHED_CMD_H
18581 +#define _VX_SCHED_CMD_H
18582 +
18583 +
18584 +/*  sched vserver commands */
18585 +
18586 +#define VCMD_set_sched_v2      VC_CMD(SCHED, 1, 2)
18587 +#define VCMD_set_sched_v3      VC_CMD(SCHED, 1, 3)
18588 +#define VCMD_set_sched         VC_CMD(SCHED, 1, 4)
18589 +
18590 +struct vcmd_set_sched_v2 {
18591 +       int32_t fill_rate;
18592 +       int32_t interval;
18593 +       int32_t tokens;
18594 +       int32_t tokens_min;
18595 +       int32_t tokens_max;
18596 +       uint64_t cpu_mask;
18597 +};
18598 +
18599 +struct vcmd_set_sched_v3 {
18600 +       uint32_t set_mask;
18601 +       int32_t fill_rate;
18602 +       int32_t interval;
18603 +       int32_t tokens;
18604 +       int32_t tokens_min;
18605 +       int32_t tokens_max;
18606 +       int32_t priority_bias;
18607 +};
18608 +
18609 +struct vcmd_set_sched_v4 {
18610 +       uint32_t set_mask;
18611 +       int32_t fill_rate;
18612 +       int32_t interval;
18613 +       int32_t tokens;
18614 +       int32_t tokens_min;
18615 +       int32_t tokens_max;
18616 +       int32_t prio_bias;
18617 +       int32_t cpu_id;
18618 +       int32_t bucket_id;
18619 +};
18620 +
18621 +
18622 +#define VXSM_FILL_RATE         0x0001
18623 +#define VXSM_INTERVAL          0x0002
18624 +#define VXSM_FILL_RATE2                0x0004
18625 +#define VXSM_INTERVAL2         0x0008
18626 +#define VXSM_TOKENS            0x0010
18627 +#define VXSM_TOKENS_MIN                0x0020
18628 +#define VXSM_TOKENS_MAX                0x0040
18629 +#define VXSM_PRIO_BIAS         0x0100
18630 +
18631 +#define VXSM_IDLE_TIME         0x0200
18632 +#define VXSM_FORCE             0x0400
18633 +
18634 +#define        VXSM_V3_MASK            0x0173
18635 +#define        VXSM_SET_MASK           0x01FF
18636 +
18637 +#define VXSM_CPU_ID            0x1000
18638 +#define VXSM_BUCKET_ID         0x2000
18639 +
18640 +#define SCHED_KEEP             (-2)    /* only for v2 */
18641 +
18642 +#ifdef __KERNEL__
18643 +
18644 +#include <linux/compiler.h>
18645 +
18646 +extern int vc_set_sched_v2(struct vx_info *, void __user *);
18647 +extern int vc_set_sched_v3(struct vx_info *, void __user *);
18648 +extern int vc_set_sched(struct vx_info *, void __user *);
18649 +
18650 +#endif /* __KERNEL__ */
18651 +#endif /* _VX_SCHED_CMD_H */
18652 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/sched_def.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched_def.h
18653 --- linux-2.6.19.1/include/linux/vserver/sched_def.h    1970-01-01 01:00:00 +0100
18654 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/sched_def.h  2006-11-08 04:57:49 +0100
18655 @@ -0,0 +1,67 @@
18656 +#ifndef _VX_SCHED_DEF_H
18657 +#define _VX_SCHED_DEF_H
18658 +
18659 +#include <linux/spinlock.h>
18660 +#include <linux/jiffies.h>
18661 +#include <linux/cpumask.h>
18662 +#include <asm/atomic.h>
18663 +#include <asm/param.h>
18664 +
18665 +
18666 +/* context sub struct */
18667 +
18668 +struct _vx_sched {
18669 +       spinlock_t tokens_lock;         /* lock for token bucket */
18670 +
18671 +       int tokens;                     /* number of CPU tokens */
18672 +       int fill_rate[2];               /* Fill rate: add X tokens... */
18673 +       int interval[2];                /* Divisor:   per Y jiffies   */
18674 +       int tokens_min;                 /* Limit:     minimum for unhold */
18675 +       int tokens_max;                 /* Limit:     no more than N tokens */
18676 +
18677 +       unsigned update_mask;           /* which features should be updated */
18678 +       cpumask_t update;               /* CPUs which should update */
18679 +
18680 +       int prio_bias;                  /* bias offset for priority */
18681 +       int vavavoom;                   /* last calculated vavavoom */
18682 +};
18683 +
18684 +struct _vx_sched_pc {
18685 +       int tokens;                     /* number of CPU tokens */
18686 +       int flags;                      /* bucket flags */
18687 +
18688 +       int fill_rate[2];               /* Fill rate: add X tokens... */
18689 +       int interval[2];                /* Divisor:   per Y jiffies   */
18690 +       int tokens_min;                 /* Limit:     minimum for unhold */
18691 +       int tokens_max;                 /* Limit:     no more than N tokens */
18692 +
18693 +       unsigned long norm_time;        /* last time accounted */
18694 +       unsigned long idle_time;        /* non linear time for fair sched */
18695 +       unsigned long token_time;       /* token time for accounting */
18696 +       unsigned long onhold;           /* jiffies when put on hold */
18697 +
18698 +       uint64_t user_ticks;            /* token tick events */
18699 +       uint64_t sys_ticks;             /* token tick events */
18700 +       uint64_t hold_ticks;            /* token ticks paused */
18701 +};
18702 +
18703 +
18704 +#define VXSF_ONHOLD    0x0001
18705 +#define VXSF_IDLE_TIME 0x0100
18706 +
18707 +#ifdef CONFIG_VSERVER_DEBUG
18708 +
18709 +static inline void __dump_vx_sched(struct _vx_sched *sched)
18710 +{
18711 +       printk("\t_vx_sched:\n");
18712 +       printk("\t tokens: %4d/%4d, %4d/%4d, %4d, %4d\n",
18713 +               sched->fill_rate[0], sched->interval[0],
18714 +               sched->fill_rate[1], sched->interval[1],
18715 +               sched->tokens_min, sched->tokens_max);
18716 +       printk("\t priority = %4d, %4d\n",
18717 +               sched->prio_bias, sched->vavavoom);
18718 +}
18719 +
18720 +#endif
18721 +
18722 +#endif /* _VX_SCHED_DEF_H */
18723 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/signal.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/signal.h
18724 --- linux-2.6.19.1/include/linux/vserver/signal.h       1970-01-01 01:00:00 +0100
18725 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/signal.h     2006-11-08 04:57:45 +0100
18726 @@ -0,0 +1,14 @@
18727 +#ifndef _VX_SIGNAL_H
18728 +#define _VX_SIGNAL_H
18729 +
18730 +
18731 +#ifdef __KERNEL__
18732 +
18733 +struct vx_info;
18734 +
18735 +int vx_info_kill(struct vx_info *, int, int);
18736 +
18737 +#endif /* __KERNEL__ */
18738 +#else  /* _VX_SIGNAL_H */
18739 +#warning duplicate inclusion
18740 +#endif /* _VX_SIGNAL_H */
18741 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/signal_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/signal_cmd.h
18742 --- linux-2.6.19.1/include/linux/vserver/signal_cmd.h   1970-01-01 01:00:00 +0100
18743 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/signal_cmd.h 2006-12-05 17:36:09 +0100
18744 @@ -0,0 +1,43 @@
18745 +#ifndef _VX_SIGNAL_CMD_H
18746 +#define _VX_SIGNAL_CMD_H
18747 +
18748 +
18749 +/*  signalling vserver commands */
18750 +
18751 +#define VCMD_ctx_kill          VC_CMD(PROCTRL, 1, 0)
18752 +#define VCMD_wait_exit         VC_CMD(EVENT, 99, 0)
18753 +
18754 +struct vcmd_ctx_kill_v0 {
18755 +       int32_t pid;
18756 +       int32_t sig;
18757 +};
18758 +
18759 +struct vcmd_wait_exit_v0 {
18760 +       int32_t reboot_cmd;
18761 +       int32_t exit_code;
18762 +};
18763 +
18764 +#ifdef __KERNEL__
18765 +
18766 +extern int vc_ctx_kill(struct vx_info *, void __user *);
18767 +extern int vc_wait_exit(struct vx_info *, void __user *);
18768 +
18769 +#endif /* __KERNEL__ */
18770 +
18771 +/*  process alteration commands */
18772 +
18773 +#define VCMD_get_pflags                VC_CMD(PROCALT, 5, 0)
18774 +#define VCMD_set_pflags                VC_CMD(PROCALT, 6, 0)
18775 +
18776 +struct vcmd_pflags_v0 {
18777 +       uint32_t flagword;
18778 +       uint32_t mask;
18779 +};
18780 +
18781 +#ifdef __KERNEL__
18782 +
18783 +extern int vc_get_pflags(uint32_t pid, void __user *);
18784 +extern int vc_set_pflags(uint32_t pid, void __user *);
18785 +
18786 +#endif /* __KERNEL__ */
18787 +#endif /* _VX_SIGNAL_CMD_H */
18788 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/space.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/space.h
18789 --- linux-2.6.19.1/include/linux/vserver/space.h        1970-01-01 01:00:00 +0100
18790 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/space.h      2006-12-05 18:57:02 +0100
18791 @@ -0,0 +1,13 @@
18792 +#ifndef _VX_SPACE_H
18793 +#define _VX_SPACE_H
18794 +
18795 +
18796 +#include <linux/types.h>
18797 +
18798 +struct vx_info;
18799 +
18800 +int vx_set_space(struct vx_info *vxi, unsigned long mask);
18801 +
18802 +#else  /* _VX_SPACE_H */
18803 +#warning duplicate inclusion
18804 +#endif /* _VX_SPACE_H */
18805 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/space_cmd.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/space_cmd.h
18806 --- linux-2.6.19.1/include/linux/vserver/space_cmd.h    1970-01-01 01:00:00 +0100
18807 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/space_cmd.h  2006-12-05 18:14:49 +0100
18808 @@ -0,0 +1,26 @@
18809 +#ifndef _VX_SPACE_CMD_H
18810 +#define _VX_SPACE_CMD_H
18811 +
18812 +
18813 +#define VCMD_enter_space_v0    VC_CMD(PROCALT, 1, 0)
18814 +#define VCMD_enter_space       VC_CMD(PROCALT, 1, 1)
18815 +
18816 +#define VCMD_set_space_v0      VC_CMD(PROCALT, 3, 0)
18817 +#define VCMD_set_space         VC_CMD(PROCALT, 3, 1)
18818 +
18819 +#define VCMD_get_space_mask    VC_CMD(PROCALT, 4, 0)
18820 +
18821 +
18822 +struct vcmd_space_mask {
18823 +       uint64_t mask;
18824 +};
18825 +
18826 +
18827 +#ifdef __KERNEL__
18828 +
18829 +extern int vc_enter_space(struct vx_info *, void __user *);
18830 +extern int vc_set_space(struct vx_info *, void __user *);
18831 +extern int vc_get_space_mask(struct vx_info *, void __user *);
18832 +
18833 +#endif /* __KERNEL__ */
18834 +#endif /* _VX_SPACE_CMD_H */
18835 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/switch.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/switch.h
18836 --- linux-2.6.19.1/include/linux/vserver/switch.h       1970-01-01 01:00:00 +0100
18837 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/switch.h     2006-12-09 03:45:16 +0100
18838 @@ -0,0 +1,102 @@
18839 +#ifndef _VX_SWITCH_H
18840 +#define _VX_SWITCH_H
18841 +
18842 +#include <linux/types.h>
18843 +
18844 +
18845 +#define VC_CATEGORY(c)         (((c) >> 24) & 0x3F)
18846 +#define VC_COMMAND(c)          (((c) >> 16) & 0xFF)
18847 +#define VC_VERSION(c)          ((c) & 0xFFF)
18848 +
18849 +#define VC_CMD(c,i,v)          ((((VC_CAT_ ## c) & 0x3F) << 24) \
18850 +                               | (((i) & 0xFF) << 16) | ((v) & 0xFFF))
18851 +
18852 +/*
18853 +
18854 +  Syscall Matrix V2.8
18855 +
18856 +        |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL|
18857 +        |STATS  |DESTROY|ALTER  |CHANGE |LIMIT  |TEST   | |       |       |
18858 +        |INFO   |SETUP  |       |MOVE   |       |       | |       |       |
18859 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18860 +  SYSTEM |VERSION|VSETUP |VHOST  |       |       |       | |DEVICE |       |
18861 +  HOST   |     00|     01|     02|     03|     04|     05| |     06|     07|
18862 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18863 +  CPU    |       |VPROC  |PROCALT|PROCMIG|PROCTRL|       | |SCHED. |       |
18864 +  PROCESS|     08|     09|     10|     11|     12|     13| |     14|     15|
18865 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18866 +  MEMORY |       |       |       |       |       |       | |SWAP   |       |
18867 +        |     16|     17|     18|     19|     20|     21| |     22|     23|
18868 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18869 +  NETWORK|       |VNET   |NETALT |NETMIG |NETCTL |       | |SERIAL |       |
18870 +        |     24|     25|     26|     27|     28|     29| |     30|     31|
18871 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18872 +  DISK   |       |       |       |       |DLIMIT |       | |INODE  |       |
18873 +  VFS    |     32|     33|     34|     35|     36|     37| |     38|     39|
18874 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18875 +  OTHER  |VSTAT  |       |       |       |       |       | |VINFO  |       |
18876 +        |     40|     41|     42|     43|     44|     45| |     46|     47|
18877 +  =======+=======+=======+=======+=======+=======+=======+ +=======+=======+
18878 +  SPECIAL|EVENT  |       |       |       |FLAGS  |       | |       |       |
18879 +        |     48|     49|     50|     51|     52|     53| |     54|     55|
18880 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18881 +  SPECIAL|DEBUG  |       |       |       |RLIMIT |SYSCALL| |       |COMPAT |
18882 +        |     56|     57|     58|     59|     60|TEST 61| |     62|     63|
18883 +  -------+-------+-------+-------+-------+-------+-------+ +-------+-------+
18884 +
18885 +*/
18886 +
18887 +#define VC_CAT_VERSION         0
18888 +
18889 +#define VC_CAT_VSETUP          1
18890 +#define VC_CAT_VHOST           2
18891 +
18892 +#define VC_CAT_DEVICE          6
18893 +
18894 +#define VC_CAT_VPROC           9
18895 +#define VC_CAT_PROCALT         10
18896 +#define VC_CAT_PROCMIG         11
18897 +#define VC_CAT_PROCTRL         12
18898 +
18899 +#define VC_CAT_SCHED           14
18900 +
18901 +#define VC_CAT_VNET            25
18902 +#define VC_CAT_NETALT          26
18903 +#define VC_CAT_NETMIG          27
18904 +#define VC_CAT_NETCTRL         28
18905 +
18906 +#define VC_CAT_DLIMIT          36
18907 +#define VC_CAT_INODE           38
18908 +
18909 +#define VC_CAT_VSTAT           40
18910 +#define VC_CAT_VINFO           46
18911 +#define VC_CAT_EVENT           48
18912 +
18913 +#define VC_CAT_FLAGS           52
18914 +#define VC_CAT_DEBUG           56
18915 +#define VC_CAT_RLIMIT          60
18916 +
18917 +#define VC_CAT_SYSTEST         61
18918 +#define VC_CAT_COMPAT          63
18919 +
18920 +/*  interface version */
18921 +
18922 +#define VCI_VERSION            0x00020102
18923 +#define VCI_LEGACY_VERSION     0x000100FF
18924 +
18925 +/*  query version */
18926 +
18927 +#define VCMD_get_version       VC_CMD(VERSION, 0, 0)
18928 +#define VCMD_get_vci           VC_CMD(VERSION, 1, 0)
18929 +
18930 +
18931 +#ifdef __KERNEL__
18932 +
18933 +#include <linux/errno.h>
18934 +
18935 +
18936 +#else  /* __KERNEL__ */
18937 +#define __user
18938 +#endif /* __KERNEL__ */
18939 +
18940 +#endif /* _VX_SWITCH_H */
18941 diff -NurpP --minimal linux-2.6.19.1/include/linux/vserver/tag.h linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/tag.h
18942 --- linux-2.6.19.1/include/linux/vserver/tag.h  1970-01-01 01:00:00 +0100
18943 +++ linux-2.6.19.1-vs2.3.0.6/include/linux/vserver/tag.h        2006-12-17 04:19:20 +0100
18944 @@ -0,0 +1,147 @@
18945 +#ifndef _DX_TAG_H
18946 +#define _DX_TAG_H
18947 +
18948 +
18949 +#define DX_TAG(in)     (IS_TAGGED(in))
18950 +
18951 +
18952 +#ifdef CONFIG_DX_TAG_NFSD
18953 +#define DX_TAG_NFSD    1
18954 +#else
18955 +#define DX_TAG_NFSD    0
18956 +#endif
18957 +
18958 +
18959 +#ifdef CONFIG_TAGGING_NONE
18960 +
18961 +#define MAX_UID                0xFFFFFFFF
18962 +#define MAX_GID                0xFFFFFFFF
18963 +
18964 +#define INOTAG_TAG(cond, uid, gid, tag)        (0)
18965 +
18966 +#define TAGINO_UID(cond, uid, tag)     (uid)
18967 +#define TAGINO_GID(cond, gid, tag)     (gid)
18968 +
18969 +#endif
18970 +
18971 +
18972 +#ifdef CONFIG_TAGGING_GID16
18973 +
18974 +#define MAX_UID                0xFFFFFFFF
18975 +#define MAX_GID                0x0000FFFF
18976 +
18977 +#define INOTAG_TAG(cond, uid, gid, tag)        \
18978 +       ((cond) ? (((gid) >> 16) & 0xFFFF) : 0)
18979 +
18980 +#define TAGINO_UID(cond, uid, tag)     (uid)
18981 +#define TAGINO_GID(cond, gid, tag)     \
18982 +       ((cond) ? (((gid) & 0xFFFF) | ((tag) << 16)) : (gid))
18983 +
18984 +#endif
18985 +
18986 +
18987 +#ifdef CONFIG_TAGGING_ID24
18988 +
18989 +#define MAX_UID                0x00FFFFFF
18990 +#define MAX_GID                0x00FFFFFF
18991 +
18992 +#define INOTAG_TAG(cond, uid, gid, tag)        \
18993 +       ((cond) ? ((((uid) >> 16) & 0xFF00) | (((gid) >> 24) & 0xFF)) : 0)
18994 +
18995 +#define TAGINO_UID(cond, uid, tag)     \
18996 +       ((cond) ? (((uid) & 0xFFFFFF) | (((tag) & 0xFF00) << 16)) : (uid))
18997 +#define TAGINO_GID(cond, gid, tag)     \
18998 +       ((cond) ? (((gid) & 0xFFFFFF) | (((tag) & 0x00FF) << 24)) : (gid))
18999 +
19000 +#endif
19001 +
19002 +
19003 +#ifdef CONFIG_TAGGING_UID16
19004 +
19005 +#define MAX_UID                0x0000FFFF
19006 +#define MAX_GID                0xFFFFFFFF
19007 +
19008 +#define INOTAG_TAG(cond, uid, gid, tag)        \
19009 +       ((cond) ? (((uid) >> 16) & 0xFFFF) : 0)
19010 +
19011 +#define TAGINO_UID(cond, uid, tag)     \
19012 +       ((cond) ? (((uid) & 0xFFFF) | ((tag) << 16)) : (uid))
19013 +#define TAGINO_GID(cond, gid, tag)     (gid)
19014 +
19015 +#endif
19016 +
19017 +
19018 +#ifdef CONFIG_TAGGING_INTERN
19019 +
19020 +#define MAX_UID                0xFFFFFFFF
19021 +#define MAX_GID                0xFFFFFFFF
19022 +
19023 +#define INOTAG_TAG(cond, uid, gid, tag)        \
19024 +       ((cond) ? (tag) : 0)
19025 +
19026 +#define TAGINO_UID(cond, uid, tag)     (uid)
19027 +#define TAGINO_GID(cond, gid, tag)     (gid)
19028 +
19029 +#endif
19030 +
19031 +
19032 +#ifdef CONFIG_TAGGING_RUNTIME
19033 +
19034 +#define MAX_UID                0xFFFFFFFF
19035 +#define MAX_GID                0xFFFFFFFF
19036 +
19037 +#define INOTAG_TAG(cond, uid, gid, tag)        (0)
19038 +
19039 +#define TAGINO_UID(cond, uid, tag)     (uid)
19040 +#define TAGINO_GID(cond, gid, tag)     (gid)
19041 +
19042 +#endif
19043 +
19044 +
19045 +#ifndef CONFIG_TAGGING_NONE
19046 +#define dx_current_fstag(sb)   \
19047 +       ((sb)->s_flags & MS_TAGGED ? dx_current_tag(): 0)
19048 +#else
19049 +#define dx_current_fstag(sb)   (0)
19050 +#endif
19051 +
19052 +#ifndef CONFIG_TAGGING_INTERN
19053 +#define TAGINO_TAG(cond, tag)  (0)
19054 +#else
19055 +#define TAGINO_TAG(cond, tag)  ((cond) ? (tag) : 0)
19056 +#endif
19057 +
19058 +#define INOTAG_UID(cond, uid, gid)     \
19059 +       ((cond) ? ((uid) & MAX_UID) : (uid))
19060 +#define INOTAG_GID(cond, uid, gid)     \
19061 +       ((cond) ? ((gid) & MAX_GID) : (gid))
19062 +
19063 +
19064 +static inline uid_t dx_map_uid(uid_t uid)
19065 +{
19066 +       if ((uid > MAX_UID) && (uid != -1))
19067 +               uid = -2;
19068 +       return (uid & MAX_UID);
19069 +}
19070 +
19071 +static inline gid_t dx_map_gid(gid_t gid)
19072 +{
19073 +       if ((gid > MAX_GID) && (gid != -1))
19074 +               gid = -2;
19075 +       return (gid & MAX_GID);
19076 +}
19077 +
19078 +
19079 +#ifdef CONFIG_PROPAGATE
19080 +
19081 +int dx_parse_tag(char *string, tag_t *tag, int remove);
19082 +
19083 +void __dx_propagate_tag(struct nameidata *nd, struct inode *inode);
19084 +
19085 +#define dx_propagate_tag(n,i)  __dx_propagate_tag(n,i)
19086 +
19087 +#else
19088 +#define dx_propagate_tag(n,i)  do { } while (0)
19089 +#endif
19090 +
19091 +#endif /* _DX_TAG_H */
19092 diff -NurpP --minimal linux-2.6.19.1/include/net/af_unix.h linux-2.6.19.1-vs2.3.0.6/include/net/af_unix.h
19093 --- linux-2.6.19.1/include/net/af_unix.h        2006-09-20 16:58:44 +0200
19094 +++ linux-2.6.19.1-vs2.3.0.6/include/net/af_unix.h      2006-12-04 05:06:17 +0100
19095 @@ -4,6 +4,7 @@
19096  #include <linux/socket.h>
19097  #include <linux/un.h>
19098  #include <linux/mutex.h>
19099 +#include <linux/vs_base.h>
19100  #include <net/sock.h>
19101  
19102  extern void unix_inflight(struct file *fp);
19103 @@ -17,9 +18,9 @@ extern spinlock_t unix_table_lock;
19104  
19105  extern atomic_t unix_tot_inflight;
19106  
19107 -static inline struct sock *first_unix_socket(int *i)
19108 +static inline struct sock *next_unix_socket_table(int *i)
19109  {
19110 -       for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
19111 +       for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
19112                 if (!hlist_empty(&unix_socket_table[*i]))
19113                         return __sk_head(&unix_socket_table[*i]);
19114         }
19115 @@ -28,16 +29,19 @@ static inline struct sock *first_unix_so
19116  
19117  static inline struct sock *next_unix_socket(int *i, struct sock *s)
19118  {
19119 -       struct sock *next = sk_next(s);
19120 -       /* More in this chain? */
19121 -       if (next)
19122 -               return next;
19123 -       /* Look for next non-empty chain. */
19124 -       for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
19125 -               if (!hlist_empty(&unix_socket_table[*i]))
19126 -                       return __sk_head(&unix_socket_table[*i]);
19127 -       }
19128 -       return NULL;
19129 +       do {
19130 +               if (s)
19131 +                       s = sk_next(s);
19132 +               if (!s)
19133 +                       s = next_unix_socket_table(i);
19134 +       } while (s && !nx_check(s->sk_nid, VS_WATCH_P|VS_IDENT));
19135 +       return s;
19136 +}
19137 +
19138 +static inline struct sock *first_unix_socket(int *i)
19139 +{
19140 +       *i = 0;
19141 +       return next_unix_socket(i, NULL);
19142  }
19143  
19144  #define forall_unix_sockets(i, s) \
19145 diff -NurpP --minimal linux-2.6.19.1/include/net/inet_hashtables.h linux-2.6.19.1-vs2.3.0.6/include/net/inet_hashtables.h
19146 --- linux-2.6.19.1/include/net/inet_hashtables.h        2006-11-30 21:19:40 +0100
19147 +++ linux-2.6.19.1-vs2.3.0.6/include/net/inet_hashtables.h      2006-11-08 04:57:42 +0100
19148 @@ -271,6 +271,26 @@ static inline int inet_iif(const struct 
19149         return ((struct rtable *)skb->dst)->rt_iif;
19150  }
19151  
19152 +/*
19153 + *      Check if a given address matches for an inet socket
19154 + *
19155 + *      nxi:   the socket's nx_info if any
19156 + *      addr:  to be verified address
19157 + *      saddr: socket addresses
19158 + */
19159 +static inline int inet_addr_match (
19160 +       struct nx_info *nxi,
19161 +       uint32_t addr,
19162 +       uint32_t saddr)
19163 +{
19164 +       if (addr && (saddr == addr))
19165 +               return 1;
19166 +       if (!saddr)
19167 +               return addr_in_nx_info(nxi, addr);
19168 +       return 0;
19169 +}
19170 +
19171 +
19172  extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
19173                                            const __be32 daddr,
19174                                            const unsigned short hnum,
19175 diff -NurpP --minimal linux-2.6.19.1/include/net/inet_sock.h linux-2.6.19.1-vs2.3.0.6/include/net/inet_sock.h
19176 --- linux-2.6.19.1/include/net/inet_sock.h      2006-11-30 21:19:40 +0100
19177 +++ linux-2.6.19.1-vs2.3.0.6/include/net/inet_sock.h    2006-11-08 04:57:42 +0100
19178 @@ -112,6 +112,7 @@ struct inet_sock {
19179         /* Socket demultiplex comparisons on incoming packets. */
19180         __be32                  daddr;
19181         __be32                  rcv_saddr;
19182 +       __be32                  rcv_saddr2;     /* Second bound ipv4 addr, for ipv4root */
19183         __be16                  dport;
19184         __u16                   num;
19185         __be32                  saddr;
19186 diff -NurpP --minimal linux-2.6.19.1/include/net/inet_timewait_sock.h linux-2.6.19.1-vs2.3.0.6/include/net/inet_timewait_sock.h
19187 --- linux-2.6.19.1/include/net/inet_timewait_sock.h     2006-11-30 21:19:40 +0100
19188 +++ linux-2.6.19.1-vs2.3.0.6/include/net/inet_timewait_sock.h   2006-11-08 04:57:42 +0100
19189 @@ -115,6 +115,10 @@ struct inet_timewait_sock {
19190  #define tw_refcnt              __tw_common.skc_refcnt
19191  #define tw_hash                        __tw_common.skc_hash
19192  #define tw_prot                        __tw_common.skc_prot
19193 +#define tw_xid         __tw_common.skc_xid
19194 +#define tw_vx_info             __tw_common.skc_vx_info
19195 +#define tw_nid         __tw_common.skc_nid
19196 +#define tw_nx_info             __tw_common.skc_nx_info
19197         volatile unsigned char  tw_substate;
19198         /* 3 bits hole, try to pack */
19199         unsigned char           tw_rcv_wscale;
19200 diff -NurpP --minimal linux-2.6.19.1/include/net/route.h linux-2.6.19.1-vs2.3.0.6/include/net/route.h
19201 --- linux-2.6.19.1/include/net/route.h  2006-11-30 21:19:40 +0100
19202 +++ linux-2.6.19.1-vs2.3.0.6/include/net/route.h        2006-12-17 03:25:02 +0100
19203 @@ -27,12 +27,16 @@
19204  #include <net/dst.h>
19205  #include <net/inetpeer.h>
19206  #include <net/flow.h>
19207 +#include <net/inet_sock.h>
19208  #include <linux/in_route.h>
19209  #include <linux/rtnetlink.h>
19210  #include <linux/route.h>
19211  #include <linux/ip.h>
19212  #include <linux/cache.h>
19213  #include <linux/security.h>
19214 +#include <linux/vs_base.h>
19215 +#include <linux/vs_inet.h>
19216 +#include <linux/in.h>
19217  
19218  #ifndef __KERNEL__
19219  #warning This file is not supposed to be used outside of kernel.
19220 @@ -144,6 +148,8 @@ static inline char rt_tos2priority(u8 to
19221         return ip_tos2prio[IPTOS_TOS(tos)>>1];
19222  }
19223  
19224 +#include "route_vs.h"
19225 +
19226  static inline int ip_route_connect(struct rtable **rp, __be32 dst,
19227                                    __be32 src, u32 tos, int oif, u8 protocol,
19228                                    __be16 sport, __be16 dport, struct sock *sk)
19229 @@ -158,7 +164,21 @@ static inline int ip_route_connect(struc
19230                                          .dport = dport } } };
19231  
19232         int err;
19233 -       if (!dst || !src) {
19234 +       struct nx_info *nx_info = current->nx_info;
19235 +
19236 +       if (sk)
19237 +               nx_info = sk->sk_nx_info;
19238 +
19239 +       vxdprintk(VXD_CBIT(net, 4),
19240 +               "ip_route_connect(%p) %p,%p;%lx",
19241 +               sk, nx_info, sk->sk_socket,
19242 +               (sk->sk_socket?sk->sk_socket->flags:0));
19243 +
19244 +       err = ip_find_src(nx_info, rp, &fl);
19245 +       if (err)
19246 +               return err;
19247 +
19248 +       if (!fl.fl4_dst || !fl.fl4_src) {
19249                 err = __ip_route_output_key(rp, &fl);
19250                 if (err)
19251                         return err;
19252 diff -NurpP --minimal linux-2.6.19.1/include/net/route_vs.h linux-2.6.19.1-vs2.3.0.6/include/net/route_vs.h
19253 --- linux-2.6.19.1/include/net/route_vs.h       1970-01-01 01:00:00 +0100
19254 +++ linux-2.6.19.1-vs2.3.0.6/include/net/route_vs.h     2006-12-17 03:47:12 +0100
19255 @@ -0,0 +1,64 @@
19256 +
19257 +static inline int ip_find_src(struct nx_info *nxi, struct rtable **rp, struct flowi *fl)
19258 +{
19259 +       int err;
19260 +       int i, n;
19261 +       uint32_t ipv4root;
19262 +
19263 +       if (!nxi)
19264 +               return 0;
19265 +
19266 +       ipv4root = nxi->ipv4[0];
19267 +       if (ipv4root == 0)
19268 +               return 0;
19269 +
19270 +       n = nxi->nbipv4;
19271 +       if (fl->fl4_src == 0) {
19272 +               if (n > 1) {
19273 +                       u32 foundsrc;
19274 +
19275 +                       err = __ip_route_output_key(rp, fl);
19276 +                       if (err) {
19277 +                               fl->fl4_src = ipv4root;
19278 +                               err = __ip_route_output_key(rp, fl);
19279 +                       }
19280 +                       if (err)
19281 +                               return err;
19282 +
19283 +                       foundsrc = (*rp)->rt_src;
19284 +                       ip_rt_put(*rp);
19285 +
19286 +                       for (i=0; i<n; i++){
19287 +                               u32 mask = nxi->mask[i];
19288 +                               u32 ipv4 = nxi->ipv4[i];
19289 +                               u32 net4 = ipv4 & mask;
19290 +
19291 +                               if (foundsrc == ipv4) {
19292 +                                       fl->fl4_src = ipv4;
19293 +                                       break;
19294 +                               }
19295 +                               if (!fl->fl4_src && (foundsrc & mask) == net4)
19296 +                                       fl->fl4_src = ipv4;
19297 +                       }
19298 +               }
19299 +               if (fl->fl4_src == 0)
19300 +                       fl->fl4_src = (fl->fl4_dst == IPI_LOOPBACK)
19301 +                               ? IPI_LOOPBACK : ipv4root;
19302 +       } else {
19303 +               for (i=0; i<n; i++) {
19304 +                       if (nxi->ipv4[i] == fl->fl4_src)
19305 +                               break;
19306 +               }
19307 +               if (i == n)
19308 +                       return -EPERM;
19309 +       }
19310 +
19311 +       if (fl->fl4_dst == IPI_LOOPBACK && !nx_check(0, VS_ADMIN))
19312 +               fl->fl4_dst = nxi->ipv4[0];
19313 +#ifdef CONFIG_VSERVER_REMAP_SADDR
19314 +       if (fl->fl4_src == IPI_LOOPBACK && !nx_check(0, VS_ADMIN))
19315 +               fl->fl4_src = nxi->ipv4[0];
19316 +#endif
19317 +       return 0;
19318 +}
19319 +
19320 diff -NurpP --minimal linux-2.6.19.1/include/net/sock.h linux-2.6.19.1-vs2.3.0.6/include/net/sock.h
19321 --- linux-2.6.19.1/include/net/sock.h   2006-11-30 21:19:41 +0100
19322 +++ linux-2.6.19.1-vs2.3.0.6/include/net/sock.h 2006-11-30 20:55:45 +0100
19323 @@ -118,6 +118,10 @@ struct sock_common {
19324         atomic_t                skc_refcnt;
19325         unsigned int            skc_hash;
19326         struct proto            *skc_prot;
19327 +       xid_t                   skc_xid;
19328 +       struct vx_info          *skc_vx_info;
19329 +       nid_t                   skc_nid;
19330 +       struct nx_info          *skc_nx_info;
19331  };
19332  
19333  /**
19334 @@ -194,6 +198,10 @@ struct sock {
19335  #define sk_refcnt              __sk_common.skc_refcnt
19336  #define sk_hash                        __sk_common.skc_hash
19337  #define sk_prot                        __sk_common.skc_prot
19338 +#define sk_xid                 __sk_common.skc_xid
19339 +#define sk_vx_info             __sk_common.skc_vx_info
19340 +#define sk_nid                 __sk_common.skc_nid
19341 +#define sk_nx_info             __sk_common.skc_nx_info
19342         unsigned char           sk_shutdown : 2,
19343                                 sk_no_check : 2,
19344                                 sk_userlocks : 4;
19345 diff -NurpP --minimal linux-2.6.19.1/init/Makefile linux-2.6.19.1-vs2.3.0.6/init/Makefile
19346 --- linux-2.6.19.1/init/Makefile        2006-09-20 16:58:44 +0200
19347 +++ linux-2.6.19.1-vs2.3.0.6/init/Makefile      2006-12-06 21:16:15 +0100
19348 @@ -15,6 +15,7 @@ clean-files := ../include/linux/compile.
19349  
19350  # dependencies on generated files need to be listed explicitly
19351  
19352 +$(obj)/main.o: include/linux/compile.h
19353  $(obj)/version.o: include/linux/compile.h
19354  
19355  # compile.h changes depending on hostname, generation number, etc,
19356 diff -NurpP --minimal linux-2.6.19.1/init/main.c linux-2.6.19.1-vs2.3.0.6/init/main.c
19357 --- linux-2.6.19.1/init/main.c  2006-11-30 21:19:43 +0100
19358 +++ linux-2.6.19.1-vs2.3.0.6/init/main.c        2006-12-06 08:48:35 +0100
19359 @@ -49,6 +49,8 @@
19360  #include <linux/buffer_head.h>
19361  #include <linux/debug_locks.h>
19362  #include <linux/lockdep.h>
19363 +#include <linux/utsrelease.h>
19364 +#include <linux/compile.h>
19365  
19366  #include <asm/io.h>
19367  #include <asm/bugs.h>
19368 @@ -501,7 +503,7 @@ asmlinkage void __init start_kernel(void
19369         boot_cpu_init();
19370         page_address_init();
19371         printk(KERN_NOTICE);
19372 -       printk(linux_banner);
19373 +       printk(linux_banner, UTS_RELEASE, UTS_VERSION);
19374         setup_arch(&command_line);
19375         unwind_setup();
19376         setup_per_cpu_areas();
19377 diff -NurpP --minimal linux-2.6.19.1/init/version.c linux-2.6.19.1-vs2.3.0.6/init/version.c
19378 --- linux-2.6.19.1/init/version.c       2006-11-30 21:19:43 +0100
19379 +++ linux-2.6.19.1-vs2.3.0.6/init/version.c     2006-12-06 08:48:35 +0100
19380 @@ -35,5 +35,6 @@ struct uts_namespace init_uts_ns = {
19381  EXPORT_SYMBOL_GPL(init_uts_ns);
19382  
19383  const char linux_banner[] =
19384 -       "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
19385 -       LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
19386 +       "Linux version %s (" LINUX_COMPILE_BY "@"
19387 +       LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") %s\n";
19388 +
19389 diff -NurpP --minimal linux-2.6.19.1/ipc/mqueue.c linux-2.6.19.1-vs2.3.0.6/ipc/mqueue.c
19390 --- linux-2.6.19.1/ipc/mqueue.c 2006-11-30 21:19:43 +0100
19391 +++ linux-2.6.19.1-vs2.3.0.6/ipc/mqueue.c       2006-11-08 04:57:52 +0100
19392 @@ -29,6 +29,8 @@
19393  #include <linux/audit.h>
19394  #include <linux/signal.h>
19395  #include <linux/mutex.h>
19396 +#include <linux/vs_context.h>
19397 +#include <linux/vs_limit.h>
19398  
19399  #include <net/sock.h>
19400  #include "util.h"
19401 @@ -151,17 +153,20 @@ static struct inode *mqueue_get_inode(st
19402                         spin_lock(&mq_lock);
19403                         if (u->mq_bytes + mq_bytes < u->mq_bytes ||
19404                             u->mq_bytes + mq_bytes >
19405 -                           p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur) {
19406 +                           p->signal->rlim[RLIMIT_MSGQUEUE].rlim_cur ||
19407 +                           !vx_ipcmsg_avail(p->vx_info, mq_bytes)) {
19408                                 spin_unlock(&mq_lock);
19409                                 goto out_inode;
19410                         }
19411                         u->mq_bytes += mq_bytes;
19412 +                       vx_ipcmsg_add(p->vx_info, u, mq_bytes);
19413                         spin_unlock(&mq_lock);
19414  
19415                         info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
19416                         if (!info->messages) {
19417                                 spin_lock(&mq_lock);
19418                                 u->mq_bytes -= mq_bytes;
19419 +                               vx_ipcmsg_sub(p->vx_info, u, mq_bytes);
19420                                 spin_unlock(&mq_lock);
19421                                 goto out_inode;
19422                         }
19423 @@ -259,10 +264,14 @@ static void mqueue_delete_inode(struct i
19424                    (info->attr.mq_maxmsg * info->attr.mq_msgsize));
19425         user = info->user;
19426         if (user) {
19427 +               struct vx_info *vxi = lookup_vx_info(user->xid);
19428 +
19429                 spin_lock(&mq_lock);
19430                 user->mq_bytes -= mq_bytes;
19431 +               vx_ipcmsg_sub(vxi, user, mq_bytes);
19432                 queues_count--;
19433                 spin_unlock(&mq_lock);
19434 +               put_vx_info(vxi);
19435                 free_uid(user);
19436         }
19437  }
19438 @@ -747,7 +756,7 @@ asmlinkage long sys_mq_unlink(const char
19439         if (inode)
19440                 atomic_inc(&inode->i_count);
19441  
19442 -       err = vfs_unlink(dentry->d_parent->d_inode, dentry);
19443 +       err = vfs_unlink(dentry->d_parent->d_inode, dentry, NULL);
19444  out_err:
19445         dput(dentry);
19446  
19447 diff -NurpP --minimal linux-2.6.19.1/ipc/msg.c linux-2.6.19.1-vs2.3.0.6/ipc/msg.c
19448 --- linux-2.6.19.1/ipc/msg.c    2006-11-30 21:19:43 +0100
19449 +++ linux-2.6.19.1-vs2.3.0.6/ipc/msg.c  2006-11-30 18:53:18 +0100
19450 @@ -36,6 +36,7 @@
19451  #include <linux/seq_file.h>
19452  #include <linux/mutex.h>
19453  #include <linux/nsproxy.h>
19454 +#include <linux/vs_base.h>
19455  
19456  #include <asm/current.h>
19457  #include <asm/uaccess.h>
19458 @@ -149,6 +150,7 @@ static int newque (struct ipc_namespace 
19459  
19460         msq->q_perm.mode = msgflg & S_IRWXUGO;
19461         msq->q_perm.key = key;
19462 +       msq->q_perm.xid = vx_current_xid();
19463  
19464         msq->q_perm.security = NULL;
19465         retval = security_msg_queue_alloc(msq);
19466 @@ -903,6 +905,9 @@ static int sysvipc_msg_proc_show(struct 
19467  {
19468         struct msg_queue *msq = it;
19469  
19470 +       if (!vx_check(msq->q_perm.xid, VS_WATCH_P|VS_IDENT))
19471 +               return 0;
19472 +
19473         return seq_printf(s,
19474                         "%10d %10d  %4o  %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
19475                         msq->q_perm.key,
19476 diff -NurpP --minimal linux-2.6.19.1/ipc/sem.c linux-2.6.19.1-vs2.3.0.6/ipc/sem.c
19477 --- linux-2.6.19.1/ipc/sem.c    2006-11-30 21:19:43 +0100
19478 +++ linux-2.6.19.1-vs2.3.0.6/ipc/sem.c  2006-11-30 18:53:18 +0100
19479 @@ -83,6 +83,8 @@
19480  #include <linux/seq_file.h>
19481  #include <linux/mutex.h>
19482  #include <linux/nsproxy.h>
19483 +#include <linux/vs_base.h>
19484 +#include <linux/vs_limit.h>
19485  
19486  #include <asm/uaccess.h>
19487  #include "util.h"
19488 @@ -230,6 +232,7 @@ static int newary (struct ipc_namespace 
19489  
19490         sma->sem_perm.mode = (semflg & S_IRWXUGO);
19491         sma->sem_perm.key = key;
19492 +       sma->sem_perm.xid = vx_current_xid();
19493  
19494         sma->sem_perm.security = NULL;
19495         retval = security_sem_alloc(sma);
19496 @@ -245,6 +248,9 @@ static int newary (struct ipc_namespace 
19497                 return -ENOSPC;
19498         }
19499         ns->used_sems += nsems;
19500 +       /* FIXME: obsoleted? */
19501 +       vx_semary_inc(sma);
19502 +       vx_nsems_add(sma, nsems);
19503  
19504         sma->sem_id = sem_buildid(ns, id, sma->sem_perm.seq);
19505         sma->sem_base = (struct sem *) &sma[1];
19506 @@ -526,6 +532,9 @@ static void freeary (struct ipc_namespac
19507         sem_unlock(sma);
19508  
19509         ns->used_sems -= sma->sem_nsems;
19510 +       /* FIXME: obsoleted? */
19511 +       vx_nsems_sub(sma, sma->sem_nsems);
19512 +       vx_semary_dec(sma);
19513         size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
19514         security_sem_free(sma);
19515         ipc_rcu_putref(sma);
19516 @@ -1403,6 +1412,9 @@ static int sysvipc_sem_proc_show(struct 
19517  {
19518         struct sem_array *sma = it;
19519  
19520 +       if (!vx_check(sma->sem_perm.xid, VS_WATCH_P|VS_IDENT))
19521 +               return 0;
19522 +
19523         return seq_printf(s,
19524                           "%10d %10d  %4o %10lu %5u %5u %5u %5u %10lu %10lu\n",
19525                           sma->sem_perm.key,
19526 diff -NurpP --minimal linux-2.6.19.1/ipc/shm.c linux-2.6.19.1-vs2.3.0.6/ipc/shm.c
19527 --- linux-2.6.19.1/ipc/shm.c    2006-11-30 21:19:43 +0100
19528 +++ linux-2.6.19.1-vs2.3.0.6/ipc/shm.c  2006-11-30 18:53:18 +0100
19529 @@ -37,6 +37,8 @@
19530  #include <linux/seq_file.h>
19531  #include <linux/mutex.h>
19532  #include <linux/nsproxy.h>
19533 +#include <linux/vs_context.h>
19534 +#include <linux/vs_limit.h>
19535  
19536  #include <asm/uaccess.h>
19537  
19538 @@ -181,7 +183,12 @@ static void shm_open(struct vm_area_stru
19539   */
19540  static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
19541  {
19542 -       ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
19543 +       struct vx_info *vxi = lookup_vx_info(shp->shm_perm.xid);
19544 +       int numpages = (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
19545 +
19546 +       vx_ipcshm_sub(vxi, shp, numpages);
19547 +       ns->shm_tot -= numpages;
19548 +
19549         shm_rmid(ns, shp->id);
19550         shm_unlock(shp);
19551         if (!is_file_hugepages(shp->shm_file))
19552 @@ -191,6 +198,7 @@ static void shm_destroy(struct ipc_names
19553                                                 shp->mlock_user);
19554         fput (shp->shm_file);
19555         security_shm_free(shp);
19556 +       put_vx_info(vxi);
19557         ipc_rcu_putref(shp);
19558  }
19559  
19560 @@ -282,11 +290,15 @@ static int newseg (struct ipc_namespace 
19561         if (ns->shm_tot + numpages >= ns->shm_ctlall)
19562                 return -ENOSPC;
19563  
19564 +       if (!vx_ipcshm_avail(current->vx_info, numpages))
19565 +               return -ENOSPC;
19566 +
19567         shp = ipc_rcu_alloc(sizeof(*shp));
19568         if (!shp)
19569                 return -ENOMEM;
19570  
19571         shp->shm_perm.key = key;
19572 +       shp->shm_perm.xid = vx_current_xid();
19573         shp->shm_perm.mode = (shmflg & S_IRWXUGO);
19574         shp->mlock_user = NULL;
19575  
19576 @@ -339,6 +351,7 @@ static int newseg (struct ipc_namespace 
19577                 file->f_op = &shm_file_operations;
19578  
19579         ns->shm_tot += numpages;
19580 +       vx_ipcshm_add(current->vx_info, key, numpages);
19581         shm_unlock(shp);
19582         return shp->id;
19583  
19584 @@ -993,6 +1006,9 @@ static int sysvipc_shm_proc_show(struct 
19585  #define SMALL_STRING "%10d %10d  %4o %10u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
19586  #define BIG_STRING   "%10d %10d  %4o %21u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
19587  
19588 +       if (!vx_check(shp->shm_perm.xid, VS_WATCH_P|VS_IDENT))
19589 +               return 0;
19590 +
19591         if (sizeof(size_t) <= sizeof(int))
19592                 format = SMALL_STRING;
19593         else
19594 diff -NurpP --minimal linux-2.6.19.1/ipc/util.c linux-2.6.19.1-vs2.3.0.6/ipc/util.c
19595 --- linux-2.6.19.1/ipc/util.c   2006-11-30 21:19:43 +0100
19596 +++ linux-2.6.19.1-vs2.3.0.6/ipc/util.c 2006-11-30 18:53:18 +0100
19597 @@ -33,6 +33,7 @@
19598  #include <linux/proc_fs.h>
19599  #include <linux/audit.h>
19600  #include <linux/nsproxy.h>
19601 +#include <linux/vs_base.h>
19602  
19603  #include <asm/unistd.h>
19604  
19605 @@ -261,7 +262,9 @@ int ipc_findkey(struct ipc_ids* ids, key
19606          */
19607         for (id = 0; id <= max_id; id++) {
19608                 p = ids->entries->p[id];
19609 -               if(p==NULL)
19610 +               if (p==NULL)
19611 +                       continue;
19612 +               if (!vx_check(p->xid, VS_WATCH_P|VS_IDENT))
19613                         continue;
19614                 if (key == p->key)
19615                         return id;
19616 @@ -574,6 +577,9 @@ int ipcperms (struct kern_ipc_perm *ipcp
19617  
19618         if (unlikely((err = audit_ipc_obj(ipcp))))
19619                 return err;
19620 +
19621 +       if (!vx_check(ipcp->xid, VS_WATCH_P|VS_IDENT)) /* maybe just VS_IDENT? */
19622 +               return -1;
19623         requested_mode = (flag >> 6) | (flag >> 3) | flag;
19624         granted_mode = ipcp->mode;
19625         if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
19626 diff -NurpP --minimal linux-2.6.19.1/kernel/Makefile linux-2.6.19.1-vs2.3.0.6/kernel/Makefile
19627 --- linux-2.6.19.1/kernel/Makefile      2006-11-30 21:19:43 +0100
19628 +++ linux-2.6.19.1-vs2.3.0.6/kernel/Makefile    2006-11-08 23:23:13 +0100
19629 @@ -10,6 +10,8 @@ obj-y     = sched.o fork.o exec_domain.o
19630             kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
19631             hrtimer.o rwsem.o latency.o nsproxy.o srcu.o
19632  
19633 +obj-y    += vserver/
19634 +
19635  obj-$(CONFIG_STACKTRACE) += stacktrace.o
19636  obj-y += time/
19637  obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
19638 diff -NurpP --minimal linux-2.6.19.1/kernel/capability.c linux-2.6.19.1-vs2.3.0.6/kernel/capability.c
19639 --- linux-2.6.19.1/kernel/capability.c  2006-11-30 21:19:43 +0100
19640 +++ linux-2.6.19.1-vs2.3.0.6/kernel/capability.c        2006-11-30 19:37:57 +0100
19641 @@ -12,6 +12,7 @@
19642  #include <linux/module.h>
19643  #include <linux/security.h>
19644  #include <linux/syscalls.h>
19645 +#include <linux/vs_context.h>
19646  #include <asm/uaccess.h>
19647  
19648  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
19649 @@ -244,8 +245,12 @@ int __capable(struct task_struct *t, int
19650  }
19651  EXPORT_SYMBOL(__capable);
19652  
19653 +#include <linux/vserver/base.h>
19654  int capable(int cap)
19655  {
19656 +       /* here for now so we don't require task locking */
19657 +       if (vs_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap))
19658 +               return 0;
19659         return __capable(current, cap);
19660  }
19661  EXPORT_SYMBOL(capable);
19662 diff -NurpP --minimal linux-2.6.19.1/kernel/compat.c linux-2.6.19.1-vs2.3.0.6/kernel/compat.c
19663 --- linux-2.6.19.1/kernel/compat.c      2006-11-30 21:19:43 +0100
19664 +++ linux-2.6.19.1-vs2.3.0.6/kernel/compat.c    2006-11-08 21:52:09 +0100
19665 @@ -846,7 +846,7 @@ asmlinkage long compat_sys_time(compat_t
19666         compat_time_t i;
19667         struct timeval tv;
19668  
19669 -       do_gettimeofday(&tv);
19670 +       vx_gettimeofday(&tv);
19671         i = tv.tv_sec;
19672  
19673         if (tloc) {
19674 @@ -870,7 +870,7 @@ asmlinkage long compat_sys_stime(compat_
19675         if (err)
19676                 return err;
19677  
19678 -       do_settimeofday(&tv);
19679 +       vx_settimeofday(&tv);
19680         return 0;
19681  }
19682  
19683 diff -NurpP --minimal linux-2.6.19.1/kernel/exit.c linux-2.6.19.1-vs2.3.0.6/kernel/exit.c
19684 --- linux-2.6.19.1/kernel/exit.c        2006-11-30 21:19:43 +0100
19685 +++ linux-2.6.19.1-vs2.3.0.6/kernel/exit.c      2006-11-08 04:57:53 +0100
19686 @@ -41,6 +41,9 @@
19687  #include <linux/audit.h> /* for audit_free() */
19688  #include <linux/resource.h>
19689  #include <linux/blkdev.h>
19690 +#include <linux/vs_limit.h>
19691 +#include <linux/vs_context.h>
19692 +#include <linux/vs_network.h>
19693  
19694  #include <asm/uaccess.h>
19695  #include <asm/unistd.h>
19696 @@ -437,9 +440,11 @@ static void close_files(struct files_str
19697                                 struct file * file = xchg(&fdt->fd[i], NULL);
19698                                 if (file)
19699                                         filp_close(file, files);
19700 +                               vx_openfd_dec(i);
19701                         }
19702                         i++;
19703                         set >>= 1;
19704 +                       cond_resched();
19705                 }
19706         }
19707  }
19708 @@ -592,6 +597,11 @@ static void exit_mm(struct task_struct *
19709  static inline void
19710  choose_new_parent(struct task_struct *p, struct task_struct *reaper)
19711  {
19712 +       /* check for reaper context */
19713 +       vxwprintk((p->xid != reaper->xid) && (reaper != child_reaper),
19714 +               "rogue reaper: %p[%d,#%u] <> %p[%d,#%u]",
19715 +               p, p->pid, p->xid, reaper, reaper->pid, reaper->xid);
19716 +
19717         /*
19718          * Make sure we're not reparenting to ourselves and that
19719          * the parent is not a zombie.
19720 @@ -674,7 +684,7 @@ forget_original_parent(struct task_struc
19721         do {
19722                 reaper = next_thread(reaper);
19723                 if (reaper == father) {
19724 -                       reaper = child_reaper;
19725 +                       reaper = vx_child_reaper(father);
19726                         break;
19727                 }
19728         } while (reaper->exit_state);
19729 @@ -698,7 +708,7 @@ forget_original_parent(struct task_struc
19730  
19731                 if (father == p->real_parent) {
19732                         /* reparent with a reaper, real father it's us */
19733 -                       choose_new_parent(p, reaper);
19734 +                       choose_new_parent(p, vx_child_reaper(p));
19735                         reparent_thread(p, father, 0);
19736                 } else {
19737                         /* reparent ptraced task to its real parent */
19738 @@ -934,6 +944,8 @@ fastcall NORET_TYPE void do_exit(long co
19739  
19740         tsk->exit_code = code;
19741         proc_exit_connector(tsk);
19742 +       /* needs to stay before exit_notify() */
19743 +       exit_vx_info_early(tsk, code);
19744         exit_notify(tsk);
19745         exit_task_namespaces(tsk);
19746  #ifdef CONFIG_NUMA
19747 @@ -959,6 +971,10 @@ fastcall NORET_TYPE void do_exit(long co
19748         if (tsk->splice_pipe)
19749                 __free_pipe_info(tsk->splice_pipe);
19750  
19751 +       /* needs to stay after exit_notify() */
19752 +       exit_vx_info(tsk, code);
19753 +       exit_nx_info(tsk);
19754 +
19755         preempt_disable();
19756         /* causes final put_task_struct in finish_task_switch(). */
19757         tsk->state = TASK_DEAD;
19758 diff -NurpP --minimal linux-2.6.19.1/kernel/fork.c linux-2.6.19.1-vs2.3.0.6/kernel/fork.c
19759 --- linux-2.6.19.1/kernel/fork.c        2006-11-30 21:19:43 +0100
19760 +++ linux-2.6.19.1-vs2.3.0.6/kernel/fork.c      2006-11-30 20:55:45 +0100
19761 @@ -48,6 +48,10 @@
19762  #include <linux/delayacct.h>
19763  #include <linux/taskstats_kern.h>
19764  #include <linux/random.h>
19765 +#include <linux/vs_context.h>
19766 +#include <linux/vs_network.h>
19767 +#include <linux/vs_limit.h>
19768 +#include <linux/vs_memory.h>
19769  
19770  #include <asm/pgtable.h>
19771  #include <asm/pgalloc.h>
19772 @@ -107,6 +111,8 @@ void free_task(struct task_struct *tsk)
19773  {
19774         free_thread_info(tsk->thread_info);
19775         rt_mutex_debug_task_free(tsk);
19776 +       clr_vx_info(&tsk->vx_info);
19777 +       clr_nx_info(&tsk->nx_info);
19778         free_task_struct(tsk);
19779  }
19780  EXPORT_SYMBOL(free_task);
19781 @@ -214,6 +220,8 @@ static inline int dup_mmap(struct mm_str
19782         mm->free_area_cache = oldmm->mmap_base;
19783         mm->cached_hole_size = ~0UL;
19784         mm->map_count = 0;
19785 +       __set_mm_counter(mm, file_rss, 0);
19786 +       __set_mm_counter(mm, anon_rss, 0);
19787         cpus_clear(mm->cpu_vm_mask);
19788         mm->mm_rb = RB_ROOT;
19789         rb_link = &mm->mm_rb.rb_node;
19790 @@ -225,7 +233,7 @@ static inline int dup_mmap(struct mm_str
19791  
19792                 if (mpnt->vm_flags & VM_DONTCOPY) {
19793                         long pages = vma_pages(mpnt);
19794 -                       mm->total_vm -= pages;
19795 +                       vx_vmpages_sub(mm, pages);
19796                         vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
19797                                                                 -pages);
19798                         continue;
19799 @@ -332,8 +340,6 @@ static struct mm_struct * mm_init(struct
19800         INIT_LIST_HEAD(&mm->mmlist);
19801         mm->core_waiters = 0;
19802         mm->nr_ptes = 0;
19803 -       set_mm_counter(mm, file_rss, 0);
19804 -       set_mm_counter(mm, anon_rss, 0);
19805         spin_lock_init(&mm->page_table_lock);
19806         rwlock_init(&mm->ioctx_list_lock);
19807         mm->ioctx_list = NULL;
19808 @@ -342,6 +348,7 @@ static struct mm_struct * mm_init(struct
19809  
19810         if (likely(!mm_alloc_pgd(mm))) {
19811                 mm->def_flags = 0;
19812 +               set_vx_info(&mm->mm_vx_info, current->vx_info);
19813                 return mm;
19814         }
19815         free_mm(mm);
19816 @@ -373,6 +380,7 @@ void fastcall __mmdrop(struct mm_struct 
19817         BUG_ON(mm == &init_mm);
19818         mm_free_pgd(mm);
19819         destroy_context(mm);
19820 +       clr_vx_info(&mm->mm_vx_info);
19821         free_mm(mm);
19822  }
19823  
19824 @@ -478,6 +486,7 @@ static struct mm_struct *dup_mm(struct t
19825                 goto fail_nomem;
19826  
19827         memcpy(mm, oldmm, sizeof(*mm));
19828 +       mm->mm_vx_info = NULL;
19829  
19830         if (!mm_init(mm))
19831                 goto fail_nomem;
19832 @@ -505,6 +514,7 @@ fail_nocontext:
19833          * If init_new_context() failed, we cannot use mmput() to free the mm
19834          * because it calls destroy_context()
19835          */
19836 +       clr_vx_info(&mm->mm_vx_info);
19837         mm_free_pgd(mm);
19838         free_mm(mm);
19839         return NULL;
19840 @@ -700,6 +710,8 @@ static struct files_struct *dup_fd(struc
19841                 struct file *f = *old_fds++;
19842                 if (f) {
19843                         get_file(f);
19844 +                       /* FIXME: sum it first for check and performance */
19845 +                       vx_openfd_inc(open_files - i);
19846                 } else {
19847                         /*
19848                          * The fd may be claimed in the fd bitmap but not yet
19849 @@ -955,6 +967,8 @@ static struct task_struct *copy_process(
19850  {
19851         int retval;
19852         struct task_struct *p = NULL;
19853 +       struct vx_info *vxi;
19854 +       struct nx_info *nxi;
19855  
19856         if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
19857                 return ERR_PTR(-EINVAL);
19858 @@ -989,12 +1003,30 @@ static struct task_struct *copy_process(
19859         DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
19860         DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
19861  #endif
19862 +       init_vx_info(&p->vx_info, current->vx_info);
19863 +       init_nx_info(&p->nx_info, current->nx_info);
19864 +
19865 +       /* check vserver memory */
19866 +       if (p->mm && !(clone_flags & CLONE_VM)) {
19867 +               if (vx_vmpages_avail(p->mm, p->mm->total_vm))
19868 +                       vx_pages_add(p->vx_info, RLIMIT_AS, p->mm->total_vm);
19869 +               else
19870 +                       goto bad_fork_free;
19871 +       }
19872 +       if (p->mm && vx_flags(VXF_FORK_RSS, 0)) {
19873 +               if (!vx_rss_avail(p->mm, get_mm_counter(p->mm, file_rss)))
19874 +                       goto bad_fork_cleanup_vm;
19875 +       }
19876 +
19877         retval = -EAGAIN;
19878 +       if (!vx_nproc_avail(1))
19879 +               goto bad_fork_cleanup_vm;
19880 +
19881         if (atomic_read(&p->user->processes) >=
19882                         p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
19883                 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
19884                                 p->user != &root_user)
19885 -                       goto bad_fork_free;
19886 +                       goto bad_fork_cleanup_vm;
19887         }
19888  
19889         atomic_inc(&p->user->__count);
19890 @@ -1256,6 +1288,18 @@ static struct task_struct *copy_process(
19891  
19892         total_forks++;
19893         spin_unlock(&current->sighand->siglock);
19894 +
19895 +       /* p is copy of current */
19896 +       vxi = p->vx_info;
19897 +       if (vxi) {
19898 +               claim_vx_info(vxi, p);
19899 +               atomic_inc(&vxi->cvirt.nr_threads);
19900 +               atomic_inc(&vxi->cvirt.total_forks);
19901 +               vx_nproc_inc(p);
19902 +       }
19903 +       nxi = p->nx_info;
19904 +       if (nxi)
19905 +               claim_nx_info(nxi, p);
19906         write_unlock_irq(&tasklist_lock);
19907         proc_fork_connector(p);
19908         return p;
19909 @@ -1297,6 +1341,9 @@ bad_fork_cleanup_count:
19910         put_group_info(p->group_info);
19911         atomic_dec(&p->user->processes);
19912         free_uid(p->user);
19913 +bad_fork_cleanup_vm:
19914 +       if (p->mm && !(clone_flags & CLONE_VM))
19915 +               vx_pages_sub(p->vx_info, RLIMIT_AS, p->mm->total_vm);
19916  bad_fork_free:
19917         free_task(p);
19918  fork_out:
19919 @@ -1357,6 +1404,19 @@ long do_fork(unsigned long clone_flags,
19920  
19921         if (!pid)
19922                 return -EAGAIN;
19923 +
19924 +       /* kernel threads are host only */
19925 +       if ((clone_flags & CLONE_KTHREAD) && !vx_check(0, VS_ADMIN)) {
19926 +               vxwprintk(1, "xid=%d tried to spawn a kernel thread.",
19927 +                       vx_current_xid());
19928 +               free_pid(pid);
19929 +               return -EPERM;
19930 +       }
19931 +
19932 +       /* fake ipc/uts on namespace */
19933 +       if (clone_flags & CLONE_NEWNS)
19934 +               clone_flags |= CLONE_NEWUTS|CLONE_NEWIPC;
19935 +
19936         nr = pid->nr;
19937         if (unlikely(current->ptrace)) {
19938                 trace = fork_traceflag (clone_flags);
19939 diff -NurpP --minimal linux-2.6.19.1/kernel/kthread.c linux-2.6.19.1-vs2.3.0.6/kernel/kthread.c
19940 --- linux-2.6.19.1/kernel/kthread.c     2006-09-20 16:58:44 +0200
19941 +++ linux-2.6.19.1-vs2.3.0.6/kernel/kthread.c   2006-11-08 04:57:52 +0100
19942 @@ -123,7 +123,7 @@ static void keventd_create_kthread(void 
19943         } else {
19944                 wait_for_completion(&create->started);
19945                 read_lock(&tasklist_lock);
19946 -               create->result = find_task_by_pid(pid);
19947 +               create->result = find_task_by_real_pid(pid);
19948                 read_unlock(&tasklist_lock);
19949         }
19950         complete(&create->done);
19951 diff -NurpP --minimal linux-2.6.19.1/kernel/nsproxy.c linux-2.6.19.1-vs2.3.0.6/kernel/nsproxy.c
19952 --- linux-2.6.19.1/kernel/nsproxy.c     2006-11-30 21:19:43 +0100
19953 +++ linux-2.6.19.1-vs2.3.0.6/kernel/nsproxy.c   2006-11-14 02:14:48 +0100
19954 @@ -22,11 +22,6 @@
19955  
19956  struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
19957  
19958 -static inline void get_nsproxy(struct nsproxy *ns)
19959 -{
19960 -       atomic_inc(&ns->count);
19961 -}
19962 -
19963  void get_task_namespaces(struct task_struct *tsk)
19964  {
19965         struct nsproxy *ns = tsk->nsproxy;
19966 diff -NurpP --minimal linux-2.6.19.1/kernel/pid.c linux-2.6.19.1-vs2.3.0.6/kernel/pid.c
19967 --- linux-2.6.19.1/kernel/pid.c 2006-11-30 21:19:43 +0100
19968 +++ linux-2.6.19.1-vs2.3.0.6/kernel/pid.c       2006-12-04 01:47:02 +0100
19969 @@ -27,6 +27,7 @@
19970  #include <linux/bootmem.h>
19971  #include <linux/hash.h>
19972  #include <linux/pspace.h>
19973 +#include <linux/vs_pid.h>
19974  
19975  #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
19976  static struct hlist_head *pid_hash;
19977 @@ -299,6 +300,10 @@ struct task_struct * fastcall pid_task(s
19978   */
19979  struct task_struct *find_task_by_pid_type(int type, int nr)
19980  {
19981 +       if (type == PIDTYPE_PID)
19982 +               nr = vx_rmap_pid(nr);
19983 +       else if (type == PIDTYPE_REALPID)
19984 +               type = PIDTYPE_PID;
19985         return pid_task(find_pid(nr), type);
19986  }
19987  
19988 diff -NurpP --minimal linux-2.6.19.1/kernel/posix-timers.c linux-2.6.19.1-vs2.3.0.6/kernel/posix-timers.c
19989 --- linux-2.6.19.1/kernel/posix-timers.c        2006-11-30 21:19:43 +0100
19990 +++ linux-2.6.19.1-vs2.3.0.6/kernel/posix-timers.c      2006-11-08 04:57:52 +0100
19991 @@ -48,6 +48,7 @@
19992  #include <linux/wait.h>
19993  #include <linux/workqueue.h>
19994  #include <linux/module.h>
19995 +#include <linux/vs_context.h>
19996  
19997  /*
19998   * Management arrays for POSIX timers.  Timers are kept in slab memory
19999 @@ -298,6 +299,10 @@ void do_schedule_next_timer(struct sigin
20000  
20001  int posix_timer_event(struct k_itimer *timr,int si_private)
20002  {
20003 +       struct vx_info_save vxis;
20004 +       int ret;
20005 +
20006 +       enter_vx_info(task_get_vx_info(timr->it_process), &vxis);
20007         memset(&timr->sigq->info, 0, sizeof(siginfo_t));
20008         timr->sigq->info.si_sys_private = si_private;
20009         /* Send signal to the process that owns this timer.*/
20010 @@ -310,11 +315,11 @@ int posix_timer_event(struct k_itimer *t
20011  
20012         if (timr->it_sigev_notify & SIGEV_THREAD_ID) {
20013                 struct task_struct *leader;
20014 -               int ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
20015 -                                       timr->it_process);
20016  
20017 +               ret = send_sigqueue(timr->it_sigev_signo, timr->sigq,
20018 +                                   timr->it_process);
20019                 if (likely(ret >= 0))
20020 -                       return ret;
20021 +                       goto out;
20022  
20023                 timr->it_sigev_notify = SIGEV_SIGNAL;
20024                 leader = timr->it_process->group_leader;
20025 @@ -322,8 +327,12 @@ int posix_timer_event(struct k_itimer *t
20026                 timr->it_process = leader;
20027         }
20028  
20029 -       return send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
20030 -                                  timr->it_process);
20031 +       ret = send_group_sigqueue(timr->it_sigev_signo, timr->sigq,
20032 +                                 timr->it_process);
20033 +out:
20034 +       leave_vx_info(&vxis);
20035 +       put_vx_info(vxis.vxi);
20036 +       return ret;
20037  }
20038  EXPORT_SYMBOL_GPL(posix_timer_event);
20039  
20040 @@ -372,7 +381,7 @@ static struct task_struct * good_sigeven
20041         struct task_struct *rtn = current->group_leader;
20042  
20043         if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
20044 -               (!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
20045 +               (!(rtn = find_task_by_real_pid(event->sigev_notify_thread_id)) ||
20046                  rtn->tgid != current->tgid ||
20047                  (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
20048                 return NULL;
20049 diff -NurpP --minimal linux-2.6.19.1/kernel/printk.c linux-2.6.19.1-vs2.3.0.6/kernel/printk.c
20050 --- linux-2.6.19.1/kernel/printk.c      2006-11-30 21:19:44 +0100
20051 +++ linux-2.6.19.1-vs2.3.0.6/kernel/printk.c    2006-11-30 19:14:49 +0100
20052 @@ -32,6 +32,7 @@
20053  #include <linux/bootmem.h>
20054  #include <linux/syscalls.h>
20055  #include <linux/jiffies.h>
20056 +#include <linux/vs_cvirt.h>
20057  
20058  #include <asm/uaccess.h>
20059  
20060 @@ -185,18 +186,13 @@ int do_syslog(int type, char __user *buf
20061         unsigned long i, j, limit, count;
20062         int do_clear = 0;
20063         char c;
20064 -       int error = 0;
20065 +       int error;
20066  
20067         error = security_syslog(type);
20068         if (error)
20069                 return error;
20070  
20071 -       switch (type) {
20072 -       case 0:         /* Close log */
20073 -               break;
20074 -       case 1:         /* Open log */
20075 -               break;
20076 -       case 2:         /* Read from log */
20077 +       if ((type >= 2) && (type <= 4)) {
20078                 error = -EINVAL;
20079                 if (!buf || len < 0)
20080                         goto out;
20081 @@ -207,6 +203,16 @@ int do_syslog(int type, char __user *buf
20082                         error = -EFAULT;
20083                         goto out;
20084                 }
20085 +       }
20086 +       if (!vx_check(0, VS_ADMIN|VS_WATCH))
20087 +               return vx_do_syslog(type, buf, len);
20088 +
20089 +       switch (type) {
20090 +       case 0:         /* Close log */
20091 +               break;
20092 +       case 1:         /* Open log */
20093 +               break;
20094 +       case 2:         /* Read from log */
20095                 error = wait_event_interruptible(log_wait,
20096                                                         (log_start - log_end));
20097                 if (error)
20098 @@ -231,16 +237,6 @@ int do_syslog(int type, char __user *buf
20099                 do_clear = 1;
20100                 /* FALL THRU */
20101         case 3:         /* Read last kernel messages */
20102 -               error = -EINVAL;
20103 -               if (!buf || len < 0)
20104 -                       goto out;
20105 -               error = 0;
20106 -               if (!len)
20107 -                       goto out;
20108 -               if (!access_ok(VERIFY_WRITE, buf, len)) {
20109 -                       error = -EFAULT;
20110 -                       goto out;
20111 -               }
20112                 count = len;
20113                 if (count > log_buf_len)
20114                         count = log_buf_len;
20115 diff -NurpP --minimal linux-2.6.19.1/kernel/ptrace.c linux-2.6.19.1-vs2.3.0.6/kernel/ptrace.c
20116 --- linux-2.6.19.1/kernel/ptrace.c      2006-11-30 21:19:44 +0100
20117 +++ linux-2.6.19.1-vs2.3.0.6/kernel/ptrace.c    2006-11-30 19:38:18 +0100
20118 @@ -18,6 +18,7 @@
20119  #include <linux/ptrace.h>
20120  #include <linux/security.h>
20121  #include <linux/signal.h>
20122 +#include <linux/vs_context.h>
20123  
20124  #include <asm/pgtable.h>
20125  #include <asm/uaccess.h>
20126 @@ -144,6 +145,11 @@ static int may_attach(struct task_struct
20127                 dumpable = task->mm->dumpable;
20128         if (!dumpable && !capable(CAP_SYS_PTRACE))
20129                 return -EPERM;
20130 +       if (!vx_check(task->xid, VS_ADMIN_P|VS_IDENT))
20131 +               return -EPERM;
20132 +       if (!vx_check(task->xid, VS_IDENT) &&
20133 +               !task_vx_flags(task, VXF_STATE_ADMIN, 0))
20134 +               return -EACCES;
20135  
20136         return security_ptrace(current, task);
20137  }
20138 @@ -468,6 +474,10 @@ asmlinkage long sys_ptrace(long request,
20139                 goto out;
20140         }
20141  
20142 +       ret = -EPERM;
20143 +       if (!vx_check(vx_task_xid(child), VS_WATCH_P|VS_IDENT))
20144 +               goto out_put_task_struct;
20145 +
20146         if (request == PTRACE_ATTACH) {
20147                 ret = ptrace_attach(child);
20148                 goto out_put_task_struct;
20149 diff -NurpP --minimal linux-2.6.19.1/kernel/sched.c linux-2.6.19.1-vs2.3.0.6/kernel/sched.c
20150 --- linux-2.6.19.1/kernel/sched.c       2006-11-30 21:19:44 +0100
20151 +++ linux-2.6.19.1-vs2.3.0.6/kernel/sched.c     2006-11-30 18:53:18 +0100
20152 @@ -55,6 +55,8 @@
20153  #include <asm/tlb.h>
20154  
20155  #include <asm/unistd.h>
20156 +#include <linux/vs_sched.h>
20157 +#include <linux/vs_cvirt.h>
20158  
20159  /*
20160   * Convert user-nice values [ -20 ... 0 ... 19 ]
20161 @@ -243,6 +245,16 @@ struct rq {
20162         struct task_struct *migration_thread;
20163         struct list_head migration_queue;
20164  #endif
20165 +       unsigned long norm_time;
20166 +       unsigned long idle_time;
20167 +#ifdef CONFIG_VSERVER_IDLETIME
20168 +       int idle_skip;
20169 +#endif
20170 +#ifdef CONFIG_VSERVER_HARDCPU
20171 +       struct list_head hold_queue;
20172 +       unsigned long nr_onhold;
20173 +       int idle_tokens;
20174 +#endif
20175  
20176  #ifdef CONFIG_SCHEDSTATS
20177         /* latency stats */
20178 @@ -672,6 +684,7 @@ sched_info_switch(struct task_struct *pr
20179   */
20180  static void dequeue_task(struct task_struct *p, struct prio_array *array)
20181  {
20182 +       BUG_ON(p->state & TASK_ONHOLD);
20183         array->nr_active--;
20184         list_del(&p->run_list);
20185         if (list_empty(array->queue + p->prio))
20186 @@ -680,6 +693,7 @@ static void dequeue_task(struct task_str
20187  
20188  static void enqueue_task(struct task_struct *p, struct prio_array *array)
20189  {
20190 +       BUG_ON(p->state & TASK_ONHOLD);
20191         sched_info_queued(p);
20192         list_add_tail(&p->run_list, array->queue + p->prio);
20193         __set_bit(p->prio, array->bitmap);
20194 @@ -693,12 +707,14 @@ static void enqueue_task(struct task_str
20195   */
20196  static void requeue_task(struct task_struct *p, struct prio_array *array)
20197  {
20198 +       BUG_ON(p->state & TASK_ONHOLD);
20199         list_move_tail(&p->run_list, array->queue + p->prio);
20200  }
20201  
20202  static inline void
20203  enqueue_task_head(struct task_struct *p, struct prio_array *array)
20204  {
20205 +       BUG_ON(p->state & TASK_ONHOLD);
20206         list_add(&p->run_list, array->queue + p->prio);
20207         __set_bit(p->prio, array->bitmap);
20208         array->nr_active++;
20209 @@ -727,6 +743,10 @@ static inline int __normal_prio(struct t
20210         bonus = CURRENT_BONUS(p) - MAX_BONUS / 2;
20211  
20212         prio = p->static_prio - bonus;
20213 +
20214 +       /* adjust effective priority */
20215 +       prio = vx_adjust_prio(p, prio, MAX_USER_PRIO);
20216 +
20217         if (prio < MAX_RT_PRIO)
20218                 prio = MAX_RT_PRIO;
20219         if (prio > MAX_PRIO-1)
20220 @@ -836,6 +856,9 @@ static int effective_prio(struct task_st
20221         return p->prio;
20222  }
20223  
20224 +#include "sched_mon.h"
20225 +
20226 +
20227  /*
20228   * __activate_task - move a task to the runqueue.
20229   */
20230 @@ -845,6 +868,7 @@ static void __activate_task(struct task_
20231  
20232         if (batch_task(p))
20233                 target = rq->expired;
20234 +       vxm_activate_task(p, rq);
20235         enqueue_task(p, target);
20236         inc_nr_running(p, rq);
20237  }
20238 @@ -854,6 +878,7 @@ static void __activate_task(struct task_
20239   */
20240  static inline void __activate_idle_task(struct task_struct *p, struct rq *rq)
20241  {
20242 +       vxm_activate_idle(p, rq);
20243         enqueue_task_head(p, rq->active);
20244         inc_nr_running(p, rq);
20245  }
20246 @@ -975,19 +1000,30 @@ static void activate_task(struct task_st
20247         }
20248         p->timestamp = now;
20249  
20250 +       vx_activate_task(p);
20251         __activate_task(p, rq);
20252  }
20253  
20254  /*
20255   * deactivate_task - remove a task from the runqueue.
20256   */
20257 -static void deactivate_task(struct task_struct *p, struct rq *rq)
20258 +static void __deactivate_task(struct task_struct *p, struct rq *rq)
20259  {
20260         dec_nr_running(p, rq);
20261         dequeue_task(p, p->array);
20262 +       vxm_deactivate_task(p, rq);
20263         p->array = NULL;
20264  }
20265  
20266 +static inline
20267 +void deactivate_task(struct task_struct *p, struct rq *rq)
20268 +{
20269 +       vx_deactivate_task(p);
20270 +       __deactivate_task(p, rq);
20271 +}
20272 +
20273 +#include "sched_hard.h"
20274 +
20275  /*
20276   * resched_task - mark a task 'to be rescheduled now'.
20277   *
20278 @@ -1063,6 +1099,7 @@ migrate_task(struct task_struct *p, int 
20279  {
20280         struct rq *rq = task_rq(p);
20281  
20282 +       vxm_migrate_task(p, rq, dest_cpu);
20283         /*
20284          * If the task is not on a runqueue (and not running), then
20285          * it is sufficient to simply update the task's cpu field.
20286 @@ -1391,6 +1428,12 @@ static int try_to_wake_up(struct task_st
20287  
20288         rq = task_rq_lock(p, &flags);
20289         old_state = p->state;
20290 +
20291 +       /* we need to unhold suspended tasks */
20292 +       if (old_state & TASK_ONHOLD) {
20293 +               vx_unhold_task(p, rq);
20294 +               old_state = p->state;
20295 +       }
20296         if (!(old_state & state))
20297                 goto out;
20298  
20299 @@ -1496,6 +1539,7 @@ out_activate:
20300  #endif /* CONFIG_SMP */
20301         if (old_state == TASK_UNINTERRUPTIBLE) {
20302                 rq->nr_uninterruptible--;
20303 +               vx_uninterruptible_dec(p);
20304                 /*
20305                  * Tasks on involuntary sleep don't earn
20306                  * sleep_avg beyond just interactive state.
20307 @@ -1642,6 +1686,7 @@ void fastcall wake_up_new_task(struct ta
20308  
20309         p->prio = effective_prio(p);
20310  
20311 +       vx_activate_task(p);
20312         if (likely(cpu == this_cpu)) {
20313                 if (!(clone_flags & CLONE_VM)) {
20314                         /*
20315 @@ -1653,6 +1698,7 @@ void fastcall wake_up_new_task(struct ta
20316                                 __activate_task(p, rq);
20317                         else {
20318                                 p->prio = current->prio;
20319 +                               BUG_ON(p->state & TASK_ONHOLD);
20320                                 p->normal_prio = current->normal_prio;
20321                                 list_add_tail(&p->run_list, &current->run_list);
20322                                 p->array = current->array;
20323 @@ -2973,13 +3019,16 @@ static inline int expired_starving(struc
20324  void account_user_time(struct task_struct *p, cputime_t cputime)
20325  {
20326         struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
20327 +       struct vx_info *vxi = p->vx_info;  /* p is _always_ current */
20328         cputime64_t tmp;
20329 +       int nice = (TASK_NICE(p) > 0);
20330  
20331         p->utime = cputime_add(p->utime, cputime);
20332 +       vx_account_user(vxi, cputime, nice);
20333  
20334         /* Add user time to cpustat. */
20335         tmp = cputime_to_cputime64(cputime);
20336 -       if (TASK_NICE(p) > 0)
20337 +       if (nice)
20338                 cpustat->nice = cputime64_add(cpustat->nice, tmp);
20339         else
20340                 cpustat->user = cputime64_add(cpustat->user, tmp);
20341 @@ -2995,10 +3044,12 @@ void account_system_time(struct task_str
20342                          cputime_t cputime)
20343  {
20344         struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
20345 +       struct vx_info *vxi = p->vx_info;  /* p is _always_ current */
20346         struct rq *rq = this_rq();
20347         cputime64_t tmp;
20348  
20349         p->stime = cputime_add(p->stime, cputime);
20350 +       vx_account_system(vxi, cputime, (p == rq->idle));
20351  
20352         /* Add system time to cpustat. */
20353         tmp = cputime_to_cputime64(cputime);
20354 @@ -3052,12 +3103,14 @@ void scheduler_tick(void)
20355         struct rq *rq = cpu_rq(cpu);
20356  
20357         update_cpu_clock(p, rq, now);
20358 +       vxm_sync(now, cpu);
20359  
20360         rq->timestamp_last_tick = now;
20361  
20362         if (p == rq->idle) {
20363                 if (wake_priority_sleeper(rq))
20364                         goto out;
20365 +               vx_idle_resched(rq);
20366                 rebalance_tick(cpu, rq, SCHED_IDLE);
20367                 return;
20368         }
20369 @@ -3090,7 +3143,7 @@ void scheduler_tick(void)
20370                 }
20371                 goto out_unlock;
20372         }
20373 -       if (!--p->time_slice) {
20374 +       if (vx_need_resched(p, --p->time_slice, cpu)) {
20375                 dequeue_task(p, rq->active);
20376                 set_tsk_need_resched(p);
20377                 p->prio = effective_prio(p);
20378 @@ -3377,14 +3430,25 @@ need_resched_nonpreemptible:
20379                                 unlikely(signal_pending(prev))))
20380                         prev->state = TASK_RUNNING;
20381                 else {
20382 -                       if (prev->state == TASK_UNINTERRUPTIBLE)
20383 +                       if (prev->state == TASK_UNINTERRUPTIBLE) {
20384                                 rq->nr_uninterruptible++;
20385 +                               vx_uninterruptible_inc(prev);
20386 +                       }
20387                         deactivate_task(prev, rq);
20388                 }
20389         }
20390  
20391         cpu = smp_processor_id();
20392 +       vx_set_rq_time(rq, jiffies);
20393 +try_unhold:
20394 +       vx_try_unhold(rq, cpu);
20395 +pick_next:
20396 +
20397         if (unlikely(!rq->nr_running)) {
20398 +               /* can we skip idle time? */
20399 +               if (vx_try_skip(rq, cpu))
20400 +                       goto try_unhold;
20401 +
20402                 idle_balance(cpu, rq);
20403                 if (!rq->nr_running) {
20404                         next = rq->idle;
20405 @@ -3411,6 +3475,10 @@ need_resched_nonpreemptible:
20406         queue = array->queue + idx;
20407         next = list_entry(queue->next, struct task_struct, run_list);
20408  
20409 +       /* check before we schedule this context */
20410 +       if (!vx_schedule(next, rq, cpu))
20411 +               goto pick_next;
20412 +
20413         if (!rt_task(next) && interactive_sleep(next->sleep_type)) {
20414                 unsigned long long delta = now - next->timestamp;
20415                 if (unlikely((long long)(now - next->timestamp) < 0))
20416 @@ -4013,7 +4081,7 @@ asmlinkage long sys_nice(int increment)
20417                 nice = 19;
20418  
20419         if (increment < 0 && !can_nice(current, nice))
20420 -               return -EPERM;
20421 +               return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
20422  
20423         retval = security_task_setnice(current, nice);
20424         if (retval)
20425 @@ -4186,6 +4254,7 @@ recheck:
20426         oldprio = p->prio;
20427         __setscheduler(p, policy, param->sched_priority);
20428         if (array) {
20429 +               vx_activate_task(p);
20430                 __activate_task(p, rq);
20431                 /*
20432                  * Reschedule if we are currently running on this runqueue and
20433 @@ -4976,6 +5045,7 @@ static int __migrate_task(struct task_st
20434                 p->timestamp = p->timestamp - rq_src->timestamp_last_tick
20435                                 + rq_dest->timestamp_last_tick;
20436                 deactivate_task(p, rq_src);
20437 +               vx_activate_task(p);
20438                 __activate_task(p, rq_dest);
20439                 if (TASK_PREEMPTS_CURR(p, rq_dest))
20440                         resched_task(rq_dest->curr);
20441 @@ -6819,7 +6889,10 @@ void __init sched_init(void)
20442                 INIT_LIST_HEAD(&rq->migration_queue);
20443  #endif
20444                 atomic_set(&rq->nr_iowait, 0);
20445 -
20446 +#ifdef CONFIG_VSERVER_HARDCPU
20447 +               INIT_LIST_HEAD(&rq->hold_queue);
20448 +               rq->nr_onhold = 0;
20449 +#endif
20450                 for (j = 0; j < 2; j++) {
20451                         array = rq->arrays + j;
20452                         for (k = 0; k < MAX_PRIO; k++) {
20453 @@ -6895,6 +6968,7 @@ void normalize_rt_tasks(void)
20454                         deactivate_task(p, task_rq(p));
20455                 __setscheduler(p, SCHED_NORMAL, 0);
20456                 if (array) {
20457 +                       vx_activate_task(p);
20458                         __activate_task(p, task_rq(p));
20459                         resched_task(rq->curr);
20460                 }
20461 diff -NurpP --minimal linux-2.6.19.1/kernel/sched_hard.h linux-2.6.19.1-vs2.3.0.6/kernel/sched_hard.h
20462 --- linux-2.6.19.1/kernel/sched_hard.h  1970-01-01 01:00:00 +0100
20463 +++ linux-2.6.19.1-vs2.3.0.6/kernel/sched_hard.h        2006-11-30 18:53:18 +0100
20464 @@ -0,0 +1,324 @@
20465 +
20466 +#ifdef CONFIG_VSERVER_IDLELIMIT
20467 +
20468 +/*
20469 + * vx_idle_resched - reschedule after maxidle
20470 + */
20471 +static inline
20472 +void vx_idle_resched(struct rq *rq)
20473 +{
20474 +       /* maybe have a better criterion for paused */
20475 +       if (!--rq->idle_tokens && !list_empty(&rq->hold_queue))
20476 +               set_need_resched();
20477 +}
20478 +
20479 +#else /* !CONFIG_VSERVER_IDLELIMIT */
20480 +
20481 +#define vx_idle_resched(rq)
20482 +
20483 +#endif /* CONFIG_VSERVER_IDLELIMIT */
20484 +
20485 +
20486 +
20487 +#ifdef CONFIG_VSERVER_IDLETIME
20488 +
20489 +#define vx_set_rq_min_skip(rq, min)            \
20490 +       (rq)->idle_skip = (min)
20491 +
20492 +#define vx_save_min_skip(ret, min, val)                \
20493 +       __vx_save_min_skip(ret, min, val)
20494 +
20495 +static inline
20496 +void __vx_save_min_skip(int ret, int *min, int val)
20497 +{
20498 +       if (ret > -2)
20499 +               return;
20500 +       if ((*min > val) || !*min)
20501 +               *min = val;
20502 +}
20503 +
20504 +static inline
20505 +int vx_try_skip(struct rq *rq, int cpu)
20506 +{
20507 +       /* artificially advance time */
20508 +       if (rq->idle_skip > 0) {
20509 +               vxdprintk(list_empty(&rq->hold_queue),
20510 +                       "hold queue empty on cpu %d", cpu);
20511 +               rq->idle_time += rq->idle_skip;
20512 +               vxm_idle_skip(rq, cpu);
20513 +               return 1;
20514 +       }
20515 +       return 0;
20516 +}
20517 +
20518 +#else /* !CONFIG_VSERVER_IDLETIME */
20519 +
20520 +#define vx_set_rq_min_skip(rq, min)            \
20521 +       ({ int dummy = (min); dummy; })
20522 +
20523 +#define vx_save_min_skip(ret, min, val)
20524 +
20525 +static inline
20526 +int vx_try_skip(struct rq *rq, int cpu)
20527 +{
20528 +       return 0;
20529 +}
20530 +
20531 +#endif /* CONFIG_VSERVER_IDLETIME */
20532 +
20533 +
20534 +
20535 +#ifdef CONFIG_VSERVER_HARDCPU
20536 +
20537 +#define vx_set_rq_max_idle(rq, max)            \
20538 +       (rq)->idle_tokens = (max)
20539 +
20540 +#define vx_save_max_idle(ret, min, val)                \
20541 +       __vx_save_max_idle(ret, min, val)
20542 +
20543 +static inline
20544 +void __vx_save_max_idle(int ret, int *min, int val)
20545 +{
20546 +       if (*min > val)
20547 +               *min = val;
20548 +}
20549 +
20550 +
20551 +/*
20552 + * vx_hold_task - put a task on the hold queue
20553 + */
20554 +static inline
20555 +void vx_hold_task(struct task_struct *p, struct rq *rq)
20556 +{
20557 +       __deactivate_task(p, rq);
20558 +       p->state |= TASK_ONHOLD;
20559 +       /* a new one on hold */
20560 +       rq->nr_onhold++;
20561 +       vxm_hold_task(p, rq);
20562 +       list_add_tail(&p->run_list, &rq->hold_queue);
20563 +}
20564 +
20565 +/*
20566 + * vx_unhold_task - put a task back to the runqueue
20567 + */
20568 +static inline
20569 +void vx_unhold_task(struct task_struct *p, struct rq *rq)
20570 +{
20571 +       list_del(&p->run_list);
20572 +       /* one less waiting */
20573 +       rq->nr_onhold--;
20574 +       p->state &= ~TASK_ONHOLD;
20575 +       enqueue_task(p, rq->expired);
20576 +       inc_nr_running(p, rq);
20577 +       vxm_unhold_task(p, rq);
20578 +
20579 +       if (p->static_prio < rq->best_expired_prio)
20580 +               rq->best_expired_prio = p->static_prio;
20581 +}
20582 +
20583 +unsigned long nr_onhold(void)
20584 +{
20585 +       unsigned long i, sum = 0;
20586 +
20587 +       for_each_online_cpu(i)
20588 +               sum += cpu_rq(i)->nr_onhold;
20589 +
20590 +       return sum;
20591 +}
20592 +
20593 +
20594 +
20595 +static inline
20596 +int __vx_tokens_avail(struct _vx_sched_pc *sched_pc)
20597 +{
20598 +       return sched_pc->tokens;
20599 +}
20600 +
20601 +static inline
20602 +void __vx_consume_token(struct _vx_sched_pc *sched_pc)
20603 +{
20604 +       sched_pc->tokens--;
20605 +}
20606 +
20607 +static inline
20608 +int vx_need_resched(struct task_struct *p, int slice, int cpu)
20609 +{
20610 +       struct vx_info *vxi = p->vx_info;
20611 +
20612 +       if (vx_info_flags(vxi, VXF_SCHED_HARD|VXF_SCHED_PRIO, 0)) {
20613 +               struct _vx_sched_pc *sched_pc =
20614 +                       &vx_per_cpu(vxi, sched_pc, cpu);
20615 +               int tokens;
20616 +
20617 +               /* maybe we can simplify that to decrement
20618 +                  the token counter unconditional? */
20619 +
20620 +               if ((tokens = __vx_tokens_avail(sched_pc)) > 0)
20621 +                       __vx_consume_token(sched_pc);
20622 +
20623 +               /* for tokens > 0, one token was consumed */
20624 +               if (tokens < 2)
20625 +                       slice = 0;
20626 +       }
20627 +       vxm_need_resched(p, slice, cpu);
20628 +       return (slice == 0);
20629 +}
20630 +
20631 +
20632 +#define vx_set_rq_time(rq, time) do {  \
20633 +       rq->norm_time = time;           \
20634 +} while (0)
20635 +
20636 +
20637 +static inline
20638 +void vx_try_unhold(struct rq *rq, int cpu)
20639 +{
20640 +       struct vx_info *vxi = NULL;
20641 +       struct list_head *l, *n;
20642 +       int maxidle = HZ;
20643 +       int minskip = 0;
20644 +
20645 +       /* nothing to do? what about pause? */
20646 +       if (list_empty(&rq->hold_queue))
20647 +               return;
20648 +
20649 +       list_for_each_safe(l, n, &rq->hold_queue) {
20650 +               int ret, delta_min[2];
20651 +               struct _vx_sched_pc *sched_pc;
20652 +               struct task_struct *p;
20653 +
20654 +               p = list_entry(l, struct task_struct, run_list);
20655 +               /* don't bother with same context */
20656 +               if (vxi == p->vx_info)
20657 +                       continue;
20658 +
20659 +               vxi = p->vx_info;
20660 +               /* ignore paused contexts */
20661 +               if (vx_info_flags(vxi, VXF_SCHED_PAUSE, 0))
20662 +                       continue;
20663 +
20664 +               sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
20665 +
20666 +               /* recalc tokens */
20667 +               vxm_sched_info(sched_pc, vxi, cpu);
20668 +               ret = vx_tokens_recalc(sched_pc,
20669 +                       &rq->norm_time, &rq->idle_time, delta_min);
20670 +               vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
20671 +
20672 +               if (ret > 0) {
20673 +                       /* we found a runable context */
20674 +                       vx_unhold_task(p, rq);
20675 +                       break;
20676 +               }
20677 +               vx_save_max_idle(ret, &maxidle, delta_min[0]);
20678 +               vx_save_min_skip(ret, &minskip, delta_min[1]);
20679 +       }
20680 +       vx_set_rq_max_idle(rq, maxidle);
20681 +       vx_set_rq_min_skip(rq, minskip);
20682 +       vxm_rq_max_min(rq, cpu);
20683 +}
20684 +
20685 +
20686 +static inline
20687 +int vx_schedule(struct task_struct *next, struct rq *rq, int cpu)
20688 +{
20689 +       struct vx_info *vxi = next->vx_info;
20690 +       struct _vx_sched_pc *sched_pc;
20691 +       int delta_min[2];
20692 +       int flags, ret;
20693 +
20694 +       if (!vxi)
20695 +               return 1;
20696 +
20697 +       flags = vxi->vx_flags;
20698 +
20699 +       if (unlikely(vs_check_flags(flags , VXF_SCHED_PAUSE, 0)))
20700 +               goto put_on_hold;
20701 +       if (!vs_check_flags(flags , VXF_SCHED_HARD|VXF_SCHED_PRIO, 0))
20702 +               return 1;
20703 +
20704 +       sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
20705 +#ifdef CONFIG_SMP
20706 +       /* update scheduler params */
20707 +       if (cpu_isset(cpu, vxi->sched.update)) {
20708 +               vx_update_sched_param(&vxi->sched, sched_pc);
20709 +               vxm_update_sched(sched_pc, vxi, cpu);
20710 +               cpu_clear(cpu, vxi->sched.update);
20711 +       }
20712 +#endif
20713 +       vxm_sched_info(sched_pc, vxi, cpu);
20714 +       ret  = vx_tokens_recalc(sched_pc,
20715 +               &rq->norm_time, &rq->idle_time, delta_min);
20716 +       vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
20717 +
20718 +       if (!vs_check_flags(flags , VXF_SCHED_HARD, 0))
20719 +               return 1;
20720 +
20721 +       if (unlikely(ret < 0)) {
20722 +               vx_save_max_idle(ret, &rq->idle_tokens, delta_min[0]);
20723 +               vx_save_min_skip(ret, &rq->idle_skip, delta_min[1]);
20724 +               vxm_rq_max_min(rq, cpu);
20725 +       put_on_hold:
20726 +               vx_hold_task(next, rq);
20727 +               return 0;
20728 +       }
20729 +       return 1;
20730 +}
20731 +
20732 +
20733 +#else /* CONFIG_VSERVER_HARDCPU */
20734 +
20735 +static inline
20736 +void vx_hold_task(struct task_struct *p, struct rq *rq)
20737 +{
20738 +       return;
20739 +}
20740 +
20741 +static inline
20742 +void vx_unhold_task(struct task_struct *p, struct rq *rq)
20743 +{
20744 +       return;
20745 +}
20746 +
20747 +unsigned long nr_onhold(void)
20748 +{
20749 +       return 0;
20750 +}
20751 +
20752 +
20753 +static inline
20754 +int vx_need_resched(struct task_struct *p, int slice, int cpu)
20755 +{
20756 +       return (slice == 0);
20757 +}
20758 +
20759 +
20760 +#define vx_set_rq_time(rq, time)
20761 +
20762 +static inline
20763 +void vx_try_unhold(struct rq *rq, int cpu)
20764 +{
20765 +       return;
20766 +}
20767 +
20768 +static inline
20769 +int vx_schedule(struct task_struct *next, struct rq *rq, int cpu)
20770 +{
20771 +       struct vx_info *vxi = next->vx_info;
20772 +       struct _vx_sched_pc *sched_pc;
20773 +       int delta_min[2];
20774 +       int ret;
20775 +
20776 +       if (!vx_info_flags(vxi, VXF_SCHED_PRIO, 0))
20777 +               return 1;
20778 +
20779 +       sched_pc = &vx_per_cpu(vxi, sched_pc, cpu);
20780 +       vxm_sched_info(sched_pc, vxi, cpu);
20781 +       ret  = vx_tokens_recalc(sched_pc,
20782 +               &rq->norm_time, &rq->idle_time, delta_min);
20783 +       vxm_tokens_recalc(sched_pc, rq, vxi, cpu);
20784 +       return 1;
20785 +}
20786 +
20787 +#endif /* CONFIG_VSERVER_HARDCPU */
20788 +
20789 diff -NurpP --minimal linux-2.6.19.1/kernel/sched_mon.h linux-2.6.19.1-vs2.3.0.6/kernel/sched_mon.h
20790 --- linux-2.6.19.1/kernel/sched_mon.h   1970-01-01 01:00:00 +0100
20791 +++ linux-2.6.19.1-vs2.3.0.6/kernel/sched_mon.h 2006-11-08 04:57:48 +0100
20792 @@ -0,0 +1,200 @@
20793 +
20794 +#include <linux/vserver/monitor.h>
20795 +
20796 +#ifdef  CONFIG_VSERVER_MONITOR
20797 +
20798 +#ifdef CONFIG_VSERVER_HARDCPU
20799 +#define HARDCPU(x) (x)
20800 +#else
20801 +#define HARDCPU(x) (0)
20802 +#endif
20803 +
20804 +#ifdef CONFIG_VSERVER_IDLETIME
20805 +#define IDLETIME(x) (x)
20806 +#else
20807 +#define IDLETIME(x) (0)
20808 +#endif
20809 +
20810 +struct _vx_mon_entry *vxm_advance(int cpu);
20811 +
20812 +
20813 +static inline
20814 +void   __vxm_basic(struct _vx_mon_entry *entry, xid_t xid, int type)
20815 +{
20816 +       entry->type = type;
20817 +       entry->xid = xid;
20818 +}
20819 +
20820 +static inline
20821 +void   __vxm_sync(int cpu)
20822 +{
20823 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20824 +
20825 +       __vxm_basic(entry, 0, VXM_SYNC);
20826 +       entry->ev.sec = xtime.tv_sec;
20827 +       entry->ev.nsec = xtime.tv_nsec;
20828 +}
20829 +
20830 +static inline
20831 +void   __vxm_task(struct task_struct *p, int type)
20832 +{
20833 +       struct _vx_mon_entry *entry = vxm_advance(task_cpu(p));
20834 +
20835 +       __vxm_basic(entry, p->xid, type);
20836 +       entry->ev.tsk.pid = p->pid;
20837 +       entry->ev.tsk.state = p->state;
20838 +}
20839 +
20840 +static inline
20841 +void   __vxm_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20842 +{
20843 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20844 +
20845 +       __vxm_basic(entry, vxi->vx_id, (VXM_SCHED | s->flags));
20846 +       entry->sd.tokens = s->tokens;
20847 +       entry->sd.norm_time = s->norm_time;
20848 +       entry->sd.idle_time = s->idle_time;
20849 +}
20850 +
20851 +static inline
20852 +void   __vxm_rqinfo1(struct rq *q, int cpu)
20853 +{
20854 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20855 +
20856 +       entry->type = VXM_RQINFO_1;
20857 +       entry->xid = ((unsigned long)q >> 16) & 0xffff;
20858 +       entry->q1.running = q->nr_running;
20859 +       entry->q1.onhold = HARDCPU(q->nr_onhold);
20860 +       entry->q1.iowait = atomic_read(&q->nr_iowait);
20861 +       entry->q1.uintr = q->nr_uninterruptible;
20862 +       entry->q1.idle_tokens = IDLETIME(q->idle_tokens);
20863 +}
20864 +
20865 +static inline
20866 +void   __vxm_rqinfo2(struct rq *q, int cpu)
20867 +{
20868 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20869 +
20870 +       entry->type = VXM_RQINFO_2;
20871 +       entry->xid = (unsigned long)q & 0xffff;
20872 +       entry->q2.norm_time = q->norm_time;
20873 +       entry->q2.idle_time = q->idle_time;
20874 +       entry->q2.idle_skip = IDLETIME(q->idle_skip);
20875 +}
20876 +
20877 +static inline
20878 +void   __vxm_update(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20879 +{
20880 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20881 +
20882 +       __vxm_basic(entry, vxi->vx_id, VXM_UPDATE);
20883 +       entry->ev.tokens = s->tokens;
20884 +}
20885 +
20886 +static inline
20887 +void   __vxm_update1(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20888 +{
20889 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20890 +
20891 +       __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_1);
20892 +       entry->u1.tokens_max = s->tokens_max;
20893 +       entry->u1.fill_rate = s->fill_rate[0];
20894 +       entry->u1.interval = s->interval[0];
20895 +}
20896 +
20897 +static inline
20898 +void   __vxm_update2(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20899 +{
20900 +       struct _vx_mon_entry *entry = vxm_advance(cpu);
20901 +
20902 +       __vxm_basic(entry, vxi->vx_id, VXM_UPDATE_2);
20903 +       entry->u2.tokens_min = s->tokens_min;
20904 +       entry->u2.fill_rate = s->fill_rate[1];
20905 +       entry->u2.interval = s->interval[1];
20906 +}
20907 +
20908 +
20909 +#define        vxm_activate_task(p,q)          __vxm_task(p, VXM_ACTIVATE)
20910 +#define        vxm_activate_idle(p,q)          __vxm_task(p, VXM_IDLE)
20911 +#define        vxm_deactivate_task(p,q)        __vxm_task(p, VXM_DEACTIVATE)
20912 +#define        vxm_hold_task(p,q)              __vxm_task(p, VXM_HOLD)
20913 +#define        vxm_unhold_task(p,q)            __vxm_task(p, VXM_UNHOLD)
20914 +
20915 +static inline
20916 +void   vxm_migrate_task(struct task_struct *p, struct rq *rq, int dest)
20917 +{
20918 +       __vxm_task(p, VXM_MIGRATE);
20919 +       __vxm_rqinfo1(rq, task_cpu(p));
20920 +       __vxm_rqinfo2(rq, task_cpu(p));
20921 +}
20922 +
20923 +static inline
20924 +void   vxm_idle_skip(struct rq *rq, int cpu)
20925 +{
20926 +       __vxm_rqinfo1(rq, cpu);
20927 +       __vxm_rqinfo2(rq, cpu);
20928 +}
20929 +
20930 +static inline
20931 +void   vxm_need_resched(struct task_struct *p, int slice, int cpu)
20932 +{
20933 +       if (slice)
20934 +               return;
20935 +
20936 +       __vxm_task(p, VXM_RESCHED);
20937 +}
20938 +
20939 +static inline
20940 +void   vxm_sync(unsigned long now, int cpu)
20941 +{
20942 +       if (!CONFIG_VSERVER_MONITOR_SYNC ||
20943 +               (now % CONFIG_VSERVER_MONITOR_SYNC))
20944 +               return;
20945 +
20946 +       __vxm_sync(cpu);
20947 +}
20948 +
20949 +#define        vxm_sched_info(s,v,c)           __vxm_sched(s,v,c)
20950 +
20951 +static inline
20952 +void   vxm_tokens_recalc(struct _vx_sched_pc *s, struct rq *rq,
20953 +       struct vx_info *vxi, int cpu)
20954 +{
20955 +       __vxm_sched(s, vxi, cpu);
20956 +       __vxm_rqinfo2(rq, cpu);
20957 +}
20958 +
20959 +static inline
20960 +void   vxm_update_sched(struct _vx_sched_pc *s, struct vx_info *vxi, int cpu)
20961 +{
20962 +       __vxm_sched(s, vxi, cpu);
20963 +       __vxm_update(s, vxi, cpu);
20964 +       __vxm_update1(s, vxi, cpu);
20965 +       __vxm_update2(s, vxi, cpu);
20966 +}
20967 +
20968 +static inline
20969 +void   vxm_rq_max_min(struct rq *rq, int cpu)
20970 +{
20971 +       __vxm_rqinfo1(rq, cpu);
20972 +       __vxm_rqinfo2(rq, cpu);
20973 +}
20974 +
20975 +#else  /* CONFIG_VSERVER_MONITOR */
20976 +
20977 +#define        vxm_activate_task(t,q)          do { } while (0)
20978 +#define        vxm_activate_idle(t,q)          do { } while (0)
20979 +#define        vxm_deactivate_task(t,q)        do { } while (0)
20980 +#define        vxm_hold_task(t,q)              do { } while (0)
20981 +#define        vxm_unhold_task(t,q)            do { } while (0)
20982 +#define        vxm_migrate_task(t,q,d)         do { } while (0)
20983 +#define        vxm_idle_skip(q,c)              do { } while (0)
20984 +#define        vxm_need_resched(t,s,c)         do { } while (0)
20985 +#define        vxm_sync(s,c)                   do { } while (0)
20986 +#define        vxm_sched_info(s,v,c)           do { } while (0)
20987 +#define        vxm_tokens_recalc(s,q,v,c)      do { } while (0)
20988 +#define        vxm_update_sched(s,v,c)         do { } while (0)
20989 +#define        vxm_rq_max_min(q,c)             do { } while (0)
20990 +
20991 +#endif /* CONFIG_VSERVER_MONITOR */
20992 +
20993 diff -NurpP --minimal linux-2.6.19.1/kernel/signal.c linux-2.6.19.1-vs2.3.0.6/kernel/signal.c
20994 --- linux-2.6.19.1/kernel/signal.c      2006-11-30 21:19:44 +0100
20995 +++ linux-2.6.19.1-vs2.3.0.6/kernel/signal.c    2006-11-30 19:43:08 +0100
20996 @@ -23,6 +23,7 @@
20997  #include <linux/binfmts.h>
20998  #include <linux/security.h>
20999  #include <linux/syscalls.h>
21000 +#include <linux/vs_context.h>
21001  #include <linux/ptrace.h>
21002  #include <linux/signal.h>
21003  #include <linux/capability.h>
21004 @@ -577,17 +578,30 @@ static int check_kill_permission(int sig
21005                                  struct task_struct *t)
21006  {
21007         int error = -EINVAL;
21008 +
21009         if (!valid_signal(sig))
21010                 return error;
21011 +
21012 +       if ((info != SEND_SIG_NOINFO) &&
21013 +               (is_si_special(info) || !SI_FROMUSER(info)))
21014 +               goto skip;
21015 +
21016         error = -EPERM;
21017 -       if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
21018 -           && ((sig != SIGCONT) ||
21019 +       if (((sig != SIGCONT) ||
21020                 (current->signal->session != t->signal->session))
21021             && (current->euid ^ t->suid) && (current->euid ^ t->uid)
21022             && (current->uid ^ t->suid) && (current->uid ^ t->uid)
21023             && !capable(CAP_KILL))
21024                 return error;
21025  
21026 +       error = -ESRCH;
21027 +       if (!vx_check(vx_task_xid(t), VS_WATCH_P|VS_IDENT)) {
21028 +               vxwprintk(current->xid,
21029 +                       "signal xid mismatch %p[#%u,%u] xid=#%u\n",
21030 +                       t, vx_task_xid(t), t->pid, current->xid);
21031 +               return error;
21032 +       }
21033 +skip:
21034         error = security_task_kill(t, info, sig, 0);
21035         if (!error)
21036                 audit_signal_info(sig, t); /* Let audit system see the signal */
21037 @@ -1125,7 +1139,7 @@ int kill_pid_info(int sig, struct siginf
21038         }
21039         p = pid_task(pid, PIDTYPE_PID);
21040         error = -ESRCH;
21041 -       if (p)
21042 +       if (p && vx_check(vx_task_xid(p), VS_IDENT))
21043                 error = group_send_sig_info(sig, info, p);
21044         if (unlikely(acquired_tasklist_lock))
21045                 read_unlock(&tasklist_lock);
21046 @@ -1197,7 +1211,8 @@ static int kill_something_info(int sig, 
21047  
21048                 read_lock(&tasklist_lock);
21049                 for_each_process(p) {
21050 -                       if (p->pid > 1 && p->tgid != current->tgid) {
21051 +                       if (vx_check(vx_task_xid(p), VS_ADMIN_P|VS_IDENT) &&
21052 +                               p->pid > 1 && p->tgid != current->tgid) {
21053                                 int err = group_send_sig_info(sig, info, p);
21054                                 ++count;
21055                                 if (err != -EPERM)
21056 @@ -1881,6 +1896,11 @@ relock:
21057                 if (current == child_reaper)
21058                         continue;
21059  
21060 +               /* virtual init is protected against user signals */
21061 +               if ((info->si_code == SI_USER) &&
21062 +                       vx_current_initpid(current->pid))
21063 +                       continue;
21064 +
21065                 if (sig_kernel_stop(signr)) {
21066                         /*
21067                          * The default action is to stop all threads in
21068 diff -NurpP --minimal linux-2.6.19.1/kernel/softirq.c linux-2.6.19.1-vs2.3.0.6/kernel/softirq.c
21069 --- linux-2.6.19.1/kernel/softirq.c     2006-12-13 07:46:36 +0100
21070 +++ linux-2.6.19.1-vs2.3.0.6/kernel/softirq.c   2006-12-13 09:16:31 +0100
21071 @@ -17,6 +17,7 @@
21072  #include <linux/kthread.h>
21073  #include <linux/rcupdate.h>
21074  #include <linux/smp.h>
21075 +#include <linux/vs_context.h>
21076  
21077  #include <asm/irq.h>
21078  /*
21079 diff -NurpP --minimal linux-2.6.19.1/kernel/sys.c linux-2.6.19.1-vs2.3.0.6/kernel/sys.c
21080 --- linux-2.6.19.1/kernel/sys.c 2006-11-30 21:19:44 +0100
21081 +++ linux-2.6.19.1-vs2.3.0.6/kernel/sys.c       2006-12-02 01:37:05 +0100
21082 @@ -10,6 +10,7 @@
21083  #include <linux/mman.h>
21084  #include <linux/smp_lock.h>
21085  #include <linux/notifier.h>
21086 +#include <linux/kmod.h>
21087  #include <linux/reboot.h>
21088  #include <linux/prctl.h>
21089  #include <linux/highuid.h>
21090 @@ -33,6 +34,7 @@
21091  #include <linux/compat.h>
21092  #include <linux/syscalls.h>
21093  #include <linux/kprobes.h>
21094 +#include <linux/vs_pid.h>
21095  
21096  #include <asm/uaccess.h>
21097  #include <asm/io.h>
21098 @@ -569,7 +571,10 @@ static int set_one_prio(struct task_stru
21099                 goto out;
21100         }
21101         if (niceval < task_nice(p) && !can_nice(p, niceval)) {
21102 -               error = -EACCES;
21103 +               if (vx_flags(VXF_IGNEG_NICE, 0))
21104 +                       error = 0;
21105 +               else
21106 +                       error = -EACCES;
21107                 goto out;
21108         }
21109         no_nice = security_task_setnice(p, niceval);
21110 @@ -621,7 +626,8 @@ asmlinkage long sys_setpriority(int whic
21111                         if (!who)
21112                                 who = current->uid;
21113                         else
21114 -                               if ((who != current->uid) && !(user = find_user(who)))
21115 +                               if ((who != current->uid) &&
21116 +                                       !(user = find_user(vx_current_xid(), who)))
21117                                         goto out_unlock;        /* No processes for this user */
21118  
21119                         do_each_thread(g, p)
21120 @@ -679,7 +685,8 @@ asmlinkage long sys_getpriority(int whic
21121                         if (!who)
21122                                 who = current->uid;
21123                         else
21124 -                               if ((who != current->uid) && !(user = find_user(who)))
21125 +                               if ((who != current->uid) &&
21126 +                                       !(user = find_user(vx_current_xid(), who)))
21127                                         goto out_unlock;        /* No processes for this user */
21128  
21129                         do_each_thread(g, p)
21130 @@ -792,6 +799,9 @@ void kernel_power_off(void)
21131         machine_power_off();
21132  }
21133  EXPORT_SYMBOL_GPL(kernel_power_off);
21134 +
21135 +long vs_reboot(unsigned int, void __user *);
21136 +
21137  /*
21138   * Reboot system call: for obvious reasons only root may call it,
21139   * and even root needs to set up some magic numbers in the registers
21140 @@ -822,6 +832,9 @@ asmlinkage long sys_reboot(int magic1, i
21141         if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
21142                 cmd = LINUX_REBOOT_CMD_HALT;
21143  
21144 +       if (!vx_check(0, VS_ADMIN|VS_WATCH))
21145 +               return vs_reboot(cmd, arg);
21146 +
21147         lock_kernel();
21148         switch (cmd) {
21149         case LINUX_REBOOT_CMD_RESTART:
21150 @@ -1001,7 +1014,7 @@ static int set_user(uid_t new_ruid, int 
21151  {
21152         struct user_struct *new_user;
21153  
21154 -       new_user = alloc_uid(new_ruid);
21155 +       new_user = alloc_uid(vx_current_xid(), new_ruid);
21156         if (!new_user)
21157                 return -EAGAIN;
21158  
21159 @@ -1356,15 +1369,18 @@ asmlinkage long sys_setpgid(pid_t pid, p
21160  {
21161         struct task_struct *p;
21162         struct task_struct *group_leader = current->group_leader;
21163 +       pid_t rpgid;
21164         int err = -EINVAL;
21165  
21166         if (!pid)
21167 -               pid = group_leader->pid;
21168 +               pid = vx_map_pid(group_leader->pid);
21169         if (!pgid)
21170                 pgid = pid;
21171         if (pgid < 0)
21172                 return -EINVAL;
21173  
21174 +       rpgid = vx_rmap_pid(pgid);
21175 +
21176         /* From this point forward we keep holding onto the tasklist lock
21177          * so that our parent does not change from under us. -DaveM
21178          */
21179 @@ -1399,22 +1415,22 @@ asmlinkage long sys_setpgid(pid_t pid, p
21180         if (pgid != pid) {
21181                 struct task_struct *p;
21182  
21183 -               do_each_task_pid(pgid, PIDTYPE_PGID, p) {
21184 +               do_each_task_pid(rpgid, PIDTYPE_PGID, p) {
21185                         if (p->signal->session == group_leader->signal->session)
21186                                 goto ok_pgid;
21187 -               } while_each_task_pid(pgid, PIDTYPE_PGID, p);
21188 +               } while_each_task_pid(rpgid, PIDTYPE_PGID, p);
21189                 goto out;
21190         }
21191  
21192  ok_pgid:
21193 -       err = security_task_setpgid(p, pgid);
21194 +       err = security_task_setpgid(p, rpgid);
21195         if (err)
21196                 goto out;
21197  
21198 -       if (process_group(p) != pgid) {
21199 +       if (process_group(p) != rpgid) {
21200                 detach_pid(p, PIDTYPE_PGID);
21201 -               p->signal->pgrp = pgid;
21202 -               attach_pid(p, PIDTYPE_PGID, pgid);
21203 +               p->signal->pgrp = rpgid;
21204 +               attach_pid(p, PIDTYPE_PGID, rpgid);
21205         }
21206  
21207         err = 0;
21208 @@ -1427,7 +1443,7 @@ out:
21209  asmlinkage long sys_getpgid(pid_t pid)
21210  {
21211         if (!pid)
21212 -               return process_group(current);
21213 +               return vx_rmap_pid(process_group(current));
21214         else {
21215                 int retval;
21216                 struct task_struct *p;
21217 @@ -1439,7 +1455,7 @@ asmlinkage long sys_getpgid(pid_t pid)
21218                 if (p) {
21219                         retval = security_task_getpgid(p);
21220                         if (!retval)
21221 -                               retval = process_group(p);
21222 +                               retval = vx_rmap_pid(process_group(p));
21223                 }
21224                 read_unlock(&tasklist_lock);
21225                 return retval;
21226 @@ -1789,7 +1805,7 @@ asmlinkage long sys_sethostname(char __u
21227         int errno;
21228         char tmp[__NEW_UTS_LEN];
21229  
21230 -       if (!capable(CAP_SYS_ADMIN))
21231 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME))
21232                 return -EPERM;
21233         if (len < 0 || len > __NEW_UTS_LEN)
21234                 return -EINVAL;
21235 @@ -1834,7 +1850,7 @@ asmlinkage long sys_setdomainname(char _
21236         int errno;
21237         char tmp[__NEW_UTS_LEN];
21238  
21239 -       if (!capable(CAP_SYS_ADMIN))
21240 +       if (!vx_capable(CAP_SYS_ADMIN, VXC_SET_UTSNAME))
21241                 return -EPERM;
21242         if (len < 0 || len > __NEW_UTS_LEN)
21243                 return -EINVAL;
21244 @@ -1901,7 +1917,7 @@ asmlinkage long sys_setrlimit(unsigned i
21245                 return -EINVAL;
21246         old_rlim = current->signal->rlim + resource;
21247         if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
21248 -           !capable(CAP_SYS_RESOURCE))
21249 +           !vx_capable(CAP_SYS_RESOURCE, VXC_SET_RLIMIT))
21250                 return -EPERM;
21251         if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN)
21252                 return -EPERM;
21253 diff -NurpP --minimal linux-2.6.19.1/kernel/sysctl.c linux-2.6.19.1-vs2.3.0.6/kernel/sysctl.c
21254 --- linux-2.6.19.1/kernel/sysctl.c      2006-11-30 21:19:44 +0100
21255 +++ linux-2.6.19.1-vs2.3.0.6/kernel/sysctl.c    2006-12-02 01:37:05 +0100
21256 @@ -87,6 +87,7 @@ static int ngroups_max = NGROUPS_MAX;
21257  #ifdef CONFIG_KMOD
21258  extern char modprobe_path[];
21259  #endif
21260 +extern char vshelper_path[];
21261  #ifdef CONFIG_CHR_DEV_SG
21262  extern int sg_big_buff;
21263  #endif
21264 @@ -456,6 +457,15 @@ static ctl_table kern_table[] = {
21265                 .strategy       = &sysctl_string,
21266         },
21267  #endif
21268 +       {
21269 +               .ctl_name       = KERN_VSHELPER,
21270 +               .procname       = "vshelper",
21271 +               .data           = &vshelper_path,
21272 +               .maxlen         = 256,
21273 +               .mode           = 0644,
21274 +               .proc_handler   = &proc_dostring,
21275 +               .strategy       = &sysctl_string,
21276 +       },
21277  #ifdef CONFIG_CHR_DEV_SG
21278         {
21279                 .ctl_name       = KERN_SG_BIG_BUFF,
21280 diff -NurpP --minimal linux-2.6.19.1/kernel/time.c linux-2.6.19.1-vs2.3.0.6/kernel/time.c
21281 --- linux-2.6.19.1/kernel/time.c        2006-11-30 21:19:44 +0100
21282 +++ linux-2.6.19.1-vs2.3.0.6/kernel/time.c      2006-11-08 04:57:44 +0100
21283 @@ -61,7 +61,7 @@ asmlinkage long sys_time(time_t __user *
21284         time_t i;
21285         struct timeval tv;
21286  
21287 -       do_gettimeofday(&tv);
21288 +       vx_gettimeofday(&tv);
21289         i = tv.tv_sec;
21290  
21291         if (tloc) {
21292 @@ -92,7 +92,7 @@ asmlinkage long sys_stime(time_t __user 
21293         if (err)
21294                 return err;
21295  
21296 -       do_settimeofday(&tv);
21297 +       vx_settimeofday(&tv);
21298         return 0;
21299  }
21300  
21301 @@ -102,7 +102,7 @@ asmlinkage long sys_gettimeofday(struct 
21302  {
21303         if (likely(tv != NULL)) {
21304                 struct timeval ktv;
21305 -               do_gettimeofday(&ktv);
21306 +               vx_gettimeofday(&ktv);
21307                 if (copy_to_user(tv, &ktv, sizeof(ktv)))
21308                         return -EFAULT;
21309         }
21310 @@ -176,7 +176,7 @@ int do_sys_settimeofday(struct timespec 
21311                 /* SMP safe, again the code in arch/foo/time.c should
21312                  * globally block out interrupts when it runs.
21313                  */
21314 -               return do_settimeofday(tv);
21315 +               return vx_settimeofday(tv);
21316         }
21317         return 0;
21318  }
21319 @@ -359,7 +359,7 @@ void getnstimeofday(struct timespec *tv)
21320  {
21321         struct timeval x;
21322  
21323 -       do_gettimeofday(&x);
21324 +       vx_gettimeofday(&x);
21325         tv->tv_sec = x.tv_sec;
21326         tv->tv_nsec = x.tv_usec * NSEC_PER_USEC;
21327  }
21328 diff -NurpP --minimal linux-2.6.19.1/kernel/timer.c linux-2.6.19.1-vs2.3.0.6/kernel/timer.c
21329 --- linux-2.6.19.1/kernel/timer.c       2006-11-30 21:19:44 +0100
21330 +++ linux-2.6.19.1-vs2.3.0.6/kernel/timer.c     2006-11-08 06:18:54 +0100
21331 @@ -34,6 +34,10 @@
21332  #include <linux/time.h>
21333  #include <linux/jiffies.h>
21334  #include <linux/posix-timers.h>
21335 +#include <linux/vs_base.h>
21336 +#include <linux/vs_cvirt.h>
21337 +#include <linux/vs_pid.h>
21338 +#include <linux/vserver/sched.h>
21339  #include <linux/cpu.h>
21340  #include <linux/syscalls.h>
21341  #include <linux/delay.h>
21342 @@ -1082,12 +1086,6 @@ asmlinkage unsigned long sys_alarm(unsig
21343  
21344  #endif
21345  
21346 -#ifndef __alpha__
21347 -
21348 -/*
21349 - * The Alpha uses getxpid, getxuid, and getxgid instead.  Maybe this
21350 - * should be moved into arch/i386 instead?
21351 - */
21352  
21353  /**
21354   * sys_getpid - return the thread group id of the current process
21355 @@ -1100,7 +1098,7 @@ asmlinkage unsigned long sys_alarm(unsig
21356   */
21357  asmlinkage long sys_getpid(void)
21358  {
21359 -       return current->tgid;
21360 +       return vx_map_tgid(current->tgid);
21361  }
21362  
21363  /*
21364 @@ -1116,10 +1114,23 @@ asmlinkage long sys_getppid(void)
21365         rcu_read_lock();
21366         pid = rcu_dereference(current->real_parent)->tgid;
21367         rcu_read_unlock();
21368 +       return vx_map_pid(pid);
21369 +}
21370  
21371 -       return pid;
21372 +#ifdef __alpha__
21373 +
21374 +/*
21375 + * The Alpha uses getxpid, getxuid, and getxgid instead.
21376 + */
21377 +
21378 +asmlinkage long do_getxpid(long *ppid)
21379 +{
21380 +       *ppid = sys_getppid();
21381 +       return sys_getpid();
21382  }
21383  
21384 +#else /* _alpha_ */
21385 +
21386  asmlinkage long sys_getuid(void)
21387  {
21388         /* Only we change this so SMP safe */
21389 @@ -1281,6 +1292,8 @@ asmlinkage long sys_sysinfo(struct sysin
21390                         tp.tv_nsec = tp.tv_nsec - NSEC_PER_SEC;
21391                         tp.tv_sec++;
21392                 }
21393 +               if (vx_flags(VXF_VIRT_UPTIME, 0))
21394 +                       vx_vsi_uptime(&tp, NULL);
21395                 val.uptime = tp.tv_sec + (tp.tv_nsec ? 1 : 0);
21396  
21397                 val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT);
21398 diff -NurpP --minimal linux-2.6.19.1/kernel/user.c linux-2.6.19.1-vs2.3.0.6/kernel/user.c
21399 --- linux-2.6.19.1/kernel/user.c        2006-11-30 21:19:44 +0100
21400 +++ linux-2.6.19.1-vs2.3.0.6/kernel/user.c      2006-11-08 21:52:09 +0100
21401 @@ -23,8 +23,8 @@
21402  #define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 8)
21403  #define UIDHASH_SZ             (1 << UIDHASH_BITS)
21404  #define UIDHASH_MASK           (UIDHASH_SZ - 1)
21405 -#define __uidhashfn(uid)       (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK)
21406 -#define uidhashentry(uid)      (uidhash_table + __uidhashfn((uid)))
21407 +#define __uidhashfn(xid,uid)   ((((uid) >> UIDHASH_BITS) + ((uid)^(xid))) & UIDHASH_MASK)
21408 +#define uidhashentry(xid,uid)  (uidhash_table + __uidhashfn((xid),(uid)))
21409  
21410  static kmem_cache_t *uid_cachep;
21411  static struct list_head uidhash_table[UIDHASH_SZ];
21412 @@ -66,7 +66,7 @@ static inline void uid_hash_remove(struc
21413         list_del(&up->uidhash_list);
21414  }
21415  
21416 -static inline struct user_struct *uid_hash_find(uid_t uid, struct list_head *hashent)
21417 +static inline struct user_struct *uid_hash_find(xid_t xid, uid_t uid, struct list_head *hashent)
21418  {
21419         struct list_head *up;
21420  
21421 @@ -75,7 +75,7 @@ static inline struct user_struct *uid_ha
21422  
21423                 user = list_entry(up, struct user_struct, uidhash_list);
21424  
21425 -               if(user->uid == uid) {
21426 +               if(user->uid == uid && user->xid == xid) {
21427                         atomic_inc(&user->__count);
21428                         return user;
21429                 }
21430 @@ -90,13 +90,13 @@ static inline struct user_struct *uid_ha
21431   *
21432   * If the user_struct could not be found, return NULL.
21433   */
21434 -struct user_struct *find_user(uid_t uid)
21435 +struct user_struct *find_user(xid_t xid, uid_t uid)
21436  {
21437         struct user_struct *ret;
21438         unsigned long flags;
21439  
21440         spin_lock_irqsave(&uidhash_lock, flags);
21441 -       ret = uid_hash_find(uid, uidhashentry(uid));
21442 +       ret = uid_hash_find(xid, uid, uidhashentry(xid, uid));
21443         spin_unlock_irqrestore(&uidhash_lock, flags);
21444         return ret;
21445  }
21446 @@ -120,13 +120,13 @@ void free_uid(struct user_struct *up)
21447         }
21448  }
21449  
21450 -struct user_struct * alloc_uid(uid_t uid)
21451 +struct user_struct * alloc_uid(xid_t xid, uid_t uid)
21452  {
21453 -       struct list_head *hashent = uidhashentry(uid);
21454 +       struct list_head *hashent = uidhashentry(xid, uid);
21455         struct user_struct *up;
21456  
21457         spin_lock_irq(&uidhash_lock);
21458 -       up = uid_hash_find(uid, hashent);
21459 +       up = uid_hash_find(xid, uid, hashent);
21460         spin_unlock_irq(&uidhash_lock);
21461  
21462         if (!up) {
21463 @@ -136,6 +136,7 @@ struct user_struct * alloc_uid(uid_t uid
21464                 if (!new)
21465                         return NULL;
21466                 new->uid = uid;
21467 +               new->xid = xid;
21468                 atomic_set(&new->__count, 1);
21469                 atomic_set(&new->processes, 0);
21470                 atomic_set(&new->files, 0);
21471 @@ -158,7 +159,7 @@ struct user_struct * alloc_uid(uid_t uid
21472                  * on adding the same user already..
21473                  */
21474                 spin_lock_irq(&uidhash_lock);
21475 -               up = uid_hash_find(uid, hashent);
21476 +               up = uid_hash_find(xid, uid, hashent);
21477                 if (up) {
21478                         key_put(new->uid_keyring);
21479                         key_put(new->session_keyring);
21480 @@ -215,7 +216,7 @@ static int __init uid_cache_init(void)
21481  
21482         /* Insert the root user immediately (init already runs as root) */
21483         spin_lock_irq(&uidhash_lock);
21484 -       uid_hash_insert(&root_user, uidhashentry(0));
21485 +       uid_hash_insert(&root_user, uidhashentry(0,0));
21486         spin_unlock_irq(&uidhash_lock);
21487  
21488         return 0;
21489 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/Kconfig linux-2.6.19.1-vs2.3.0.6/kernel/vserver/Kconfig
21490 --- linux-2.6.19.1/kernel/vserver/Kconfig       1970-01-01 01:00:00 +0100
21491 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/Kconfig     2006-12-17 04:04:22 +0100
21492 @@ -0,0 +1,241 @@
21493 +#
21494 +# Linux VServer configuration
21495 +#
21496 +
21497 +menu "Linux VServer"
21498 +
21499 +config VSERVER_SINGLE_IP
21500 +       bool    "Single IP Special Casing"
21501 +       depends on EXPERIMENTAL
21502 +       default n
21503 +       help
21504 +         This allows to have network contexts with a single
21505 +         IP to remap 0.0.0.0 bindings to that IP, avoiding
21506 +         further network checks and improving performance.
21507 +
21508 +         (note: such guests do not allow to change the ip
21509 +          on the fly and do not show loopback addresses)
21510 +
21511 +config VSERVER_AUTO_LBACK
21512 +       bool    "Automatically Assign Loopback IP"
21513 +       default y
21514 +       help
21515 +         This allows to have network contexts with a single
21516 +         IP to remap 0.0.0.0 bindings to that IP, avoiding
21517 +         further network checks and improving performance.
21518 +
21519 +         (note: such guests do not allow to change the ip
21520 +          on the fly and do not show loopback addresses)
21521 +
21522 +config VSERVER_COWBL
21523 +       bool    "Enable COW Immutable Link Breaking"
21524 +       depends on EXPERIMENTAL
21525 +       default y
21526 +       help
21527 +         This enables the COW (Copy-On-Write) link break code.
21528 +         It allows you to treat unified files like normal files
21529 +         when writing to them (which will implicitely break the
21530 +         link and create a copy of the unified file)
21531 +
21532 +config VSERVER_VTIME
21533 +       bool    "Enable Virtualized Guest Time"
21534 +       depends on EXPERIMENTAL
21535 +       default n
21536 +       help
21537 +         This enables per guest time offsets to allow for
21538 +         adjusting the system clock individually per guest.
21539 +         this adds some overhead to the time functions and
21540 +         therefore should not be enabled without good reason.
21541 +
21542 +config VSERVER_PROC_SECURE
21543 +       bool    "Enable Proc Security"
21544 +       depends on PROC_FS
21545 +       default y
21546 +       help
21547 +         This configures ProcFS security to initially hide
21548 +         non-process entries for all contexts except the main and
21549 +         spectator context (i.e. for all guests), which is a secure
21550 +         default.
21551 +
21552 +         (note: on 1.2x the entries were visible by default)
21553 +
21554 +config VSERVER_HARDCPU
21555 +       bool    "Enable Hard CPU Limits"
21556 +       depends on EXPERIMENTAL
21557 +       default n
21558 +       help
21559 +         Activate the Hard CPU Limits
21560 +
21561 +         This will compile in code that allows the Token Bucket
21562 +         Scheduler to put processes on hold when a context's
21563 +         tokens are depleted (provided that its per-context
21564 +         sched_hard flag is set).
21565 +
21566 +         Processes belonging to that context will not be able
21567 +         to consume CPU resources again until a per-context
21568 +         configured minimum of tokens has been reached.
21569 +
21570 +config VSERVER_IDLETIME
21571 +       bool    "Avoid idle CPUs by skipping Time"
21572 +       depends on VSERVER_HARDCPU
21573 +       default n
21574 +       help
21575 +         This option allows the scheduler to artificially
21576 +         advance time (per cpu) when otherwise the idle
21577 +         task would be scheduled, thus keeping the cpu
21578 +         busy and sharing the available resources among
21579 +         certain contexts.
21580 +
21581 +config VSERVER_IDLELIMIT
21582 +       bool    "Limit the IDLE task"
21583 +       depends on VSERVER_HARDCPU
21584 +       default n
21585 +       help
21586 +         Limit the idle slices, so the the next context
21587 +         will be scheduled as soon as possible.
21588 +
21589 +         This might improve interactivity and latency, but
21590 +         will also marginally increase scheduling overhead.
21591 +
21592 +choice
21593 +       prompt  "Persistent Inode Tagging"
21594 +       default TAGGING_ID24
21595 +       help
21596 +         This adds persistent context information to filesystems
21597 +         mounted with the tagxid option. Tagging is a requirement
21598 +         for per-context disk limits and per-context quota.
21599 +
21600 +
21601 +config TAGGING_NONE
21602 +       bool    "Disabled"
21603 +       help
21604 +         do not store per-context information in inodes.
21605 +
21606 +config TAGGING_UID16
21607 +       bool    "UID16/GID32"
21608 +       help
21609 +         reduces UID to 16 bit, but leaves GID at 32 bit.
21610 +
21611 +config TAGGING_GID16
21612 +       bool    "UID32/GID16"
21613 +       help
21614 +         reduces GID to 16 bit, but leaves UID at 32 bit.
21615 +
21616 +config TAGGING_ID24
21617 +       bool    "UID24/GID24"
21618 +       help
21619 +         uses the upper 8bit from UID and GID for XID tagging
21620 +         which leaves 24bit for UID/GID each, which should be
21621 +         more than sufficient for normal use.
21622 +
21623 +config TAGGING_INTERN
21624 +       bool    "UID32/GID32"
21625 +       help
21626 +         this uses otherwise reserved inode fields in the on
21627 +         disk representation, which limits the use to a few
21628 +         filesystems (currently ext2 and ext3)
21629 +
21630 +config TAGGING_RUNTIME
21631 +       bool    "Runtime"
21632 +       depends on EXPERIMENTAL
21633 +       help
21634 +         inodes are tagged when first accessed, this doesn't
21635 +         require any persistant information, but might give
21636 +         funny results for mixed access.
21637 +
21638 +endchoice
21639 +
21640 +config TAG_NFSD
21641 +       bool    "Tag NFSD User Auth and Files"
21642 +       default n
21643 +       help
21644 +         Enable this if you do want the in-kernel NFS
21645 +         Server to use the tagging specified above.
21646 +         (will require patched clients too)
21647 +
21648 +config PROPAGATE
21649 +       bool    "Enable Inode Tag Propagation"
21650 +       default n
21651 +       depends on EXPERIMENTAL
21652 +       help
21653 +         This allows for the tagid= mount option to specify
21654 +         a tagid which is to be used for the entire mount
21655 +         tree.
21656 +
21657 +config VSERVER_PRIVACY
21658 +       bool    "Honor Privacy Aspects of Guests"
21659 +       default y
21660 +       help
21661 +         When enabled, most context checks will disallow
21662 +         access to structures assigned to a specific context,
21663 +         like ptys or loop devices.
21664 +
21665 +config VSERVER_DEBUG
21666 +       bool    "VServer Debugging Code"
21667 +       default n
21668 +       help
21669 +         Set this to yes if you want to be able to activate
21670 +         debugging output at runtime. It adds a probably small
21671 +         overhead to all vserver related functions and
21672 +         increases the kernel size by about 20k.
21673 +
21674 +config VSERVER_HISTORY
21675 +       bool    "VServer History Tracing"
21676 +       depends on VSERVER_DEBUG
21677 +       default n
21678 +       help
21679 +         Set this to yes if you want to record the history of
21680 +         linux-vserver activities, so they can be replayed in
21681 +         the event of a kernel panic or oops.
21682 +
21683 +config VSERVER_HISTORY_SIZE
21684 +       int     "Per-CPU History Size (32-65536)"
21685 +       depends on VSERVER_HISTORY
21686 +       range 32 65536
21687 +       default 64
21688 +       help
21689 +         This allows you to specify the number of entries in
21690 +         the per-CPU history buffer.
21691 +
21692 +config VSERVER_MONITOR
21693 +       bool    "VServer Scheduling Monitor"
21694 +       depends on VSERVER_DEBUG
21695 +       default n
21696 +       help
21697 +         Set this to yes if you want to record the scheduling
21698 +         decisions, so that they can be relayed to userspace
21699 +         for detailed analysis.
21700 +
21701 +config VSERVER_MONITOR_SIZE
21702 +       int     "Per-CPU Monitor Queue Size (32-65536)"
21703 +       depends on VSERVER_MONITOR
21704 +       range 32 65536
21705 +       default 1024
21706 +       help
21707 +         This allows you to specify the number of entries in
21708 +         the per-CPU scheduling monitor buffer.
21709 +
21710 +config VSERVER_MONITOR_SYNC
21711 +       int     "Per-CPU Monitor Sync Interval (0-65536)"
21712 +       depends on VSERVER_MONITOR
21713 +       range 0 65536
21714 +       default 256
21715 +       help
21716 +         This allows you to specify the interval in ticks
21717 +         when a time sync entry is inserted.
21718 +
21719 +endmenu
21720 +
21721 +
21722 +config VSERVER
21723 +       bool
21724 +       default y
21725 +       select UTS_NS
21726 +       select IPC_NS
21727 +
21728 +config VSERVER_SECURITY
21729 +       bool
21730 +       depends on SECURITY
21731 +       default y
21732 +       select SECURITY_CAPABILITIES
21733 +
21734 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/Makefile linux-2.6.19.1-vs2.3.0.6/kernel/vserver/Makefile
21735 --- linux-2.6.19.1/kernel/vserver/Makefile      1970-01-01 01:00:00 +0100
21736 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/Makefile    2006-12-17 04:10:21 +0100
21737 @@ -0,0 +1,16 @@
21738 +#
21739 +# Makefile for the Linux vserver routines.
21740 +#
21741 +
21742 +
21743 +obj-y          += vserver.o
21744 +
21745 +vserver-y      := switch.o context.o space.o sched.o network.o inode.o \
21746 +                  limit.o cvirt.o cacct.o signal.o helper.o init.o dlimit.o
21747 +
21748 +vserver-$(CONFIG_INET) += inet.o
21749 +vserver-$(CONFIG_PROC_FS) += proc.o
21750 +vserver-$(CONFIG_VSERVER_DEBUG) += sysctl.o debug.o
21751 +vserver-$(CONFIG_VSERVER_HISTORY) += history.o
21752 +vserver-$(CONFIG_VSERVER_MONITOR) += monitor.o
21753 +
21754 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cacct.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct.c
21755 --- linux-2.6.19.1/kernel/vserver/cacct.c       1970-01-01 01:00:00 +0100
21756 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct.c     2006-11-30 18:53:18 +0100
21757 @@ -0,0 +1,44 @@
21758 +/*
21759 + *  linux/kernel/vserver/cacct.c
21760 + *
21761 + *  Virtual Server: Context Accounting
21762 + *
21763 + *  Copyright (C) 2006  Herbert Pötzl
21764 + *
21765 + *  V0.01  added accounting stats
21766 + *
21767 + */
21768 +
21769 +#include <linux/types.h>
21770 +#include <linux/sched.h>
21771 +#include <linux/vs_context.h>
21772 +#include <linux/vserver/switch.h>
21773 +#include <linux/vserver/cacct_cmd.h>
21774 +#include <linux/vserver/cacct_int.h>
21775 +
21776 +#include <asm/errno.h>
21777 +#include <asm/uaccess.h>
21778 +
21779 +
21780 +int vc_sock_stat(struct vx_info *vxi, void __user *data)
21781 +{
21782 +       struct vcmd_sock_stat_v0 vc_data;
21783 +       int j, field;
21784 +
21785 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
21786 +               return -EFAULT;
21787 +
21788 +       field = vc_data.field;
21789 +       if ((field < 0) || (field >= VXA_SOCK_SIZE))
21790 +               return -EINVAL;
21791 +
21792 +       for (j=0; j<3; j++) {
21793 +               vc_data.count[j] = vx_sock_count(&vxi->cacct, field, j);
21794 +               vc_data.total[j] = vx_sock_total(&vxi->cacct, field, j);
21795 +       }
21796 +
21797 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
21798 +               return -EFAULT;
21799 +       return 0;
21800 +}
21801 +
21802 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cacct_init.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct_init.h
21803 --- linux-2.6.19.1/kernel/vserver/cacct_init.h  1970-01-01 01:00:00 +0100
21804 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct_init.h        2006-11-08 04:57:49 +0100
21805 @@ -0,0 +1,25 @@
21806 +
21807 +
21808 +static inline void vx_info_init_cacct(struct _vx_cacct *cacct)
21809 +{
21810 +       int i,j;
21811 +
21812 +
21813 +       for (i=0; i<VXA_SOCK_SIZE; i++) {
21814 +               for (j=0; j<3; j++) {
21815 +                       atomic_set(&cacct->sock[i][j].count, 0);
21816 +                       atomic_set(&cacct->sock[i][j].total, 0);
21817 +               }
21818 +       }
21819 +       for (i=0; i<8; i++)
21820 +               atomic_set(&cacct->slab[i], 0);
21821 +       for (i=0; i<5; i++)
21822 +               for (j=0; j<4; j++)
21823 +                       atomic_set(&cacct->page[i][j], 0);
21824 +}
21825 +
21826 +static inline void vx_info_exit_cacct(struct _vx_cacct *cacct)
21827 +{
21828 +       return;
21829 +}
21830 +
21831 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cacct_proc.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct_proc.h
21832 --- linux-2.6.19.1/kernel/vserver/cacct_proc.h  1970-01-01 01:00:00 +0100
21833 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cacct_proc.h        2006-11-08 04:57:49 +0100
21834 @@ -0,0 +1,58 @@
21835 +#ifndef _VX_CACCT_PROC_H
21836 +#define _VX_CACCT_PROC_H
21837 +
21838 +#include <linux/vserver/cacct_int.h>
21839 +
21840 +
21841 +#define VX_SOCKA_TOP   \
21842 +       "Type\t    recv #/bytes\t\t   send #/bytes\t\t    fail #/bytes\n"
21843 +
21844 +static inline int vx_info_proc_cacct(struct _vx_cacct *cacct, char *buffer)
21845 +{
21846 +       int i,j, length = 0;
21847 +       static char *type[VXA_SOCK_SIZE] = {
21848 +               "UNSPEC", "UNIX", "INET", "INET6", "PACKET", "OTHER" };
21849 +
21850 +       length += sprintf(buffer + length, VX_SOCKA_TOP);
21851 +       for (i=0; i<VXA_SOCK_SIZE; i++) {
21852 +               length += sprintf(buffer + length,
21853 +                       "%s:", type[i]);
21854 +               for (j=0; j<3; j++) {
21855 +                       length += sprintf(buffer + length,
21856 +                               "\t%10lu/%-10lu"
21857 +                               ,vx_sock_count(cacct, i, j)
21858 +                               ,vx_sock_total(cacct, i, j)
21859 +                               );
21860 +               }
21861 +               buffer[length++] = '\n';
21862 +       }
21863 +
21864 +       length += sprintf(buffer + length, "\n");
21865 +       length += sprintf(buffer + length,
21866 +               "slab:\t %8u %8u %8u %8u\n"
21867 +               ,atomic_read(&cacct->slab[1])
21868 +               ,atomic_read(&cacct->slab[4])
21869 +               ,atomic_read(&cacct->slab[0])
21870 +               ,atomic_read(&cacct->slab[2])
21871 +               );
21872 +
21873 +       length += sprintf(buffer + length, "\n");
21874 +       for (i=0; i<5; i++) {
21875 +               length += sprintf(buffer + length,
21876 +                       "page[%d]: %8u %8u %8u %8u\t %8u %8u %8u %8u\n"
21877 +                       ,i
21878 +                       ,atomic_read(&cacct->page[i][0])
21879 +                       ,atomic_read(&cacct->page[i][1])
21880 +                       ,atomic_read(&cacct->page[i][2])
21881 +                       ,atomic_read(&cacct->page[i][3])
21882 +                       ,atomic_read(&cacct->page[i][4])
21883 +                       ,atomic_read(&cacct->page[i][5])
21884 +                       ,atomic_read(&cacct->page[i][6])
21885 +                       ,atomic_read(&cacct->page[i][7])
21886 +                       );
21887 +       }
21888 +
21889 +       return length;
21890 +}
21891 +
21892 +#endif /* _VX_CACCT_PROC_H */
21893 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/context.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/context.c
21894 --- linux-2.6.19.1/kernel/vserver/context.c     1970-01-01 01:00:00 +0100
21895 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/context.c   2006-12-17 05:32:40 +0100
21896 @@ -0,0 +1,959 @@
21897 +/*
21898 + *  linux/kernel/vserver/context.c
21899 + *
21900 + *  Virtual Server: Context Support
21901 + *
21902 + *  Copyright (C) 2003-2006  Herbert Pötzl
21903 + *
21904 + *  V0.01  context helper
21905 + *  V0.02  vx_ctx_kill syscall command
21906 + *  V0.03  replaced context_info calls
21907 + *  V0.04  redesign of struct (de)alloc
21908 + *  V0.05  rlimit basic implementation
21909 + *  V0.06  task_xid and info commands
21910 + *  V0.07  context flags and caps
21911 + *  V0.08  switch to RCU based hash
21912 + *  V0.09  revert to non RCU for now
21913 + *  V0.10  and back to working RCU hash
21914 + *  V0.11  and back to locking again
21915 + *  V0.12  referenced context store
21916 + *  V0.13  separate per cpu data
21917 + *  V0.14  changed vcmds to vxi arg
21918 + *  V0.15  added context stat
21919 + *
21920 + */
21921 +
21922 +#include <linux/slab.h>
21923 +#include <linux/types.h>
21924 +#include <linux/namespace.h>
21925 +
21926 +#include <linux/sched.h>
21927 +#include <linux/vserver/context.h>
21928 +#include <linux/vserver/network.h>
21929 +#include <linux/vserver/debug.h>
21930 +#include <linux/vserver/limit.h>
21931 +#include <linux/vserver/limit_int.h>
21932 +#include <linux/vserver/space.h>
21933 +
21934 +#include <linux/vs_context.h>
21935 +#include <linux/vs_limit.h>
21936 +#include <linux/vserver/context_cmd.h>
21937 +
21938 +#include <linux/err.h>
21939 +#include <asm/errno.h>
21940 +
21941 +#include "cvirt_init.h"
21942 +#include "cacct_init.h"
21943 +#include "limit_init.h"
21944 +#include "sched_init.h"
21945 +
21946 +
21947 +atomic_t vx_global_ctotal      = ATOMIC_INIT(0);
21948 +atomic_t vx_global_cactive     = ATOMIC_INIT(0);
21949 +
21950 +
21951 +/*     now inactive context structures */
21952 +
21953 +static struct hlist_head vx_info_inactive = HLIST_HEAD_INIT;
21954 +
21955 +static spinlock_t vx_info_inactive_lock = SPIN_LOCK_UNLOCKED;
21956 +
21957 +
21958 +/*     __alloc_vx_info()
21959 +
21960 +       * allocate an initialized vx_info struct
21961 +       * doesn't make it visible (hash)                        */
21962 +
21963 +static struct vx_info *__alloc_vx_info(xid_t xid)
21964 +{
21965 +       struct vx_info *new = NULL;
21966 +       int cpu;
21967 +
21968 +       vxdprintk(VXD_CBIT(xid, 0), "alloc_vx_info(%d)*", xid);
21969 +
21970 +       /* would this benefit from a slab cache? */
21971 +       new = kmalloc(sizeof(struct vx_info), GFP_KERNEL);
21972 +       if (!new)
21973 +               return 0;
21974 +
21975 +       memset (new, 0, sizeof(struct vx_info));
21976 +#ifdef CONFIG_SMP
21977 +       new->ptr_pc = alloc_percpu(struct _vx_info_pc);
21978 +       if (!new->ptr_pc)
21979 +               goto error;
21980 +#endif
21981 +       new->vx_id = xid;
21982 +       INIT_HLIST_NODE(&new->vx_hlist);
21983 +       atomic_set(&new->vx_usecnt, 0);
21984 +       atomic_set(&new->vx_tasks, 0);
21985 +       new->vx_parent = NULL;
21986 +       new->vx_state = 0;
21987 +       init_waitqueue_head(&new->vx_wait);
21988 +
21989 +       /* prepare reaper */
21990 +       get_task_struct(child_reaper);
21991 +       new->vx_reaper = child_reaper;
21992 +
21993 +       /* rest of init goes here */
21994 +       vx_info_init_limit(&new->limit);
21995 +       vx_info_init_sched(&new->sched);
21996 +       vx_info_init_cvirt(&new->cvirt);
21997 +       vx_info_init_cacct(&new->cacct);
21998 +
21999 +       /* per cpu data structures */
22000 +       for_each_possible_cpu(cpu) {
22001 +               vx_info_init_sched_pc(
22002 +                       &vx_per_cpu(new, sched_pc, cpu), cpu);
22003 +               vx_info_init_cvirt_pc(
22004 +                       &vx_per_cpu(new, cvirt_pc, cpu), cpu);
22005 +       }
22006 +
22007 +       new->vx_flags = VXF_INIT_SET;
22008 +       new->vx_bcaps = CAP_INIT_EFF_SET;
22009 +       new->vx_ccaps = 0;
22010 +       new->vx_cap_bset = cap_bset;
22011 +
22012 +       new->reboot_cmd = 0;
22013 +       new->exit_code = 0;
22014 +
22015 +       vxdprintk(VXD_CBIT(xid, 0),
22016 +               "alloc_vx_info(%d) = %p", xid, new);
22017 +       vxh_alloc_vx_info(new);
22018 +       atomic_inc(&vx_global_ctotal);
22019 +       return new;
22020 +#ifdef CONFIG_SMP
22021 +error:
22022 +       kfree(new);
22023 +       return 0;
22024 +#endif
22025 +}
22026 +
22027 +/*     __dealloc_vx_info()
22028 +
22029 +       * final disposal of vx_info                             */
22030 +
22031 +static void __dealloc_vx_info(struct vx_info *vxi)
22032 +{
22033 +       int cpu;
22034 +
22035 +       vxdprintk(VXD_CBIT(xid, 0),
22036 +               "dealloc_vx_info(%p)", vxi);
22037 +       vxh_dealloc_vx_info(vxi);
22038 +
22039 +       vxi->vx_id = -1;
22040 +
22041 +       vx_info_exit_limit(&vxi->limit);
22042 +       vx_info_exit_sched(&vxi->sched);
22043 +       vx_info_exit_cvirt(&vxi->cvirt);
22044 +       vx_info_exit_cacct(&vxi->cacct);
22045 +
22046 +       for_each_possible_cpu(cpu) {
22047 +               vx_info_exit_sched_pc(
22048 +                       &vx_per_cpu(vxi, sched_pc, cpu), cpu);
22049 +               vx_info_exit_cvirt_pc(
22050 +                       &vx_per_cpu(vxi, cvirt_pc, cpu), cpu);
22051 +       }
22052 +
22053 +       vxi->vx_state |= VXS_RELEASED;
22054 +
22055 +#ifdef CONFIG_SMP
22056 +       free_percpu(vxi->ptr_pc);
22057 +#endif
22058 +       kfree(vxi);
22059 +       atomic_dec(&vx_global_ctotal);
22060 +}
22061 +
22062 +static void __shutdown_vx_info(struct vx_info *vxi)
22063 +{
22064 +       struct nsproxy *nsproxy;
22065 +       struct fs_struct *fs;
22066 +
22067 +       might_sleep();
22068 +
22069 +       vxi->vx_state |= VXS_SHUTDOWN;
22070 +       vs_state_change(vxi, VSC_SHUTDOWN);
22071 +
22072 +       nsproxy = xchg(&vxi->vx_nsproxy, NULL);
22073 +       if (nsproxy)
22074 +               put_nsproxy(nsproxy);
22075 +
22076 +       fs = xchg(&vxi->vx_fs, NULL);
22077 +       if (fs)
22078 +               put_fs_struct(fs);
22079 +}
22080 +
22081 +/* exported stuff */
22082 +
22083 +void free_vx_info(struct vx_info *vxi)
22084 +{
22085 +       unsigned long flags;
22086 +
22087 +       /* context shutdown is mandatory */
22088 +       BUG_ON(!vx_info_state(vxi, VXS_SHUTDOWN));
22089 +
22090 +       BUG_ON(atomic_read(&vxi->vx_usecnt));
22091 +       BUG_ON(atomic_read(&vxi->vx_tasks));
22092 +
22093 +       BUG_ON(vx_info_state(vxi, VXS_HASHED));
22094 +
22095 +       BUG_ON(vxi->vx_nsproxy);
22096 +       BUG_ON(vxi->vx_fs);
22097 +
22098 +       spin_lock_irqsave(&vx_info_inactive_lock, flags);
22099 +       hlist_del(&vxi->vx_hlist);
22100 +       spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
22101 +
22102 +       __dealloc_vx_info(vxi);
22103 +}
22104 +
22105 +
22106 +/*     hash table for vx_info hash */
22107 +
22108 +#define VX_HASH_SIZE   13
22109 +
22110 +static struct hlist_head vx_info_hash[VX_HASH_SIZE] =
22111 +       { [0 ... VX_HASH_SIZE-1] = HLIST_HEAD_INIT };
22112 +
22113 +static spinlock_t vx_info_hash_lock = SPIN_LOCK_UNLOCKED;
22114 +
22115 +
22116 +static inline unsigned int __hashval(xid_t xid)
22117 +{
22118 +       return (xid % VX_HASH_SIZE);
22119 +}
22120 +
22121 +
22122 +
22123 +/*     __hash_vx_info()
22124 +
22125 +       * add the vxi to the global hash table
22126 +       * requires the hash_lock to be held                     */
22127 +
22128 +static inline void __hash_vx_info(struct vx_info *vxi)
22129 +{
22130 +       struct hlist_head *head;
22131 +
22132 +       vxd_assert_lock(&vx_info_hash_lock);
22133 +       vxdprintk(VXD_CBIT(xid, 4),
22134 +               "__hash_vx_info: %p[#%d]", vxi, vxi->vx_id);
22135 +       vxh_hash_vx_info(vxi);
22136 +
22137 +       /* context must not be hashed */
22138 +       BUG_ON(vx_info_state(vxi, VXS_HASHED));
22139 +
22140 +       vxi->vx_state |= VXS_HASHED;
22141 +       head = &vx_info_hash[__hashval(vxi->vx_id)];
22142 +       hlist_add_head(&vxi->vx_hlist, head);
22143 +       atomic_inc(&vx_global_cactive);
22144 +}
22145 +
22146 +/*     __unhash_vx_info()
22147 +
22148 +       * remove the vxi from the global hash table
22149 +       * requires the hash_lock to be held                     */
22150 +
22151 +static inline void __unhash_vx_info(struct vx_info *vxi)
22152 +{
22153 +       unsigned long flags;
22154 +
22155 +       vxd_assert_lock(&vx_info_hash_lock);
22156 +       vxdprintk(VXD_CBIT(xid, 4),
22157 +               "__unhash_vx_info: %p[#%d]", vxi, vxi->vx_id);
22158 +       vxh_unhash_vx_info(vxi);
22159 +
22160 +       /* context must be hashed */
22161 +       BUG_ON(!vx_info_state(vxi, VXS_HASHED));
22162 +
22163 +       vxi->vx_state &= ~VXS_HASHED;
22164 +       hlist_del_init(&vxi->vx_hlist);
22165 +       spin_lock_irqsave(&vx_info_inactive_lock, flags);
22166 +       hlist_add_head(&vxi->vx_hlist, &vx_info_inactive);
22167 +       spin_unlock_irqrestore(&vx_info_inactive_lock, flags);
22168 +       atomic_dec(&vx_global_cactive);
22169 +}
22170 +
22171 +
22172 +/*     __lookup_vx_info()
22173 +
22174 +       * requires the hash_lock to be held
22175 +       * doesn't increment the vx_refcnt                       */
22176 +
22177 +static inline struct vx_info *__lookup_vx_info(xid_t xid)
22178 +{
22179 +       struct hlist_head *head = &vx_info_hash[__hashval(xid)];
22180 +       struct hlist_node *pos;
22181 +       struct vx_info *vxi;
22182 +
22183 +       vxd_assert_lock(&vx_info_hash_lock);
22184 +       hlist_for_each(pos, head) {
22185 +               vxi = hlist_entry(pos, struct vx_info, vx_hlist);
22186 +
22187 +               if (vxi->vx_id == xid)
22188 +                       goto found;
22189 +       }
22190 +       vxi = NULL;
22191 +found:
22192 +       vxdprintk(VXD_CBIT(xid, 0),
22193 +               "__lookup_vx_info(#%u): %p[#%u]",
22194 +               xid, vxi, vxi?vxi->vx_id:0);
22195 +       vxh_lookup_vx_info(vxi, xid);
22196 +       return vxi;
22197 +}
22198 +
22199 +
22200 +/*     __create_vx_info()
22201 +
22202 +       * create the requested context
22203 +       * get() and hash it                                     */
22204 +
22205 +static struct vx_info * __create_vx_info(int id)
22206 +{
22207 +       struct vx_info *new, *vxi = NULL;
22208 +
22209 +       vxdprintk(VXD_CBIT(xid, 1), "create_vx_info(%d)*", id);
22210 +
22211 +       if (!(new = __alloc_vx_info(id)))
22212 +               return ERR_PTR(-ENOMEM);
22213 +
22214 +       /* required to make dynamic xids unique */
22215 +       spin_lock(&vx_info_hash_lock);
22216 +
22217 +       /* static context requested */
22218 +       if ((vxi = __lookup_vx_info(id))) {
22219 +               vxdprintk(VXD_CBIT(xid, 0),
22220 +                       "create_vx_info(%d) = %p (already there)", id, vxi);
22221 +               if (vx_info_flags(vxi, VXF_STATE_SETUP, 0))
22222 +                       vxi = ERR_PTR(-EBUSY);
22223 +               else
22224 +                       vxi = ERR_PTR(-EEXIST);
22225 +               goto out_unlock;
22226 +       }
22227 +       /* new context */
22228 +       vxdprintk(VXD_CBIT(xid, 0),
22229 +               "create_vx_info(%d) = %p (new)", id, new);
22230 +       __hash_vx_info(get_vx_info(new));
22231 +       vxi = new, new = NULL;
22232 +
22233 +out_unlock:
22234 +       spin_unlock(&vx_info_hash_lock);
22235 +       vxh_create_vx_info(IS_ERR(vxi)?NULL:vxi, id);
22236 +       if (new)
22237 +               __dealloc_vx_info(new);
22238 +       return vxi;
22239 +}
22240 +
22241 +
22242 +/*     exported stuff                                          */
22243 +
22244 +
22245 +void unhash_vx_info(struct vx_info *vxi)
22246 +{
22247 +       __shutdown_vx_info(vxi);
22248 +       spin_lock(&vx_info_hash_lock);
22249 +       __unhash_vx_info(vxi);
22250 +       spin_unlock(&vx_info_hash_lock);
22251 +       __wakeup_vx_info(vxi);
22252 +}
22253 +
22254 +
22255 +/*     lookup_vx_info()
22256 +
22257 +       * search for a vx_info and get() it
22258 +       * negative id means current                             */
22259 +
22260 +struct vx_info *lookup_vx_info(int id)
22261 +{
22262 +       struct vx_info *vxi = NULL;
22263 +
22264 +       if (id < 0) {
22265 +               vxi = get_vx_info(current->vx_info);
22266 +       } else if (id > 1) {
22267 +               spin_lock(&vx_info_hash_lock);
22268 +               vxi = get_vx_info(__lookup_vx_info(id));
22269 +               spin_unlock(&vx_info_hash_lock);
22270 +       }
22271 +       return vxi;
22272 +}
22273 +
22274 +/*     xid_is_hashed()
22275 +
22276 +       * verify that xid is still hashed                       */
22277 +
22278 +int xid_is_hashed(xid_t xid)
22279 +{
22280 +       int hashed;
22281 +
22282 +       spin_lock(&vx_info_hash_lock);
22283 +       hashed = (__lookup_vx_info(xid) != NULL);
22284 +       spin_unlock(&vx_info_hash_lock);
22285 +       return hashed;
22286 +}
22287 +
22288 +#ifdef CONFIG_PROC_FS
22289 +
22290 +/*     get_xid_list()
22291 +
22292 +       * get a subset of hashed xids for proc
22293 +       * assumes size is at least one                          */
22294 +
22295 +int get_xid_list(int index, unsigned int *xids, int size)
22296 +{
22297 +       int hindex, nr_xids = 0;
22298 +
22299 +       /* only show current and children */
22300 +       if (!vx_check(0, VS_ADMIN|VS_WATCH)) {
22301 +               if (index > 0)
22302 +                       return 0;
22303 +               xids[nr_xids] = vx_current_xid();
22304 +               return 1;
22305 +       }
22306 +
22307 +       for (hindex = 0; hindex < VX_HASH_SIZE; hindex++) {
22308 +               struct hlist_head *head = &vx_info_hash[hindex];
22309 +               struct hlist_node *pos;
22310 +
22311 +               spin_lock(&vx_info_hash_lock);
22312 +               hlist_for_each(pos, head) {
22313 +                       struct vx_info *vxi;
22314 +
22315 +                       if (--index > 0)
22316 +                               continue;
22317 +
22318 +                       vxi = hlist_entry(pos, struct vx_info, vx_hlist);
22319 +                       xids[nr_xids] = vxi->vx_id;
22320 +                       if (++nr_xids >= size) {
22321 +                               spin_unlock(&vx_info_hash_lock);
22322 +                               goto out;
22323 +                       }
22324 +               }
22325 +               /* keep the lock time short */
22326 +               spin_unlock(&vx_info_hash_lock);
22327 +       }
22328 +out:
22329 +       return nr_xids;
22330 +}
22331 +#endif
22332 +
22333 +#ifdef CONFIG_VSERVER_DEBUG
22334 +
22335 +void   dump_vx_info_inactive(int level)
22336 +{
22337 +       struct hlist_node *entry, *next;
22338 +
22339 +       hlist_for_each_safe(entry, next, &vx_info_inactive) {
22340 +               struct vx_info *vxi =
22341 +                       list_entry(entry, struct vx_info, vx_hlist);
22342 +
22343 +               dump_vx_info(vxi, level);
22344 +       }
22345 +}
22346 +
22347 +#endif
22348 +
22349 +int vx_migrate_user(struct task_struct *p, struct vx_info *vxi)
22350 +{
22351 +       struct user_struct *new_user, *old_user;
22352 +
22353 +       if (!p || !vxi)
22354 +               BUG();
22355 +
22356 +       if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
22357 +               return -EACCES;
22358 +
22359 +       new_user = alloc_uid(vxi->vx_id, p->uid);
22360 +       if (!new_user)
22361 +               return -ENOMEM;
22362 +
22363 +       old_user = p->user;
22364 +       if (new_user != old_user) {
22365 +               atomic_inc(&new_user->processes);
22366 +               atomic_dec(&old_user->processes);
22367 +               p->user = new_user;
22368 +       }
22369 +       free_uid(old_user);
22370 +       return 0;
22371 +}
22372 +
22373 +void vx_mask_cap_bset(struct vx_info *vxi, struct task_struct *p)
22374 +{
22375 +       p->cap_effective &= vxi->vx_cap_bset;
22376 +       p->cap_inheritable &= vxi->vx_cap_bset;
22377 +       p->cap_permitted &= vxi->vx_cap_bset;
22378 +}
22379 +
22380 +
22381 +#include <linux/file.h>
22382 +
22383 +static int vx_openfd_task(struct task_struct *tsk)
22384 +{
22385 +       struct files_struct *files = tsk->files;
22386 +       struct fdtable *fdt;
22387 +       const unsigned long *bptr;
22388 +       int count, total;
22389 +
22390 +       /* no rcu_read_lock() because of spin_lock() */
22391 +       spin_lock(&files->file_lock);
22392 +       fdt = files_fdtable(files);
22393 +       bptr = fdt->open_fds->fds_bits;
22394 +       count = fdt->max_fds / (sizeof(unsigned long) * 8);
22395 +       for (total = 0; count > 0; count--) {
22396 +               if (*bptr)
22397 +                       total += hweight_long(*bptr);
22398 +               bptr++;
22399 +       }
22400 +       spin_unlock(&files->file_lock);
22401 +       return total;
22402 +}
22403 +
22404 +
22405 +/*     for *space compatibility */
22406 +
22407 +asmlinkage long sys_unshare(unsigned long);
22408 +
22409 +/*
22410 + *     migrate task to new context
22411 + *     gets vxi, puts old_vxi on change
22412 + *     optionally unshares namespaces (hack)
22413 + */
22414 +
22415 +int vx_migrate_task(struct task_struct *p, struct vx_info *vxi, int unshare)
22416 +{
22417 +       struct vx_info *old_vxi;
22418 +       int ret = 0;
22419 +
22420 +       if (!p || !vxi)
22421 +               BUG();
22422 +
22423 +       vxdprintk(VXD_CBIT(xid, 5),
22424 +               "vx_migrate_task(%p,%p[#%d.%d])", p, vxi,
22425 +               vxi->vx_id, atomic_read(&vxi->vx_usecnt));
22426 +
22427 +       if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0) &&
22428 +               !vx_info_flags(vxi, VXF_STATE_SETUP, 0))
22429 +               return -EACCES;
22430 +
22431 +       old_vxi = task_get_vx_info(p);
22432 +       if (old_vxi == vxi)
22433 +               goto out;
22434 +
22435 +       if (!(ret = vx_migrate_user(p, vxi))) {
22436 +               int openfd;
22437 +
22438 +               task_lock(p);
22439 +               openfd = vx_openfd_task(p);
22440 +
22441 +               if (old_vxi) {
22442 +                       atomic_dec(&old_vxi->cvirt.nr_threads);
22443 +                       atomic_dec(&old_vxi->cvirt.nr_running);
22444 +                       __rlim_dec(&old_vxi->limit, RLIMIT_NPROC);
22445 +                       /* FIXME: what about the struct files here? */
22446 +                       __rlim_sub(&old_vxi->limit, VLIMIT_OPENFD, openfd);
22447 +                       /* account for the executable */
22448 +                       __rlim_dec(&old_vxi->limit, VLIMIT_DENTRY);
22449 +               }
22450 +               atomic_inc(&vxi->cvirt.nr_threads);
22451 +               atomic_inc(&vxi->cvirt.nr_running);
22452 +               __rlim_inc(&vxi->limit, RLIMIT_NPROC);
22453 +               /* FIXME: what about the struct files here? */
22454 +               __rlim_add(&vxi->limit, VLIMIT_OPENFD, openfd);
22455 +               /* account for the executable */
22456 +               __rlim_inc(&vxi->limit, VLIMIT_DENTRY);
22457 +
22458 +               if (old_vxi) {
22459 +                       release_vx_info(old_vxi, p);
22460 +                       clr_vx_info(&p->vx_info);
22461 +               }
22462 +               claim_vx_info(vxi, p);
22463 +               set_vx_info(&p->vx_info, vxi);
22464 +               p->xid = vxi->vx_id;
22465 +
22466 +               vxdprintk(VXD_CBIT(xid, 5),
22467 +                       "moved task %p into vxi:%p[#%d]",
22468 +                       p, vxi, vxi->vx_id);
22469 +
22470 +               vx_mask_cap_bset(vxi, p);
22471 +               task_unlock(p);
22472 +
22473 +               /* hack for *spaces to provide compatibility */
22474 +               if (unshare) {
22475 +                       ret = sys_unshare(CLONE_NEWUTS|CLONE_NEWIPC);
22476 +                       vx_set_space(vxi, CLONE_NEWUTS|CLONE_NEWIPC);
22477 +               }
22478 +       }
22479 +out:
22480 +       put_vx_info(old_vxi);
22481 +       return ret;
22482 +}
22483 +
22484 +int vx_set_reaper(struct vx_info *vxi, struct task_struct *p)
22485 +{
22486 +       struct task_struct *old_reaper;
22487 +
22488 +       if (!vxi)
22489 +               return -EINVAL;
22490 +
22491 +       vxdprintk(VXD_CBIT(xid, 6),
22492 +               "vx_set_reaper(%p[#%d],%p[#%d,%d])",
22493 +               vxi, vxi->vx_id, p, p->xid, p->pid);
22494 +
22495 +       old_reaper = vxi->vx_reaper;
22496 +       if (old_reaper == p)
22497 +               return 0;
22498 +
22499 +       /* set new child reaper */
22500 +       get_task_struct(p);
22501 +       vxi->vx_reaper = p;
22502 +       put_task_struct(old_reaper);
22503 +       return 0;
22504 +}
22505 +
22506 +int vx_set_init(struct vx_info *vxi, struct task_struct *p)
22507 +{
22508 +       if (!vxi)
22509 +               return -EINVAL;
22510 +
22511 +       vxdprintk(VXD_CBIT(xid, 6),
22512 +               "vx_set_init(%p[#%d],%p[#%d,%d,%d])",
22513 +               vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
22514 +
22515 +       vxi->vx_flags &= ~VXF_STATE_INIT;
22516 +       vxi->vx_initpid = p->tgid;
22517 +       return 0;
22518 +}
22519 +
22520 +void vx_exit_init(struct vx_info *vxi, struct task_struct *p, int code)
22521 +{
22522 +       vxdprintk(VXD_CBIT(xid, 6),
22523 +               "vx_exit_init(%p[#%d],%p[#%d,%d,%d])",
22524 +               vxi, vxi->vx_id, p, p->xid, p->pid, p->tgid);
22525 +
22526 +       vxi->exit_code = code;
22527 +       vxi->vx_initpid = 0;
22528 +}
22529 +
22530 +
22531 +void vx_set_persistent(struct vx_info *vxi)
22532 +{
22533 +       vxdprintk(VXD_CBIT(xid, 6),
22534 +               "vx_set_persistent(%p[#%d])", vxi, vxi->vx_id);
22535 +
22536 +       get_vx_info(vxi);
22537 +       claim_vx_info(vxi, current);
22538 +}
22539 +
22540 +void vx_clear_persistent(struct vx_info *vxi)
22541 +{
22542 +       vxdprintk(VXD_CBIT(xid, 6),
22543 +               "vx_clear_persistent(%p[#%d])", vxi, vxi->vx_id);
22544 +
22545 +       release_vx_info(vxi, current);
22546 +       put_vx_info(vxi);
22547 +}
22548 +
22549 +void vx_update_persistent(struct vx_info *vxi)
22550 +{
22551 +       if (vx_info_flags(vxi, VXF_PERSISTENT, 0))
22552 +               vx_set_persistent(vxi);
22553 +       else
22554 +               vx_clear_persistent(vxi);
22555 +}
22556 +
22557 +
22558 +/*     task must be current or locked          */
22559 +
22560 +void   exit_vx_info(struct task_struct *p, int code)
22561 +{
22562 +       struct vx_info *vxi = p->vx_info;
22563 +
22564 +       if (vxi) {
22565 +               atomic_dec(&vxi->cvirt.nr_threads);
22566 +               vx_nproc_dec(p);
22567 +
22568 +               vxi->exit_code = code;
22569 +               release_vx_info(vxi, p);
22570 +       }
22571 +}
22572 +
22573 +void   exit_vx_info_early(struct task_struct *p, int code)
22574 +{
22575 +       struct vx_info *vxi = p->vx_info;
22576 +
22577 +       if (vxi) {
22578 +               if (vxi->vx_initpid == p->tgid)
22579 +                       vx_exit_init(vxi, p, code);
22580 +               if (vxi->vx_reaper == p)
22581 +                       vx_set_reaper(vxi, child_reaper);
22582 +       }
22583 +}
22584 +
22585 +
22586 +/* vserver syscall commands below here */
22587 +
22588 +/* taks xid and vx_info functions */
22589 +
22590 +#include <asm/uaccess.h>
22591 +
22592 +
22593 +int vc_task_xid(uint32_t id, void __user *data)
22594 +{
22595 +       xid_t xid;
22596 +
22597 +       if (id) {
22598 +               struct task_struct *tsk;
22599 +
22600 +               if (!vx_check(0, VS_ADMIN|VS_WATCH))
22601 +                       return -EPERM;
22602 +
22603 +               read_lock(&tasklist_lock);
22604 +               tsk = find_task_by_real_pid(id);
22605 +               xid = (tsk) ? tsk->xid : -ESRCH;
22606 +               read_unlock(&tasklist_lock);
22607 +       }
22608 +       else
22609 +               xid = vx_current_xid();
22610 +       return xid;
22611 +}
22612 +
22613 +
22614 +int vc_vx_info(struct vx_info *vxi, void __user *data)
22615 +{
22616 +       struct vcmd_vx_info_v0 vc_data;
22617 +
22618 +       vc_data.xid = vxi->vx_id;
22619 +       vc_data.initpid = vxi->vx_initpid;
22620 +
22621 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22622 +               return -EFAULT;
22623 +       return 0;
22624 +}
22625 +
22626 +
22627 +int vc_ctx_stat(struct vx_info *vxi, void __user *data)
22628 +{
22629 +       struct vcmd_ctx_stat_v0 vc_data;
22630 +
22631 +       vc_data.usecnt = atomic_read(&vxi->vx_usecnt);
22632 +       vc_data.tasks = atomic_read(&vxi->vx_tasks);
22633 +
22634 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22635 +               return -EFAULT;
22636 +       return 0;
22637 +}
22638 +
22639 +
22640 +/* context functions */
22641 +
22642 +int vc_ctx_create(uint32_t xid, void __user *data)
22643 +{
22644 +       struct vcmd_ctx_create vc_data = { .flagword = VXF_INIT_SET };
22645 +       struct vx_info *new_vxi;
22646 +       int ret;
22647 +
22648 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
22649 +               return -EFAULT;
22650 +
22651 +       if ((xid > MAX_S_CONTEXT) || (xid < 2))
22652 +               return -EINVAL;
22653 +
22654 +       new_vxi = __create_vx_info(xid);
22655 +       if (IS_ERR(new_vxi))
22656 +               return PTR_ERR(new_vxi);
22657 +
22658 +       /* initial flags */
22659 +       new_vxi->vx_flags = vc_data.flagword;
22660 +
22661 +       /* get a reference for persistent contexts */
22662 +       if ((vc_data.flagword & VXF_PERSISTENT))
22663 +               vx_set_persistent(new_vxi);
22664 +
22665 +       ret = -ENOEXEC;
22666 +       if (vs_state_change(new_vxi, VSC_STARTUP))
22667 +               goto out_unhash;
22668 +       ret = vx_migrate_task(current, new_vxi, (!data));
22669 +       if (!ret) {
22670 +               /* return context id on success */
22671 +               ret = new_vxi->vx_id;
22672 +               goto out;
22673 +       }
22674 +out_unhash:
22675 +       /* prepare for context disposal */
22676 +       new_vxi->vx_state |= VXS_SHUTDOWN;
22677 +       if ((vc_data.flagword & VXF_PERSISTENT))
22678 +               vx_clear_persistent(new_vxi);
22679 +       __unhash_vx_info(new_vxi);
22680 +out:
22681 +       put_vx_info(new_vxi);
22682 +       return ret;
22683 +}
22684 +
22685 +
22686 +int vc_ctx_migrate(struct vx_info *vxi, void __user *data)
22687 +{
22688 +       struct vcmd_ctx_migrate vc_data = { .flagword = 0 };
22689 +       int ret;
22690 +
22691 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
22692 +               return -EFAULT;
22693 +
22694 +       ret = vx_migrate_task(current, vxi, 0);
22695 +       if (ret)
22696 +               return ret;
22697 +       if (vc_data.flagword & VXM_SET_INIT)
22698 +               ret = vx_set_init(vxi, current);
22699 +       if (ret)
22700 +               return ret;
22701 +       if (vc_data.flagword & VXM_SET_REAPER)
22702 +               ret = vx_set_reaper(vxi, current);
22703 +       return ret;
22704 +}
22705 +
22706 +
22707 +int vc_get_cflags(struct vx_info *vxi, void __user *data)
22708 +{
22709 +       struct vcmd_ctx_flags_v0 vc_data;
22710 +
22711 +       vc_data.flagword = vxi->vx_flags;
22712 +
22713 +       /* special STATE flag handling */
22714 +       vc_data.mask = vs_mask_flags(~0UL, vxi->vx_flags, VXF_ONE_TIME);
22715 +
22716 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22717 +               return -EFAULT;
22718 +       return 0;
22719 +}
22720 +
22721 +int vc_set_cflags(struct vx_info *vxi, void __user *data)
22722 +{
22723 +       struct vcmd_ctx_flags_v0 vc_data;
22724 +       uint64_t mask, trigger;
22725 +
22726 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22727 +               return -EFAULT;
22728 +
22729 +       /* special STATE flag handling */
22730 +       mask = vs_mask_mask(vc_data.mask, vxi->vx_flags, VXF_ONE_TIME);
22731 +       trigger = (mask & vxi->vx_flags) ^ (mask & vc_data.flagword);
22732 +
22733 +       if (vxi == current->vx_info) {
22734 +               if (trigger & VXF_STATE_SETUP)
22735 +                       vx_mask_cap_bset(vxi, current);
22736 +               if (trigger & VXF_STATE_INIT) {
22737 +                       int ret;
22738 +
22739 +                       ret = vx_set_init(vxi, current);
22740 +                       if (ret)
22741 +                               return ret;
22742 +                       ret = vx_set_reaper(vxi, current);
22743 +                       if (ret)
22744 +                               return ret;
22745 +               }
22746 +       }
22747 +
22748 +       vxi->vx_flags = vs_mask_flags(vxi->vx_flags,
22749 +               vc_data.flagword, mask);
22750 +       if (trigger & VXF_PERSISTENT)
22751 +               vx_update_persistent(vxi);
22752 +
22753 +       return 0;
22754 +}
22755 +
22756 +static int do_get_caps(struct vx_info *vxi, uint64_t *bcaps, uint64_t *ccaps)
22757 +{
22758 +       if (bcaps)
22759 +               *bcaps = vxi->vx_bcaps;
22760 +       if (ccaps)
22761 +               *ccaps = vxi->vx_ccaps;
22762 +
22763 +       return 0;
22764 +}
22765 +
22766 +int vc_get_ccaps_v0(struct vx_info *vxi, void __user *data)
22767 +{
22768 +       struct vcmd_ctx_caps_v0 vc_data;
22769 +       int ret;
22770 +
22771 +       ret = do_get_caps(vxi, &vc_data.bcaps, &vc_data.ccaps);
22772 +       if (ret)
22773 +               return ret;
22774 +       vc_data.cmask = ~0UL;
22775 +
22776 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22777 +               return -EFAULT;
22778 +       return 0;
22779 +}
22780 +
22781 +int vc_get_ccaps(struct vx_info *vxi, void __user *data)
22782 +{
22783 +       struct vcmd_ctx_caps_v1 vc_data;
22784 +       int ret;
22785 +
22786 +       ret = do_get_caps(vxi, NULL, &vc_data.ccaps);
22787 +       if (ret)
22788 +               return ret;
22789 +       vc_data.cmask = ~0UL;
22790 +
22791 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22792 +               return -EFAULT;
22793 +       return 0;
22794 +}
22795 +
22796 +static int do_set_caps(struct vx_info *vxi,
22797 +       uint64_t bcaps, uint64_t bmask, uint64_t ccaps, uint64_t cmask)
22798 +{
22799 +       vxi->vx_bcaps = vs_mask_flags(vxi->vx_bcaps, bcaps, bmask);
22800 +       vxi->vx_ccaps = vs_mask_flags(vxi->vx_ccaps, ccaps, cmask);
22801 +
22802 +       return 0;
22803 +}
22804 +
22805 +int vc_set_ccaps_v0(struct vx_info *vxi, void __user *data)
22806 +{
22807 +       struct vcmd_ctx_caps_v0 vc_data;
22808 +
22809 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22810 +               return -EFAULT;
22811 +
22812 +       /* simulate old &= behaviour for bcaps */
22813 +       return do_set_caps(vxi, 0, ~vc_data.bcaps,
22814 +               vc_data.ccaps, vc_data.cmask);
22815 +}
22816 +
22817 +int vc_set_ccaps(struct vx_info *vxi, void __user *data)
22818 +{
22819 +       struct vcmd_ctx_caps_v1 vc_data;
22820 +
22821 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22822 +               return -EFAULT;
22823 +
22824 +       return do_set_caps(vxi, 0, 0, vc_data.ccaps, vc_data.cmask);
22825 +}
22826 +
22827 +int vc_get_bcaps(struct vx_info *vxi, void __user *data)
22828 +{
22829 +       struct vcmd_bcaps vc_data;
22830 +       int ret;
22831 +
22832 +       ret = do_get_caps(vxi, &vc_data.bcaps, NULL);
22833 +       if (ret)
22834 +               return ret;
22835 +       vc_data.bmask = ~0UL;
22836 +
22837 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
22838 +               return -EFAULT;
22839 +       return 0;
22840 +}
22841 +
22842 +int vc_set_bcaps(struct vx_info *vxi, void __user *data)
22843 +{
22844 +       struct vcmd_bcaps vc_data;
22845 +
22846 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
22847 +               return -EFAULT;
22848 +
22849 +       return do_set_caps(vxi, vc_data.bcaps, vc_data.bmask, 0, 0);
22850 +}
22851 +
22852 +#include <linux/module.h>
22853 +
22854 +EXPORT_SYMBOL_GPL(free_vx_info);
22855 +
22856 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cvirt.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt.c
22857 --- linux-2.6.19.1/kernel/vserver/cvirt.c       1970-01-01 01:00:00 +0100
22858 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt.c     2006-11-14 02:30:02 +0100
22859 @@ -0,0 +1,305 @@
22860 +/*
22861 + *  linux/kernel/vserver/cvirt.c
22862 + *
22863 + *  Virtual Server: Context Virtualization
22864 + *
22865 + *  Copyright (C) 2004-2006  Herbert Pötzl
22866 + *
22867 + *  V0.01  broken out from limit.c
22868 + *  V0.02  added utsname stuff
22869 + *  V0.03  changed vcmds to vxi arg
22870 + *
22871 + */
22872 +
22873 +#include <linux/sched.h>
22874 +#include <linux/sysctl.h>
22875 +#include <linux/types.h>
22876 +#include <linux/vs_context.h>
22877 +#include <linux/vs_cvirt.h>
22878 +#include <linux/vserver/switch.h>
22879 +#include <linux/vserver/cvirt_cmd.h>
22880 +//#include <linux/vserver/cacct_cmd.h>
22881 +
22882 +#include <asm/errno.h>
22883 +#include <asm/uaccess.h>
22884 +
22885 +
22886 +void vx_vsi_uptime(struct timespec *uptime, struct timespec *idle)
22887 +{
22888 +       struct vx_info *vxi = current->vx_info;
22889 +
22890 +       set_normalized_timespec(uptime,
22891 +               uptime->tv_sec - vxi->cvirt.bias_uptime.tv_sec,
22892 +               uptime->tv_nsec - vxi->cvirt.bias_uptime.tv_nsec);
22893 +       if (!idle)
22894 +               return;
22895 +       set_normalized_timespec(idle,
22896 +               idle->tv_sec - vxi->cvirt.bias_idle.tv_sec,
22897 +               idle->tv_nsec - vxi->cvirt.bias_idle.tv_nsec);
22898 +       return;
22899 +}
22900 +
22901 +uint64_t vx_idle_jiffies(void)
22902 +{
22903 +       return init_task.utime + init_task.stime;
22904 +}
22905 +
22906 +
22907 +
22908 +static inline uint32_t __update_loadavg(uint32_t load,
22909 +       int wsize, int delta, int n)
22910 +{
22911 +       unsigned long long calc, prev;
22912 +
22913 +       /* just set it to n */
22914 +       if (unlikely(delta >= wsize))
22915 +               return (n << FSHIFT);
22916 +
22917 +       calc = delta * n;
22918 +       calc <<= FSHIFT;
22919 +       prev = (wsize - delta);
22920 +       prev *= load;
22921 +       calc += prev;
22922 +       do_div(calc, wsize);
22923 +       return calc;
22924 +}
22925 +
22926 +
22927 +void vx_update_load(struct vx_info *vxi)
22928 +{
22929 +       uint32_t now, last, delta;
22930 +       unsigned int nr_running, nr_uninterruptible;
22931 +       unsigned int total;
22932 +       unsigned long flags;
22933 +
22934 +       spin_lock_irqsave(&vxi->cvirt.load_lock, flags);
22935 +
22936 +       now = jiffies;
22937 +       last = vxi->cvirt.load_last;
22938 +       delta = now - last;
22939 +
22940 +       if (delta < 5*HZ)
22941 +               goto out;
22942 +
22943 +       nr_running = atomic_read(&vxi->cvirt.nr_running);
22944 +       nr_uninterruptible = atomic_read(&vxi->cvirt.nr_uninterruptible);
22945 +       total = nr_running + nr_uninterruptible;
22946 +
22947 +       vxi->cvirt.load[0] = __update_loadavg(vxi->cvirt.load[0],
22948 +               60*HZ, delta, total);
22949 +       vxi->cvirt.load[1] = __update_loadavg(vxi->cvirt.load[1],
22950 +               5*60*HZ, delta, total);
22951 +       vxi->cvirt.load[2] = __update_loadavg(vxi->cvirt.load[2],
22952 +               15*60*HZ, delta, total);
22953 +
22954 +       vxi->cvirt.load_last = now;
22955 +out:
22956 +       atomic_inc(&vxi->cvirt.load_updates);
22957 +       spin_unlock_irqrestore(&vxi->cvirt.load_lock, flags);
22958 +}
22959 +
22960 +
22961 +/*
22962 + * Commands to do_syslog:
22963 + *
22964 + *      0 -- Close the log.  Currently a NOP.
22965 + *      1 -- Open the log. Currently a NOP.
22966 + *      2 -- Read from the log.
22967 + *      3 -- Read all messages remaining in the ring buffer.
22968 + *      4 -- Read and clear all messages remaining in the ring buffer
22969 + *      5 -- Clear ring buffer.
22970 + *      6 -- Disable printk's to console
22971 + *      7 -- Enable printk's to console
22972 + *      8 -- Set level of messages printed to console
22973 + *      9 -- Return number of unread characters in the log buffer
22974 + *     10 -- Return size of the log buffer
22975 + */
22976 +int vx_do_syslog(int type, char __user *buf, int len)
22977 +{
22978 +       int error = 0;
22979 +       int do_clear = 0;
22980 +       struct vx_info *vxi = current->vx_info;
22981 +       struct _vx_syslog *log;
22982 +
22983 +       if (!vxi)
22984 +               return -EINVAL;
22985 +       log = &vxi->cvirt.syslog;
22986 +
22987 +       switch (type) {
22988 +       case 0:         /* Close log */
22989 +       case 1:         /* Open log */
22990 +               break;
22991 +       case 2:         /* Read from log */
22992 +               error = wait_event_interruptible(log->log_wait,
22993 +                       (log->log_start - log->log_end));
22994 +               if (error)
22995 +                       break;
22996 +               spin_lock_irq(&log->logbuf_lock);
22997 +               spin_unlock_irq(&log->logbuf_lock);
22998 +               break;
22999 +       case 4:         /* Read/clear last kernel messages */
23000 +               do_clear = 1;
23001 +               /* fall through */
23002 +       case 3:         /* Read last kernel messages */
23003 +               return 0;
23004 +
23005 +       case 5:         /* Clear ring buffer */
23006 +               return 0;
23007 +
23008 +       case 6:         /* Disable logging to console */
23009 +       case 7:         /* Enable logging to console */
23010 +       case 8:         /* Set level of messages printed to console */
23011 +               break;
23012 +
23013 +       case 9:         /* Number of chars in the log buffer */
23014 +               return 0;
23015 +       case 10:        /* Size of the log buffer */
23016 +               return 0;
23017 +       default:
23018 +               error = -EINVAL;
23019 +               break;
23020 +       }
23021 +       return error;
23022 +}
23023 +
23024 +
23025 +/* virtual host info names */
23026 +
23027 +static char * vx_vhi_name(struct vx_info *vxi, int id)
23028 +{
23029 +       struct nsproxy *nsproxy;
23030 +       struct uts_namespace *uts;
23031 +
23032 +
23033 +       if (id == VHIN_CONTEXT)
23034 +               return vxi->vx_name;
23035 +
23036 +       nsproxy = vxi->vx_nsproxy;
23037 +       if (!nsproxy)
23038 +               return NULL;
23039 +
23040 +       uts = nsproxy->uts_ns;
23041 +       if (!uts)
23042 +               return NULL;
23043 +
23044 +       switch (id) {
23045 +       case VHIN_SYSNAME:
23046 +               return uts->name.sysname;
23047 +       case VHIN_NODENAME:
23048 +               return uts->name.nodename;
23049 +       case VHIN_RELEASE:
23050 +               return uts->name.release;
23051 +       case VHIN_VERSION:
23052 +               return uts->name.version;
23053 +       case VHIN_MACHINE:
23054 +               return uts->name.machine;
23055 +       case VHIN_DOMAINNAME:
23056 +               return uts->name.domainname;
23057 +       default:
23058 +               return NULL;
23059 +       }
23060 +       return NULL;
23061 +}
23062 +
23063 +int vc_set_vhi_name(struct vx_info *vxi, void __user *data)
23064 +{
23065 +       struct vcmd_vhi_name_v0 vc_data;
23066 +       char *name;
23067 +
23068 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23069 +               return -EFAULT;
23070 +
23071 +       name = vx_vhi_name(vxi, vc_data.field);
23072 +       if (!name)
23073 +               return -EINVAL;
23074 +
23075 +       memcpy(name, vc_data.name, 65);
23076 +       return 0;
23077 +}
23078 +
23079 +int vc_get_vhi_name(struct vx_info *vxi, void __user *data)
23080 +{
23081 +       struct vcmd_vhi_name_v0 vc_data;
23082 +       char *name;
23083 +
23084 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23085 +               return -EFAULT;
23086 +
23087 +       name = vx_vhi_name(vxi, vc_data.field);
23088 +       if (!name)
23089 +               return -EINVAL;
23090 +
23091 +       memcpy(vc_data.name, name, 65);
23092 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
23093 +               return -EFAULT;
23094 +       return 0;
23095 +}
23096 +
23097 +
23098 +int vc_virt_stat(struct vx_info *vxi, void __user *data)
23099 +{
23100 +       struct vcmd_virt_stat_v0 vc_data;
23101 +       struct _vx_cvirt *cvirt = &vxi->cvirt;
23102 +       struct timespec uptime;
23103 +
23104 +       do_posix_clock_monotonic_gettime(&uptime);
23105 +       set_normalized_timespec(&uptime,
23106 +               uptime.tv_sec - cvirt->bias_uptime.tv_sec,
23107 +               uptime.tv_nsec - cvirt->bias_uptime.tv_nsec);
23108 +
23109 +       vc_data.offset = timeval_to_ns(&cvirt->bias_tv);
23110 +       vc_data.uptime = timespec_to_ns(&uptime);
23111 +       vc_data.nr_threads = atomic_read(&cvirt->nr_threads);
23112 +       vc_data.nr_running = atomic_read(&cvirt->nr_running);
23113 +       vc_data.nr_uninterruptible = atomic_read(&cvirt->nr_uninterruptible);
23114 +       vc_data.nr_onhold = atomic_read(&cvirt->nr_onhold);
23115 +       vc_data.nr_forks = atomic_read(&cvirt->total_forks);
23116 +       vc_data.load[0] = cvirt->load[0];
23117 +       vc_data.load[1] = cvirt->load[1];
23118 +       vc_data.load[2] = cvirt->load[2];
23119 +
23120 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
23121 +               return -EFAULT;
23122 +       return 0;
23123 +}
23124 +
23125 +
23126 +#ifdef CONFIG_VSERVER_VTIME
23127 +
23128 +/* virtualized time base */
23129 +
23130 +void vx_gettimeofday(struct timeval *tv)
23131 +{
23132 +       do_gettimeofday(tv);
23133 +       if (!vx_flags(VXF_VIRT_TIME, 0))
23134 +               return;
23135 +
23136 +       tv->tv_sec += current->vx_info->cvirt.bias_tv.tv_sec;
23137 +       tv->tv_usec += current->vx_info->cvirt.bias_tv.tv_usec;
23138 +
23139 +       if (tv->tv_usec >= USEC_PER_SEC) {
23140 +               tv->tv_sec++;
23141 +               tv->tv_usec -= USEC_PER_SEC;
23142 +       } else if (tv->tv_usec < 0) {
23143 +               tv->tv_sec--;
23144 +               tv->tv_usec += USEC_PER_SEC;
23145 +       }
23146 +}
23147 +
23148 +int vx_settimeofday(struct timespec *ts)
23149 +{
23150 +       struct timeval tv;
23151 +
23152 +       if (!vx_flags(VXF_VIRT_TIME, 0))
23153 +               return do_settimeofday(ts);
23154 +
23155 +       do_gettimeofday(&tv);
23156 +       current->vx_info->cvirt.bias_tv.tv_sec =
23157 +               ts->tv_sec - tv.tv_sec;
23158 +       current->vx_info->cvirt.bias_tv.tv_usec =
23159 +               (ts->tv_nsec/NSEC_PER_USEC) - tv.tv_usec;
23160 +       return 0;
23161 +}
23162 +
23163 +#endif
23164 +
23165 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cvirt_init.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt_init.h
23166 --- linux-2.6.19.1/kernel/vserver/cvirt_init.h  1970-01-01 01:00:00 +0100
23167 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt_init.h        2006-11-14 02:11:41 +0100
23168 @@ -0,0 +1,71 @@
23169 +
23170 +
23171 +extern uint64_t vx_idle_jiffies(void);
23172 +
23173 +static inline void vx_info_init_cvirt(struct _vx_cvirt *cvirt)
23174 +{
23175 +       uint64_t idle_jiffies = vx_idle_jiffies();
23176 +       uint64_t nsuptime;
23177 +
23178 +       do_posix_clock_monotonic_gettime(&cvirt->bias_uptime);
23179 +       nsuptime = (unsigned long long)cvirt->bias_uptime.tv_sec
23180 +               * NSEC_PER_SEC + cvirt->bias_uptime.tv_nsec;
23181 +       cvirt->bias_clock = nsec_to_clock_t(nsuptime);
23182 +       cvirt->bias_tv.tv_sec = 0;
23183 +       cvirt->bias_tv.tv_usec = 0;
23184 +
23185 +       jiffies_to_timespec(idle_jiffies, &cvirt->bias_idle);
23186 +       atomic_set(&cvirt->nr_threads, 0);
23187 +       atomic_set(&cvirt->nr_running, 0);
23188 +       atomic_set(&cvirt->nr_uninterruptible, 0);
23189 +       atomic_set(&cvirt->nr_onhold, 0);
23190 +
23191 +       spin_lock_init(&cvirt->load_lock);
23192 +       cvirt->load_last = jiffies;
23193 +       atomic_set(&cvirt->load_updates, 0);
23194 +       cvirt->load[0] = 0;
23195 +       cvirt->load[1] = 0;
23196 +       cvirt->load[2] = 0;
23197 +       atomic_set(&cvirt->total_forks, 0);
23198 +
23199 +       spin_lock_init(&cvirt->syslog.logbuf_lock);
23200 +       init_waitqueue_head(&cvirt->syslog.log_wait);
23201 +       cvirt->syslog.log_start = 0;
23202 +       cvirt->syslog.log_end = 0;
23203 +       cvirt->syslog.con_start = 0;
23204 +       cvirt->syslog.logged_chars = 0;
23205 +}
23206 +
23207 +static inline
23208 +void vx_info_init_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
23209 +{
23210 +       // cvirt_pc->cpustat = { 0 };
23211 +}
23212 +
23213 +static inline void vx_info_exit_cvirt(struct _vx_cvirt *cvirt)
23214 +{
23215 +#ifdef CONFIG_VSERVER_DEBUG
23216 +       int value;
23217 +
23218 +       vxwprintk((value = atomic_read(&cvirt->nr_threads)),
23219 +               "!!! cvirt: %p[nr_threads] = %d on exit.",
23220 +               cvirt, value);
23221 +       vxwprintk((value = atomic_read(&cvirt->nr_running)),
23222 +               "!!! cvirt: %p[nr_running] = %d on exit.",
23223 +               cvirt, value);
23224 +       vxwprintk((value = atomic_read(&cvirt->nr_uninterruptible)),
23225 +               "!!! cvirt: %p[nr_uninterruptible] = %d on exit.",
23226 +               cvirt, value);
23227 +       vxwprintk((value = atomic_read(&cvirt->nr_onhold)),
23228 +               "!!! cvirt: %p[nr_onhold] = %d on exit.",
23229 +               cvirt, value);
23230 +#endif
23231 +       return;
23232 +}
23233 +
23234 +static inline
23235 +void vx_info_exit_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc, int cpu)
23236 +{
23237 +       return;
23238 +}
23239 +
23240 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/cvirt_proc.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt_proc.h
23241 --- linux-2.6.19.1/kernel/vserver/cvirt_proc.h  1970-01-01 01:00:00 +0100
23242 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/cvirt_proc.h        2006-11-14 03:08:43 +0100
23243 @@ -0,0 +1,138 @@
23244 +#ifndef _VX_CVIRT_PROC_H
23245 +#define _VX_CVIRT_PROC_H
23246 +
23247 +#include <linux/nsproxy.h>
23248 +#include <linux/namespace.h>
23249 +#include <linux/utsname.h>
23250 +#include <linux/ipc.h>
23251 +
23252 +
23253 +static inline
23254 +int vx_info_proc_nsproxy(struct nsproxy *nsproxy, char *buffer)
23255 +{
23256 +       struct namespace *ns;
23257 +       struct uts_namespace *uts;
23258 +       struct ipc_namespace *ipc;
23259 +       struct vfsmount *mnt;
23260 +       char *path, *root;
23261 +       int length = 0;
23262 +
23263 +       if (!nsproxy)
23264 +               goto out;
23265 +
23266 +       length += sprintf(buffer + length,
23267 +               "NSProxy:\t%p [%p,%p,%p]\n",
23268 +               nsproxy, nsproxy->namespace,
23269 +               nsproxy->uts_ns, nsproxy->ipc_ns);
23270 +
23271 +       ns = nsproxy->namespace;
23272 +       if (!ns)
23273 +               goto skip_ns;
23274 +
23275 +       path = kmalloc(PATH_MAX, GFP_KERNEL);
23276 +       if (!path)
23277 +               goto skip_ns;
23278 +
23279 +       mnt = ns->root;
23280 +       root = d_path(mnt->mnt_root, mnt->mnt_parent, path, PATH_MAX-2);
23281 +       length += sprintf(buffer + length,
23282 +               "Namespace:\t%p [#%u]\n"
23283 +               "RootPath:\t%s\n"
23284 +               ,ns , atomic_read(&ns->count)
23285 +               ,root);
23286 +       kfree(path);
23287 +skip_ns:
23288 +
23289 +       uts = nsproxy->uts_ns;
23290 +       if (!uts)
23291 +               goto skip_uts;
23292 +
23293 +       length += sprintf(buffer + length,
23294 +               "SysName:\t%.*s\n"
23295 +               "NodeName:\t%.*s\n"
23296 +               "Release:\t%.*s\n"
23297 +               "Version:\t%.*s\n"
23298 +               "Machine:\t%.*s\n"
23299 +               "DomainName:\t%.*s\n"
23300 +               ,__NEW_UTS_LEN, uts->name.sysname
23301 +               ,__NEW_UTS_LEN, uts->name.nodename
23302 +               ,__NEW_UTS_LEN, uts->name.release
23303 +               ,__NEW_UTS_LEN, uts->name.version
23304 +               ,__NEW_UTS_LEN, uts->name.machine
23305 +               ,__NEW_UTS_LEN, uts->name.domainname
23306 +               );
23307 +skip_uts:
23308 +
23309 +       ipc = nsproxy->ipc_ns;
23310 +       if (!ipc)
23311 +               goto skip_ipc;
23312 +
23313 +       length += sprintf(buffer + length,
23314 +               "SEMS:\t\t%d %d %d %d  %d\n"
23315 +               "MSG:\t\t%d %d %d\n"
23316 +               "SHM:\t\t%lu %lu  %d %d\n"
23317 +               ,ipc->sem_ctls[0], ipc->sem_ctls[1]
23318 +               ,ipc->sem_ctls[2], ipc->sem_ctls[3]
23319 +               ,ipc->used_sems
23320 +               ,ipc->msg_ctlmax, ipc->msg_ctlmnb, ipc->msg_ctlmni
23321 +               ,(unsigned long)ipc->shm_ctlmax
23322 +               ,(unsigned long)ipc->shm_ctlall
23323 +               ,ipc->shm_ctlmni, ipc->shm_tot
23324 +               );
23325 +skip_ipc:
23326 +
23327 +out:
23328 +       return length;
23329 +}
23330 +
23331 +
23332 +#include <linux/sched.h>
23333 +
23334 +#define LOAD_INT(x) ((x) >> FSHIFT)
23335 +#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
23336 +
23337 +static inline
23338 +int vx_info_proc_cvirt(struct _vx_cvirt *cvirt, char *buffer)
23339 +{
23340 +       int length = 0;
23341 +       int a, b, c;
23342 +
23343 +       length += sprintf(buffer + length,
23344 +               "BiasUptime:\t%lu.%02lu\n",
23345 +                       (unsigned long)cvirt->bias_uptime.tv_sec,
23346 +                       (cvirt->bias_uptime.tv_nsec / (NSEC_PER_SEC / 100)));
23347 +
23348 +       a = cvirt->load[0] + (FIXED_1/200);
23349 +       b = cvirt->load[1] + (FIXED_1/200);
23350 +       c = cvirt->load[2] + (FIXED_1/200);
23351 +       length += sprintf(buffer + length,
23352 +               "nr_threads:\t%d\n"
23353 +               "nr_running:\t%d\n"
23354 +               "nr_unintr:\t%d\n"
23355 +               "nr_onhold:\t%d\n"
23356 +               "load_updates:\t%d\n"
23357 +               "loadavg:\t%d.%02d %d.%02d %d.%02d\n"
23358 +               "total_forks:\t%d\n"
23359 +               ,atomic_read(&cvirt->nr_threads)
23360 +               ,atomic_read(&cvirt->nr_running)
23361 +               ,atomic_read(&cvirt->nr_uninterruptible)
23362 +               ,atomic_read(&cvirt->nr_onhold)
23363 +               ,atomic_read(&cvirt->load_updates)
23364 +               ,LOAD_INT(a), LOAD_FRAC(a)
23365 +               ,LOAD_INT(b), LOAD_FRAC(b)
23366 +               ,LOAD_INT(c), LOAD_FRAC(c)
23367 +               ,atomic_read(&cvirt->total_forks)
23368 +               );
23369 +
23370 +       return length;
23371 +}
23372 +
23373 +static inline
23374 +int vx_info_proc_cvirt_pc(struct _vx_cvirt_pc *cvirt_pc,
23375 +       char *buffer, int cpu)
23376 +{
23377 +       int length = 0;
23378 +       return length;
23379 +}
23380 +
23381 +#endif /* _VX_CVIRT_PROC_H */
23382 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/debug.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/debug.c
23383 --- linux-2.6.19.1/kernel/vserver/debug.c       1970-01-01 01:00:00 +0100
23384 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/debug.c     2006-11-30 18:53:18 +0100
23385 @@ -0,0 +1,35 @@
23386 +/*
23387 + *  kernel/vserver/debug.c
23388 + *
23389 + *  Copyright (C) 2005  Herbert Pötzl
23390 + *
23391 + *  V0.01  vx_info dump support
23392 + *
23393 + */
23394 +
23395 +#include <linux/errno.h>
23396 +#include <linux/kernel.h>
23397 +#include <linux/module.h>
23398 +#include <linux/vs_base.h>
23399 +
23400 +#include <linux/vserver/context.h>
23401 +
23402 +
23403 +void   dump_vx_info(struct vx_info *vxi, int level)
23404 +{
23405 +       printk("vx_info %p[#%d, %d.%d, %4x]\n", vxi, vxi->vx_id,
23406 +               atomic_read(&vxi->vx_usecnt),
23407 +               atomic_read(&vxi->vx_tasks),
23408 +               vxi->vx_state);
23409 +       if (level > 0) {
23410 +               __dump_vx_limit(&vxi->limit);
23411 +               __dump_vx_sched(&vxi->sched);
23412 +               __dump_vx_cvirt(&vxi->cvirt);
23413 +               __dump_vx_cacct(&vxi->cacct);
23414 +       }
23415 +       printk("---\n");
23416 +}
23417 +
23418 +
23419 +EXPORT_SYMBOL_GPL(dump_vx_info);
23420 +
23421 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/dlimit.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/dlimit.c
23422 --- linux-2.6.19.1/kernel/vserver/dlimit.c      1970-01-01 01:00:00 +0100
23423 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/dlimit.c    2006-11-08 04:57:50 +0100
23424 @@ -0,0 +1,527 @@
23425 +/*
23426 + *  linux/kernel/vserver/dlimit.c
23427 + *
23428 + *  Virtual Server: Context Disk Limits
23429 + *
23430 + *  Copyright (C) 2004-2005  Herbert Pötzl
23431 + *
23432 + *  V0.01  initial version
23433 + *  V0.02  compat32 splitup
23434 + *
23435 + */
23436 +
23437 +#include <linux/fs.h>
23438 +#include <linux/namespace.h>
23439 +#include <linux/namei.h>
23440 +#include <linux/statfs.h>
23441 +#include <linux/compat.h>
23442 +#include <linux/vserver/switch.h>
23443 +#include <linux/vs_context.h>
23444 +#include <linux/vs_tag.h>
23445 +#include <linux/vs_dlimit.h>
23446 +#include <linux/vserver/dlimit_cmd.h>
23447 +
23448 +#include <asm/errno.h>
23449 +#include <asm/uaccess.h>
23450 +
23451 +/*     __alloc_dl_info()
23452 +
23453 +       * allocate an initialized dl_info struct
23454 +       * doesn't make it visible (hash)                        */
23455 +
23456 +static struct dl_info *__alloc_dl_info(struct super_block *sb, tag_t tag)
23457 +{
23458 +       struct dl_info *new = NULL;
23459 +
23460 +       vxdprintk(VXD_CBIT(dlim, 5),
23461 +               "alloc_dl_info(%p,%d)*", sb, tag);
23462 +
23463 +       /* would this benefit from a slab cache? */
23464 +       new = kmalloc(sizeof(struct dl_info), GFP_KERNEL);
23465 +       if (!new)
23466 +               return 0;
23467 +
23468 +       memset (new, 0, sizeof(struct dl_info));
23469 +       new->dl_tag = tag;
23470 +       new->dl_sb = sb;
23471 +       INIT_RCU_HEAD(&new->dl_rcu);
23472 +       INIT_HLIST_NODE(&new->dl_hlist);
23473 +       spin_lock_init(&new->dl_lock);
23474 +       atomic_set(&new->dl_refcnt, 0);
23475 +       atomic_set(&new->dl_usecnt, 0);
23476 +
23477 +       /* rest of init goes here */
23478 +
23479 +       vxdprintk(VXD_CBIT(dlim, 4),
23480 +               "alloc_dl_info(%p,%d) = %p", sb, tag, new);
23481 +       return new;
23482 +}
23483 +
23484 +/*     __dealloc_dl_info()
23485 +
23486 +       * final disposal of dl_info                             */
23487 +
23488 +static void __dealloc_dl_info(struct dl_info *dli)
23489 +{
23490 +       vxdprintk(VXD_CBIT(dlim, 4),
23491 +               "dealloc_dl_info(%p)", dli);
23492 +
23493 +       dli->dl_hlist.next = LIST_POISON1;
23494 +       dli->dl_tag = -1;
23495 +       dli->dl_sb = 0;
23496 +
23497 +       BUG_ON(atomic_read(&dli->dl_usecnt));
23498 +       BUG_ON(atomic_read(&dli->dl_refcnt));
23499 +
23500 +       kfree(dli);
23501 +}
23502 +
23503 +
23504 +/*     hash table for dl_info hash */
23505 +
23506 +#define DL_HASH_SIZE   13
23507 +
23508 +struct hlist_head dl_info_hash[DL_HASH_SIZE];
23509 +
23510 +static spinlock_t dl_info_hash_lock = SPIN_LOCK_UNLOCKED;
23511 +
23512 +
23513 +static inline unsigned int __hashval(struct super_block *sb, tag_t tag)
23514 +{
23515 +       return ((tag ^ (unsigned long)sb) % DL_HASH_SIZE);
23516 +}
23517 +
23518 +
23519 +
23520 +/*     __hash_dl_info()
23521 +
23522 +       * add the dli to the global hash table
23523 +       * requires the hash_lock to be held                     */
23524 +
23525 +static inline void __hash_dl_info(struct dl_info *dli)
23526 +{
23527 +       struct hlist_head *head;
23528 +
23529 +       vxdprintk(VXD_CBIT(dlim, 6),
23530 +               "__hash_dl_info: %p[#%d]", dli, dli->dl_tag);
23531 +       get_dl_info(dli);
23532 +       head = &dl_info_hash[__hashval(dli->dl_sb, dli->dl_tag)];
23533 +       hlist_add_head_rcu(&dli->dl_hlist, head);
23534 +}
23535 +
23536 +/*     __unhash_dl_info()
23537 +
23538 +       * remove the dli from the global hash table
23539 +       * requires the hash_lock to be held                     */
23540 +
23541 +static inline void __unhash_dl_info(struct dl_info *dli)
23542 +{
23543 +       vxdprintk(VXD_CBIT(dlim, 6),
23544 +               "__unhash_dl_info: %p[#%d]", dli, dli->dl_tag);
23545 +       hlist_del_rcu(&dli->dl_hlist);
23546 +       put_dl_info(dli);
23547 +}
23548 +
23549 +
23550 +/*     __lookup_dl_info()
23551 +
23552 +       * requires the rcu_read_lock()
23553 +       * doesn't increment the dl_refcnt                       */
23554 +
23555 +static inline struct dl_info *__lookup_dl_info(struct super_block *sb, tag_t tag)
23556 +{
23557 +       struct hlist_head *head = &dl_info_hash[__hashval(sb, tag)];
23558 +       struct hlist_node *pos;
23559 +       struct dl_info *dli;
23560 +
23561 +       hlist_for_each_entry_rcu(dli, pos, head, dl_hlist) {
23562 +
23563 +               if (dli->dl_tag == tag && dli->dl_sb == sb) {
23564 +                       return dli;
23565 +               }
23566 +       }
23567 +       return NULL;
23568 +}
23569 +
23570 +
23571 +struct dl_info *locate_dl_info(struct super_block *sb, tag_t tag)
23572 +{
23573 +       struct dl_info *dli;
23574 +
23575 +       rcu_read_lock();
23576 +       dli = get_dl_info(__lookup_dl_info(sb, tag));
23577 +       vxdprintk(VXD_CBIT(dlim, 7),
23578 +               "locate_dl_info(%p,#%d) = %p", sb, tag, dli);
23579 +       rcu_read_unlock();
23580 +       return dli;
23581 +}
23582 +
23583 +void rcu_free_dl_info(struct rcu_head *head)
23584 +{
23585 +       struct dl_info *dli = container_of(head, struct dl_info, dl_rcu);
23586 +       int usecnt, refcnt;
23587 +
23588 +       BUG_ON(!dli || !head);
23589 +
23590 +       usecnt = atomic_read(&dli->dl_usecnt);
23591 +       BUG_ON(usecnt < 0);
23592 +
23593 +       refcnt = atomic_read(&dli->dl_refcnt);
23594 +       BUG_ON(refcnt < 0);
23595 +
23596 +       vxdprintk(VXD_CBIT(dlim, 3),
23597 +               "rcu_free_dl_info(%p)", dli);
23598 +       if (!usecnt)
23599 +               __dealloc_dl_info(dli);
23600 +       else
23601 +               printk("!!! rcu didn't free\n");
23602 +}
23603 +
23604 +
23605 +
23606 +
23607 +static int do_addrem_dlimit(uint32_t id, const char __user *name,
23608 +       uint32_t flags, int add)
23609 +{
23610 +       struct nameidata nd;
23611 +       int ret;
23612 +
23613 +       ret = user_path_walk_link(name, &nd);
23614 +       if (!ret) {
23615 +               struct super_block *sb;
23616 +               struct dl_info *dli;
23617 +
23618 +               ret = -EINVAL;
23619 +               if (!nd.dentry->d_inode)
23620 +                       goto out_release;
23621 +               if (!(sb = nd.dentry->d_inode->i_sb))
23622 +                       goto out_release;
23623 +
23624 +               if (add) {
23625 +                       dli = __alloc_dl_info(sb, id);
23626 +                       spin_lock(&dl_info_hash_lock);
23627 +
23628 +                       ret = -EEXIST;
23629 +                       if (__lookup_dl_info(sb, id))
23630 +                               goto out_unlock;
23631 +                       __hash_dl_info(dli);
23632 +                       dli = NULL;
23633 +               } else {
23634 +                       spin_lock(&dl_info_hash_lock);
23635 +                       dli = __lookup_dl_info(sb, id);
23636 +
23637 +                       ret = -ESRCH;
23638 +                       if (!dli)
23639 +                               goto out_unlock;
23640 +                       __unhash_dl_info(dli);
23641 +               }
23642 +               ret = 0;
23643 +       out_unlock:
23644 +               spin_unlock(&dl_info_hash_lock);
23645 +               if (add && dli)
23646 +                       __dealloc_dl_info(dli);
23647 +       out_release:
23648 +               path_release(&nd);
23649 +       }
23650 +       return ret;
23651 +}
23652 +
23653 +int vc_add_dlimit(uint32_t id, void __user *data)
23654 +{
23655 +       struct vcmd_ctx_dlimit_base_v0 vc_data;
23656 +
23657 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23658 +               return -EFAULT;
23659 +
23660 +       return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1);
23661 +}
23662 +
23663 +int vc_rem_dlimit(uint32_t id, void __user *data)
23664 +{
23665 +       struct vcmd_ctx_dlimit_base_v0 vc_data;
23666 +
23667 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23668 +               return -EFAULT;
23669 +
23670 +       return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0);
23671 +}
23672 +
23673 +#ifdef CONFIG_COMPAT
23674 +
23675 +int vc_add_dlimit_x32(uint32_t id, void __user *data)
23676 +{
23677 +       struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
23678 +
23679 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23680 +               return -EFAULT;
23681 +
23682 +       return do_addrem_dlimit(id,
23683 +               compat_ptr(vc_data.name_ptr), vc_data.flags, 1);
23684 +}
23685 +
23686 +int vc_rem_dlimit_x32(uint32_t id, void __user *data)
23687 +{
23688 +       struct vcmd_ctx_dlimit_base_v0_x32 vc_data;
23689 +
23690 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23691 +               return -EFAULT;
23692 +
23693 +       return do_addrem_dlimit(id,
23694 +               compat_ptr(vc_data.name_ptr), vc_data.flags, 0);
23695 +}
23696 +
23697 +#endif /* CONFIG_COMPAT */
23698 +
23699 +
23700 +static inline
23701 +int do_set_dlimit(uint32_t id, const char __user *name,
23702 +       uint32_t space_used, uint32_t space_total,
23703 +       uint32_t inodes_used, uint32_t inodes_total,
23704 +       uint32_t reserved, uint32_t flags)
23705 +{
23706 +       struct nameidata nd;
23707 +       int ret;
23708 +
23709 +       ret = user_path_walk_link(name, &nd);
23710 +       if (!ret) {
23711 +               struct super_block *sb;
23712 +               struct dl_info *dli;
23713 +
23714 +               ret = -EINVAL;
23715 +               if (!nd.dentry->d_inode)
23716 +                       goto out_release;
23717 +               if (!(sb = nd.dentry->d_inode->i_sb))
23718 +                       goto out_release;
23719 +               if ((reserved != CDLIM_KEEP &&
23720 +                       reserved > 100) ||
23721 +                       (inodes_used != CDLIM_KEEP &&
23722 +                       inodes_used > inodes_total) ||
23723 +                       (space_used != CDLIM_KEEP &&
23724 +                       space_used > space_total))
23725 +                       goto out_release;
23726 +
23727 +               ret = -ESRCH;
23728 +               dli = locate_dl_info(sb, id);
23729 +               if (!dli)
23730 +                       goto out_release;
23731 +
23732 +               spin_lock(&dli->dl_lock);
23733 +
23734 +               if (inodes_used != CDLIM_KEEP)
23735 +                       dli->dl_inodes_used = inodes_used;
23736 +               if (inodes_total != CDLIM_KEEP)
23737 +                       dli->dl_inodes_total = inodes_total;
23738 +               if (space_used != CDLIM_KEEP) {
23739 +                       dli->dl_space_used = space_used;
23740 +                       dli->dl_space_used <<= 10;
23741 +               }
23742 +               if (space_total == CDLIM_INFINITY)
23743 +                       dli->dl_space_total = DLIM_INFINITY;
23744 +               else if (space_total != CDLIM_KEEP) {
23745 +                       dli->dl_space_total = space_total;
23746 +                       dli->dl_space_total <<= 10;
23747 +               }
23748 +               if (reserved != CDLIM_KEEP)
23749 +                       dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100;
23750 +
23751 +               spin_unlock(&dli->dl_lock);
23752 +
23753 +               put_dl_info(dli);
23754 +               ret = 0;
23755 +
23756 +       out_release:
23757 +               path_release(&nd);
23758 +       }
23759 +       return ret;
23760 +}
23761 +
23762 +int vc_set_dlimit(uint32_t id, void __user *data)
23763 +{
23764 +       struct vcmd_ctx_dlimit_v0 vc_data;
23765 +
23766 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23767 +               return -EFAULT;
23768 +
23769 +       return do_set_dlimit(id, vc_data.name,
23770 +               vc_data.space_used, vc_data.space_total,
23771 +               vc_data.inodes_used, vc_data.inodes_total,
23772 +               vc_data.reserved, vc_data.flags);
23773 +}
23774 +
23775 +#ifdef CONFIG_COMPAT
23776 +
23777 +int vc_set_dlimit_x32(uint32_t id, void __user *data)
23778 +{
23779 +       struct vcmd_ctx_dlimit_v0_x32 vc_data;
23780 +
23781 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23782 +               return -EFAULT;
23783 +
23784 +       return do_set_dlimit(id, compat_ptr(vc_data.name_ptr),
23785 +               vc_data.space_used, vc_data.space_total,
23786 +               vc_data.inodes_used, vc_data.inodes_total,
23787 +               vc_data.reserved, vc_data.flags);
23788 +}
23789 +
23790 +#endif /* CONFIG_COMPAT */
23791 +
23792 +
23793 +static inline
23794 +int do_get_dlimit(uint32_t id, const char __user *name,
23795 +       uint32_t *space_used, uint32_t *space_total,
23796 +       uint32_t *inodes_used, uint32_t *inodes_total,
23797 +       uint32_t *reserved, uint32_t *flags)
23798 +{
23799 +       struct nameidata nd;
23800 +       int ret;
23801 +
23802 +       ret = user_path_walk_link(name, &nd);
23803 +       if (!ret) {
23804 +               struct super_block *sb;
23805 +               struct dl_info *dli;
23806 +
23807 +               ret = -EINVAL;
23808 +               if (!nd.dentry->d_inode)
23809 +                       goto out_release;
23810 +               if (!(sb = nd.dentry->d_inode->i_sb))
23811 +                       goto out_release;
23812 +
23813 +               ret = -ESRCH;
23814 +               dli = locate_dl_info(sb, id);
23815 +               if (!dli)
23816 +                       goto out_release;
23817 +
23818 +               spin_lock(&dli->dl_lock);
23819 +               *inodes_used = dli->dl_inodes_used;
23820 +               *inodes_total = dli->dl_inodes_total;
23821 +               *space_used = dli->dl_space_used >> 10;
23822 +               if (dli->dl_space_total == DLIM_INFINITY)
23823 +                       *space_total = CDLIM_INFINITY;
23824 +               else
23825 +                       *space_total = dli->dl_space_total >> 10;
23826 +
23827 +               *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10);
23828 +               spin_unlock(&dli->dl_lock);
23829 +
23830 +               put_dl_info(dli);
23831 +               ret = -EFAULT;
23832 +
23833 +               ret = 0;
23834 +       out_release:
23835 +               path_release(&nd);
23836 +       }
23837 +       return ret;
23838 +}
23839 +
23840 +
23841 +int vc_get_dlimit(uint32_t id, void __user *data)
23842 +{
23843 +       struct vcmd_ctx_dlimit_v0 vc_data;
23844 +       int ret;
23845 +
23846 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23847 +               return -EFAULT;
23848 +
23849 +       ret = do_get_dlimit(id, vc_data.name,
23850 +               &vc_data.space_used, &vc_data.space_total,
23851 +               &vc_data.inodes_used, &vc_data.inodes_total,
23852 +               &vc_data.reserved, &vc_data.flags);
23853 +       if (ret)
23854 +               return ret;
23855 +
23856 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
23857 +               return -EFAULT;
23858 +       return 0;
23859 +}
23860 +
23861 +#ifdef CONFIG_COMPAT
23862 +
23863 +int vc_get_dlimit_x32(uint32_t id, void __user *data)
23864 +{
23865 +       struct vcmd_ctx_dlimit_v0_x32 vc_data;
23866 +       int ret;
23867 +
23868 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
23869 +               return -EFAULT;
23870 +
23871 +       ret = do_get_dlimit(id, compat_ptr(vc_data.name_ptr),
23872 +               &vc_data.space_used, &vc_data.space_total,
23873 +               &vc_data.inodes_used, &vc_data.inodes_total,
23874 +               &vc_data.reserved, &vc_data.flags);
23875 +       if (ret)
23876 +               return ret;
23877 +
23878 +       if (copy_to_user(data, &vc_data, sizeof(vc_data)))
23879 +               return -EFAULT;
23880 +       return 0;
23881 +}
23882 +
23883 +#endif /* CONFIG_COMPAT */
23884 +
23885 +
23886 +void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf)
23887 +{
23888 +       struct dl_info *dli;
23889 +       __u64 blimit, bfree, bavail;
23890 +       __u32 ifree;
23891 +
23892 +       dli = locate_dl_info(sb, dx_current_tag());
23893 +       if (!dli)
23894 +               return;
23895 +
23896 +       spin_lock(&dli->dl_lock);
23897 +       if (dli->dl_inodes_total == (unsigned long)DLIM_INFINITY)
23898 +               goto no_ilim;
23899 +
23900 +       /* reduce max inodes available to limit */
23901 +       if (buf->f_files > dli->dl_inodes_total)
23902 +               buf->f_files = dli->dl_inodes_total;
23903 +
23904 +       ifree = dli->dl_inodes_total - dli->dl_inodes_used;
23905 +       /* reduce free inodes to min */
23906 +       if (ifree < buf->f_ffree)
23907 +               buf->f_ffree = ifree;
23908 +
23909 +no_ilim:
23910 +       if (dli->dl_space_total == DLIM_INFINITY)
23911 +               goto no_blim;
23912 +
23913 +       blimit = dli->dl_space_total >> sb->s_blocksize_bits;
23914 +
23915 +       if (dli->dl_space_total < dli->dl_space_used)
23916 +               bfree = 0;
23917 +       else
23918 +               bfree = (dli->dl_space_total - dli->dl_space_used)
23919 +                       >> sb->s_blocksize_bits;
23920 +
23921 +       bavail = ((dli->dl_space_total >> 10) * dli->dl_nrlmult);
23922 +       if (bavail < dli->dl_space_used)
23923 +               bavail = 0;
23924 +       else
23925 +               bavail = (bavail - dli->dl_space_used)
23926 +                       >> sb->s_blocksize_bits;
23927 +
23928 +       /* reduce max space available to limit */
23929 +       if (buf->f_blocks > blimit)
23930 +               buf->f_blocks = blimit;
23931 +
23932 +       /* reduce free space to min */
23933 +       if (bfree < buf->f_bfree)
23934 +               buf->f_bfree = bfree;
23935 +
23936 +       /* reduce avail space to min */
23937 +       if (bavail < buf->f_bavail)
23938 +               buf->f_bavail = bavail;
23939 +
23940 +no_blim:
23941 +       spin_unlock(&dli->dl_lock);
23942 +       put_dl_info(dli);
23943 +
23944 +       return;
23945 +}
23946 +
23947 +#include <linux/module.h>
23948 +
23949 +EXPORT_SYMBOL_GPL(locate_dl_info);
23950 +EXPORT_SYMBOL_GPL(rcu_free_dl_info);
23951 +
23952 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/helper.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/helper.c
23953 --- linux-2.6.19.1/kernel/vserver/helper.c      1970-01-01 01:00:00 +0100
23954 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/helper.c    2006-12-17 04:34:43 +0100
23955 @@ -0,0 +1,204 @@
23956 +/*
23957 + *  linux/kernel/vserver/helper.c
23958 + *
23959 + *  Virtual Context Support
23960 + *
23961 + *  Copyright (C) 2004-2005  Herbert Pötzl
23962 + *
23963 + *  V0.01  basic helper
23964 + *
23965 + */
23966 +
23967 +#include <linux/errno.h>
23968 +#include <linux/kmod.h>
23969 +#include <linux/sched.h>
23970 +#include <linux/reboot.h>
23971 +#include <linux/vs_context.h>
23972 +#include <linux/vs_network.h>
23973 +#include <linux/vserver/signal.h>
23974 +
23975 +#include <asm/uaccess.h>
23976 +#include <asm/unistd.h>
23977 +
23978 +
23979 +char vshelper_path[255] = "/sbin/vshelper";
23980 +
23981 +
23982 +static int do_vshelper(char *name, char *argv[], char *envp[], int sync)
23983 +{
23984 +       int ret;
23985 +
23986 +       if ((ret = call_usermodehelper(name, argv, envp, sync))) {
23987 +               printk( KERN_WARNING
23988 +                       "%s: (%s %s) returned %s with %d\n",
23989 +                       name, argv[1], argv[2],
23990 +                       sync?"sync":"async", ret);
23991 +       }
23992 +       vxdprintk(VXD_CBIT(switch, 4),
23993 +               "%s: (%s %s) returned %s with %d",
23994 +               name, argv[1], argv[2], sync?"sync":"async", ret);
23995 +       return ret;
23996 +}
23997 +
23998 +/*
23999 + *      vshelper path is set via /proc/sys
24000 + *      invoked by vserver sys_reboot(), with
24001 + *      the following arguments
24002 + *
24003 + *      argv [0] = vshelper_path;
24004 + *      argv [1] = action: "restart", "halt", "poweroff", ...
24005 + *      argv [2] = context identifier
24006 + *
24007 + *      envp [*] = type-specific parameters
24008 + */
24009 +
24010 +long vs_reboot_helper(struct vx_info *vxi, int cmd, void __user *arg)
24011 +{
24012 +       char id_buf[8], cmd_buf[16];
24013 +       char uid_buf[16], pid_buf[16];
24014 +       int ret;
24015 +
24016 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
24017 +       char *envp[] = {"HOME=/", "TERM=linux",
24018 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
24019 +                       uid_buf, pid_buf, cmd_buf, 0};
24020 +
24021 +       if (vx_info_state(vxi, VXS_HELPER))
24022 +               return -EAGAIN;
24023 +       vxi->vx_state |= VXS_HELPER;
24024 +
24025 +       snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
24026 +
24027 +       snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
24028 +       snprintf(uid_buf, sizeof(uid_buf)-1, "VS_UID=%d", current->uid);
24029 +       snprintf(pid_buf, sizeof(pid_buf)-1, "VS_PID=%d", current->pid);
24030 +
24031 +       switch (cmd) {
24032 +       case LINUX_REBOOT_CMD_RESTART:
24033 +               argv[1] = "restart";
24034 +               break;
24035 +
24036 +       case LINUX_REBOOT_CMD_HALT:
24037 +               argv[1] = "halt";
24038 +               break;
24039 +
24040 +       case LINUX_REBOOT_CMD_POWER_OFF:
24041 +               argv[1] = "poweroff";
24042 +               break;
24043 +
24044 +       case LINUX_REBOOT_CMD_SW_SUSPEND:
24045 +               argv[1] = "swsusp";
24046 +               break;
24047 +
24048 +       default:
24049 +               vxi->vx_state &= ~VXS_HELPER;
24050 +               return 0;
24051 +       }
24052 +
24053 +       ret = do_vshelper(vshelper_path, argv, envp, 0);
24054 +       vxi->vx_state &= ~VXS_HELPER;
24055 +       __wakeup_vx_info(vxi);
24056 +       return (ret) ? -EPERM : 0;
24057 +}
24058 +
24059 +
24060 +long vs_reboot(unsigned int cmd, void __user * arg)
24061 +{
24062 +       struct vx_info *vxi = current->vx_info;
24063 +       long ret = 0;
24064 +
24065 +       vxdprintk(VXD_CBIT(misc, 5),
24066 +               "vs_reboot(%p[#%d],%d)",
24067 +               vxi, vxi?vxi->vx_id:0, cmd);
24068 +
24069 +       ret = vs_reboot_helper(vxi, cmd, arg);
24070 +       if (ret)
24071 +               return ret;
24072 +
24073 +       vxi->reboot_cmd = cmd;
24074 +       if (vx_info_flags(vxi, VXF_REBOOT_KILL, 0)) {
24075 +               switch (cmd) {
24076 +               case LINUX_REBOOT_CMD_RESTART:
24077 +               case LINUX_REBOOT_CMD_HALT:
24078 +               case LINUX_REBOOT_CMD_POWER_OFF:
24079 +                       vx_info_kill(vxi, 0, SIGKILL);
24080 +                       vx_info_kill(vxi, 1, SIGKILL);
24081 +               default:
24082 +                       break;
24083 +               }
24084 +       }
24085 +       return 0;
24086 +}
24087 +
24088 +
24089 +/*
24090 + *      argv [0] = vshelper_path;
24091 + *      argv [1] = action: "startup", "shutdown"
24092 + *      argv [2] = context identifier
24093 + *
24094 + *      envp [*] = type-specific parameters
24095 + */
24096 +
24097 +long vs_state_change(struct vx_info *vxi, unsigned int cmd)
24098 +{
24099 +       char id_buf[8], cmd_buf[16];
24100 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
24101 +       char *envp[] = {"HOME=/", "TERM=linux",
24102 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
24103 +
24104 +       if (!vx_info_flags(vxi, VXF_SC_HELPER, 0))
24105 +               return 0;
24106 +
24107 +       snprintf(id_buf, sizeof(id_buf)-1, "%d", vxi->vx_id);
24108 +       snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
24109 +
24110 +       switch (cmd) {
24111 +       case VSC_STARTUP:
24112 +               argv[1] = "startup";
24113 +               break;
24114 +       case VSC_SHUTDOWN:
24115 +               argv[1] = "shutdown";
24116 +               break;
24117 +       default:
24118 +               return 0;
24119 +       }
24120 +
24121 +       return do_vshelper(vshelper_path, argv, envp, 1);
24122 +}
24123 +
24124 +
24125 +/*
24126 + *      argv [0] = vshelper_path;
24127 + *      argv [1] = action: "netup", "netdown"
24128 + *      argv [2] = context identifier
24129 + *
24130 + *      envp [*] = type-specific parameters
24131 + */
24132 +
24133 +long vs_net_change(struct nx_info *nxi, unsigned int cmd)
24134 +{
24135 +       char id_buf[8], cmd_buf[16];
24136 +       char *argv[] = {vshelper_path, NULL, id_buf, 0};
24137 +       char *envp[] = {"HOME=/", "TERM=linux",
24138 +                       "PATH=/sbin:/usr/sbin:/bin:/usr/bin", cmd_buf, 0};
24139 +
24140 +       if (!nx_info_flags(nxi, NXF_SC_HELPER, 0))
24141 +               return 0;
24142 +
24143 +       snprintf(id_buf, sizeof(id_buf)-1, "%d", nxi->nx_id);
24144 +       snprintf(cmd_buf, sizeof(cmd_buf)-1, "VS_CMD=%08x", cmd);
24145 +
24146 +       switch (cmd) {
24147 +       case VSC_NETUP:
24148 +               argv[1] = "netup";
24149 +               break;
24150 +       case VSC_NETDOWN:
24151 +               argv[1] = "netdown";
24152 +               break;
24153 +       default:
24154 +               return 0;
24155 +       }
24156 +
24157 +       return do_vshelper(vshelper_path, argv, envp, 1);
24158 +}
24159 +
24160 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/history.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/history.c
24161 --- linux-2.6.19.1/kernel/vserver/history.c     1970-01-01 01:00:00 +0100
24162 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/history.c   2006-11-30 18:53:18 +0100
24163 @@ -0,0 +1,264 @@
24164 +/*
24165 + *  kernel/vserver/history.c
24166 + *
24167 + *  Virtual Context History Backtrace
24168 + *
24169 + *  Copyright (C) 2004-2005  Herbert Pötzl
24170 + *
24171 + *  V0.01  basic structure
24172 + *  V0.02  hash/unhash and trace
24173 + *  V0.03  preemption fixes
24174 + *
24175 + */
24176 +
24177 +#include <linux/errno.h>
24178 +#include <linux/module.h>
24179 +#include <linux/types.h>
24180 +#include <linux/ctype.h>
24181 +
24182 +#include <asm/uaccess.h>
24183 +#include <asm/atomic.h>
24184 +#include <asm/unistd.h>
24185 +
24186 +#include <linux/vserver/context.h>
24187 +#include <linux/vserver/debug.h>
24188 +#include <linux/vserver/debug_cmd.h>
24189 +#include <linux/vserver/history.h>
24190 +
24191 +
24192 +#ifdef CONFIG_VSERVER_HISTORY
24193 +#define VXH_SIZE       CONFIG_VSERVER_HISTORY_SIZE
24194 +#else
24195 +#define VXH_SIZE       64
24196 +#endif
24197 +
24198 +struct _vx_history {
24199 +       unsigned int counter;
24200 +
24201 +       struct _vx_hist_entry entry[VXH_SIZE+1];
24202 +};
24203 +
24204 +
24205 +DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
24206 +
24207 +unsigned volatile int vxh_active = 1;
24208 +
24209 +static atomic_t sequence = ATOMIC_INIT(0);
24210 +
24211 +
24212 +/*     vxh_advance()
24213 +
24214 +       * requires disabled preemption                          */
24215 +
24216 +struct _vx_hist_entry *vxh_advance(void *loc)
24217 +{
24218 +       unsigned int cpu = smp_processor_id();
24219 +       struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
24220 +       struct _vx_hist_entry *entry;
24221 +       unsigned int index;
24222 +
24223 +       index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
24224 +       entry = &hist->entry[index];
24225 +
24226 +       entry->seq = atomic_inc_return(&sequence);
24227 +       entry->loc = loc;
24228 +       return entry;
24229 +}
24230 +
24231 +EXPORT_SYMBOL_GPL(vxh_advance);
24232 +
24233 +
24234 +#define VXH_LOC_FMTS   "(#%04x,*%d):%p"
24235 +
24236 +#define VXH_LOC_ARGS(e)        (e)->seq, cpu, (e)->loc
24237 +
24238 +
24239 +#define VXH_VXI_FMTS   "%p[#%d,%d.%d]"
24240 +
24241 +#define VXH_VXI_ARGS(e)        (e)->vxi.ptr,                   \
24242 +                       (e)->vxi.ptr?(e)->vxi.xid:0,    \
24243 +                       (e)->vxi.ptr?(e)->vxi.usecnt:0, \
24244 +                       (e)->vxi.ptr?(e)->vxi.tasks:0
24245 +
24246 +void   vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
24247 +{
24248 +       switch (e->type) {
24249 +       case VXH_THROW_OOPS:
24250 +               printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
24251 +               break;
24252 +
24253 +       case VXH_GET_VX_INFO:
24254 +       case VXH_PUT_VX_INFO:
24255 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
24256 +                       VXH_LOC_ARGS(e),
24257 +                       (e->type==VXH_GET_VX_INFO)?"get":"put",
24258 +                       VXH_VXI_ARGS(e));
24259 +               break;
24260 +
24261 +       case VXH_INIT_VX_INFO:
24262 +       case VXH_SET_VX_INFO:
24263 +       case VXH_CLR_VX_INFO:
24264 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
24265 +                       VXH_LOC_ARGS(e),
24266 +                       (e->type==VXH_INIT_VX_INFO)?"init":
24267 +                       ((e->type==VXH_SET_VX_INFO)?"set":"clr"),
24268 +                       VXH_VXI_ARGS(e), e->sc.data);
24269 +               break;
24270 +
24271 +       case VXH_CLAIM_VX_INFO:
24272 +       case VXH_RELEASE_VX_INFO:
24273 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
24274 +                       VXH_LOC_ARGS(e),
24275 +                       (e->type==VXH_CLAIM_VX_INFO)?"claim":"release",
24276 +                       VXH_VXI_ARGS(e), e->sc.data);
24277 +               break;
24278 +
24279 +       case VXH_ALLOC_VX_INFO:
24280 +       case VXH_DEALLOC_VX_INFO:
24281 +               printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
24282 +                       VXH_LOC_ARGS(e),
24283 +                       (e->type==VXH_ALLOC_VX_INFO)?"alloc":"dealloc",
24284 +                       VXH_VXI_ARGS(e));
24285 +               break;
24286 +
24287 +       case VXH_HASH_VX_INFO:
24288 +       case VXH_UNHASH_VX_INFO:
24289 +               printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
24290 +                       VXH_LOC_ARGS(e),
24291 +                       (e->type==VXH_HASH_VX_INFO)?"hash":"unhash",
24292 +                       VXH_VXI_ARGS(e));
24293 +               break;
24294 +
24295 +       case VXH_LOC_VX_INFO:
24296 +       case VXH_LOOKUP_VX_INFO:
24297 +       case VXH_CREATE_VX_INFO:
24298 +               printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
24299 +                       VXH_LOC_ARGS(e),
24300 +                       (e->type==VXH_CREATE_VX_INFO)?"create":
24301 +                       ((e->type==VXH_LOC_VX_INFO)?"loc":"lookup"),
24302 +                       e->ll.arg, VXH_VXI_ARGS(e));
24303 +               break;
24304 +       }
24305 +}
24306 +
24307 +static void __vxh_dump_history(void)
24308 +{
24309 +       unsigned int i, cpu;
24310 +
24311 +       printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
24312 +               atomic_read(&sequence), NR_CPUS);
24313 +
24314 +       for (i=0; i < VXH_SIZE; i++) {
24315 +               for_each_online_cpu(cpu) {
24316 +                       struct _vx_history *hist =
24317 +                               &per_cpu(vx_history_buffer, cpu);
24318 +                       unsigned int index = (hist->counter-i) % VXH_SIZE;
24319 +                       struct _vx_hist_entry *entry = &hist->entry[index];
24320 +
24321 +                       vxh_dump_entry(entry, cpu);
24322 +               }
24323 +       }
24324 +}
24325 +
24326 +void   vxh_dump_history(void)
24327 +{
24328 +       vxh_active = 0;
24329 +#ifdef CONFIG_SMP
24330 +       local_irq_enable();
24331 +       smp_send_stop();
24332 +       local_irq_disable();
24333 +#endif
24334 +       __vxh_dump_history();
24335 +}
24336 +
24337 +
24338 +/* vserver syscall commands below here */
24339 +
24340 +
24341 +int vc_dump_history(uint32_t id)
24342 +{
24343 +       vxh_active = 0;
24344 +       __vxh_dump_history();
24345 +       vxh_active = 1;
24346 +
24347 +       return 0;
24348 +}
24349 +
24350 +
24351 +int do_read_history(struct __user _vx_hist_entry *data,
24352 +       int cpu, uint32_t *index, uint32_t *count)
24353 +{
24354 +       int pos, ret = 0;
24355 +       struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
24356 +       int end = hist->counter;
24357 +       int start = end - VXH_SIZE + 2;
24358 +       int idx = *index;
24359 +
24360 +       /* special case: get current pos */
24361 +       if (!*count) {
24362 +               *index = end;
24363 +               return 0;
24364 +       }
24365 +
24366 +       /* have we lost some data? */
24367 +       if (idx < start)
24368 +               idx = start;
24369 +
24370 +       for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
24371 +               struct _vx_hist_entry *entry =
24372 +                       &hist->entry[idx % VXH_SIZE];
24373 +
24374 +               /* send entry to userspace */
24375 +               ret = copy_to_user (&data[pos], entry, sizeof(*entry));
24376 +               if (ret)
24377 +                       break;
24378 +       }
24379 +       /* save new index and count */
24380 +       *index = idx;
24381 +       *count = pos;
24382 +       return ret ? ret : (*index < end);
24383 +}
24384 +
24385 +int vc_read_history(uint32_t id, void __user *data)
24386 +{
24387 +       struct vcmd_read_history_v0 vc_data;
24388 +       int ret;
24389 +
24390 +       if (id >= NR_CPUS)
24391 +               return -EINVAL;
24392 +
24393 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24394 +               return -EFAULT;
24395 +
24396 +       ret = do_read_history((struct __user _vx_hist_entry *)vc_data.data,
24397 +               id, &vc_data.index, &vc_data.count);
24398 +
24399 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24400 +               return -EFAULT;
24401 +       return ret;
24402 +}
24403 +
24404 +#ifdef CONFIG_COMPAT
24405 +
24406 +int vc_read_history_x32(uint32_t id, void __user *data)
24407 +{
24408 +       struct vcmd_read_history_v0_x32 vc_data;
24409 +       int ret;
24410 +
24411 +       if (id >= NR_CPUS)
24412 +               return -EINVAL;
24413 +
24414 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24415 +               return -EFAULT;
24416 +
24417 +       ret = do_read_history((struct __user _vx_hist_entry *)
24418 +               compat_ptr(vc_data.data_ptr),
24419 +               id, &vc_data.index, &vc_data.count);
24420 +
24421 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24422 +               return -EFAULT;
24423 +       return ret;
24424 +}
24425 +
24426 +#endif /* CONFIG_COMPAT */
24427 +
24428 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/inet.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/inet.c
24429 --- linux-2.6.19.1/kernel/vserver/inet.c        1970-01-01 01:00:00 +0100
24430 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/inet.c      2006-12-17 03:23:33 +0100
24431 @@ -0,0 +1,56 @@
24432 +
24433 +#include <linux/sched.h>
24434 +#include <linux/vs_inet.h>
24435 +
24436 +
24437 +int nx_addr_conflict(struct nx_info *nxi, uint32_t addr, struct sock *sk)
24438 +{
24439 +       vxdprintk(VXD_CBIT(net, 2),
24440 +               "nx_addr_conflict(%p,%p) %d.%d,%d.%d",
24441 +               nxi, sk, VXD_QUAD(addr));
24442 +
24443 +       if (addr) {
24444 +               /* check real address */
24445 +               return __addr_in_socket(sk, addr);
24446 +       } else if (nxi) {
24447 +               /* check against nx_info */
24448 +               int i, n = nxi->nbipv4;
24449 +
24450 +               for (i=0; i<n; i++)
24451 +                       if (__addr_in_socket(sk, nxi->ipv4[i]))
24452 +                               return 1;
24453 +               return 0;
24454 +       } else {
24455 +               /* check against any */
24456 +               return 1;
24457 +       }
24458 +}
24459 +
24460 +
24461 +int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
24462 +{
24463 +       struct in_device *in_dev;
24464 +       struct in_ifaddr **ifap;
24465 +       struct in_ifaddr *ifa;
24466 +       int ret = 0;
24467 +
24468 +       if (!nxi)
24469 +               return 1;
24470 +
24471 +       in_dev = in_dev_get(dev);
24472 +       if (!in_dev)
24473 +               goto out;
24474 +
24475 +       for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
24476 +               ifap = &ifa->ifa_next) {
24477 +               if (addr_in_nx_info(nxi, ifa->ifa_local)) {
24478 +                       ret = 1;
24479 +                       break;
24480 +               }
24481 +       }
24482 +       in_dev_put(in_dev);
24483 +out:
24484 +       return ret;
24485 +}
24486 +
24487 +
24488 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/init.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/init.c
24489 --- linux-2.6.19.1/kernel/vserver/init.c        1970-01-01 01:00:00 +0100
24490 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/init.c      2006-11-09 01:00:34 +0100
24491 @@ -0,0 +1,47 @@
24492 +/*
24493 + *  linux/kernel/init.c
24494 + *
24495 + *  Virtual Server Init
24496 + *
24497 + *  Copyright (C) 2004-2005  Herbert Pötzl
24498 + *
24499 + *  V0.01  basic structure
24500 + *
24501 + */
24502 +
24503 +#include <linux/errno.h>
24504 +#include <linux/init.h>
24505 +#include <linux/module.h>
24506 +
24507 +int    vserver_register_sysctl(void);
24508 +void   vserver_unregister_sysctl(void);
24509 +
24510 +
24511 +static int __init init_vserver(void)
24512 +{
24513 +       int ret = 0;
24514 +
24515 +#ifdef CONFIG_VSERVER_DEBUG
24516 +       vserver_register_sysctl();
24517 +#endif
24518 +       return ret;
24519 +}
24520 +
24521 +
24522 +static void __exit exit_vserver(void)
24523 +{
24524 +
24525 +#ifdef CONFIG_VSERVER_DEBUG
24526 +       vserver_unregister_sysctl();
24527 +#endif
24528 +       return;
24529 +}
24530 +
24531 +/* FIXME: GFP_ZONETYPES gone
24532 +long vx_slab[GFP_ZONETYPES]; */
24533 +long vx_area;
24534 +
24535 +
24536 +module_init(init_vserver);
24537 +module_exit(exit_vserver);
24538 +
24539 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/inode.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/inode.c
24540 --- linux-2.6.19.1/kernel/vserver/inode.c       1970-01-01 01:00:00 +0100
24541 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/inode.c     2006-12-17 04:29:30 +0100
24542 @@ -0,0 +1,321 @@
24543 +/*
24544 + *  linux/kernel/vserver/inode.c
24545 + *
24546 + *  Virtual Server: File System Support
24547 + *
24548 + *  Copyright (C) 2004-2005  Herbert Pötzl
24549 + *
24550 + *  V0.01  separated from vcontext V0.05
24551 + *
24552 + */
24553 +
24554 +#include <linux/sched.h>
24555 +#include <linux/proc_fs.h>
24556 +#include <linux/devpts_fs.h>
24557 +#include <linux/namei.h>
24558 +#include <linux/mount.h>
24559 +#include <linux/parser.h>
24560 +#include <linux/compat.h>
24561 +#include <linux/vserver/inode.h>
24562 +#include <linux/vserver/inode_cmd.h>
24563 +#include <linux/vs_base.h>
24564 +#include <linux/vs_tag.h>
24565 +
24566 +#include <asm/errno.h>
24567 +#include <asm/uaccess.h>
24568 +
24569 +
24570 +static int __vc_get_iattr(struct inode *in, uint32_t *tag, uint32_t *flags, uint32_t *mask)
24571 +{
24572 +       struct proc_dir_entry *entry;
24573 +
24574 +       if (!in || !in->i_sb)
24575 +               return -ESRCH;
24576 +
24577 +       *flags = IATTR_TAG
24578 +               | (IS_BARRIER(in) ? IATTR_BARRIER : 0)
24579 +               | (IS_IUNLINK(in) ? IATTR_IUNLINK : 0)
24580 +               | (IS_IMMUTABLE(in) ? IATTR_IMMUTABLE : 0);
24581 +       *mask = IATTR_IUNLINK | IATTR_IMMUTABLE;
24582 +
24583 +       if (S_ISDIR(in->i_mode))
24584 +               *mask |= IATTR_BARRIER;
24585 +
24586 +       if (IS_TAGGED(in)) {
24587 +               *tag = in->i_tag;
24588 +               *mask |= IATTR_TAG;
24589 +       }
24590 +
24591 +       switch (in->i_sb->s_magic) {
24592 +       case PROC_SUPER_MAGIC:
24593 +               entry = PROC_I(in)->pde;
24594 +
24595 +               /* check for specific inodes? */
24596 +               if (entry)
24597 +                       *mask |= IATTR_FLAGS;
24598 +               if (entry)
24599 +                       *flags |= (entry->vx_flags & IATTR_FLAGS);
24600 +               else
24601 +                       *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS);
24602 +               break;
24603 +
24604 +       case DEVPTS_SUPER_MAGIC:
24605 +               *tag = in->i_tag;
24606 +               *mask |= IATTR_TAG;
24607 +               break;
24608 +
24609 +       default:
24610 +               break;
24611 +       }
24612 +       return 0;
24613 +}
24614 +
24615 +int vc_get_iattr(uint32_t id, void __user *data)
24616 +{
24617 +       struct nameidata nd;
24618 +       struct vcmd_ctx_iattr_v1 vc_data = { .xid = -1 };
24619 +       int ret;
24620 +
24621 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24622 +               return -EFAULT;
24623 +
24624 +       ret = user_path_walk_link(vc_data.name, &nd);
24625 +       if (!ret) {
24626 +               ret = __vc_get_iattr(nd.dentry->d_inode,
24627 +                       &vc_data.xid, &vc_data.flags, &vc_data.mask);
24628 +               path_release(&nd);
24629 +       }
24630 +       if (ret)
24631 +               return ret;
24632 +
24633 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24634 +               ret = -EFAULT;
24635 +       return ret;
24636 +}
24637 +
24638 +#ifdef CONFIG_COMPAT
24639 +
24640 +int vc_get_iattr_x32(uint32_t id, void __user *data)
24641 +{
24642 +       struct nameidata nd;
24643 +       struct vcmd_ctx_iattr_v1_x32 vc_data = { .xid = -1 };
24644 +       int ret;
24645 +
24646 +       if (!vx_check(0, VS_ADMIN))
24647 +               return -ENOSYS;
24648 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24649 +               return -EFAULT;
24650 +
24651 +       ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
24652 +       if (!ret) {
24653 +               ret = __vc_get_iattr(nd.dentry->d_inode,
24654 +                       &vc_data.xid, &vc_data.flags, &vc_data.mask);
24655 +               path_release(&nd);
24656 +       }
24657 +       if (ret)
24658 +               return ret;
24659 +
24660 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24661 +               ret = -EFAULT;
24662 +       return ret;
24663 +}
24664 +
24665 +#endif /* CONFIG_COMPAT */
24666 +
24667 +
24668 +static int __vc_set_iattr(struct dentry *de, uint32_t *tag, uint32_t *flags, uint32_t *mask)
24669 +{
24670 +       struct inode *in = de->d_inode;
24671 +       int error = 0, is_proc = 0, has_tag = 0;
24672 +       struct iattr attr = { 0 };
24673 +
24674 +       if (!in || !in->i_sb)
24675 +               return -ESRCH;
24676 +
24677 +       is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC);
24678 +       if ((*mask & IATTR_FLAGS) && !is_proc)
24679 +               return -EINVAL;
24680 +
24681 +       has_tag = IS_TAGGED(in) ||
24682 +               (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
24683 +       if ((*mask & IATTR_TAG) && !has_tag)
24684 +               return -EINVAL;
24685 +
24686 +       mutex_lock(&in->i_mutex);
24687 +       if (*mask & IATTR_TAG) {
24688 +               attr.ia_tag = *tag;
24689 +               attr.ia_valid |= ATTR_TAG;
24690 +       }
24691 +
24692 +       if (*mask & IATTR_FLAGS) {
24693 +               struct proc_dir_entry *entry = PROC_I(in)->pde;
24694 +               unsigned int iflags = PROC_I(in)->vx_flags;
24695 +
24696 +               iflags = (iflags & ~(*mask & IATTR_FLAGS))
24697 +                       | (*flags & IATTR_FLAGS);
24698 +               PROC_I(in)->vx_flags = iflags;
24699 +               if (entry)
24700 +                       entry->vx_flags = iflags;
24701 +       }
24702 +
24703 +       if (*mask & (IATTR_BARRIER | IATTR_IUNLINK | IATTR_IMMUTABLE)) {
24704 +               if (*mask & IATTR_IMMUTABLE) {
24705 +                       if (*flags & IATTR_IMMUTABLE)
24706 +                               in->i_flags |= S_IMMUTABLE;
24707 +                       else
24708 +                               in->i_flags &= ~S_IMMUTABLE;
24709 +               }
24710 +               if (*mask & IATTR_IUNLINK) {
24711 +                       if (*flags & IATTR_IUNLINK)
24712 +                               in->i_flags |= S_IUNLINK;
24713 +                       else
24714 +                               in->i_flags &= ~S_IUNLINK;
24715 +               }
24716 +               if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
24717 +                       if (*flags & IATTR_BARRIER)
24718 +                               in->i_flags |= S_BARRIER;
24719 +                       else
24720 +                               in->i_flags &= ~S_BARRIER;
24721 +               }
24722 +               if (in->i_op && in->i_op->sync_flags) {
24723 +                       error = in->i_op->sync_flags(in);
24724 +                       if (error)
24725 +                               goto out;
24726 +               }
24727 +       }
24728 +
24729 +       if (attr.ia_valid) {
24730 +               if (in->i_op && in->i_op->setattr)
24731 +                       error = in->i_op->setattr(de, &attr);
24732 +               else {
24733 +                       error = inode_change_ok(in, &attr);
24734 +                       if (!error)
24735 +                               error = inode_setattr(in, &attr);
24736 +               }
24737 +       }
24738 +
24739 +out:
24740 +       mutex_unlock(&in->i_mutex);
24741 +       return error;
24742 +}
24743 +
24744 +int vc_set_iattr(uint32_t id, void __user *data)
24745 +{
24746 +       struct nameidata nd;
24747 +       struct vcmd_ctx_iattr_v1 vc_data;
24748 +       int ret;
24749 +
24750 +       if (!capable(CAP_LINUX_IMMUTABLE))
24751 +               return -EPERM;
24752 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24753 +               return -EFAULT;
24754 +
24755 +       ret = user_path_walk_link(vc_data.name, &nd);
24756 +       if (!ret) {
24757 +               ret = __vc_set_iattr(nd.dentry,
24758 +                       &vc_data.xid, &vc_data.flags, &vc_data.mask);
24759 +               path_release(&nd);
24760 +       }
24761 +
24762 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24763 +               ret = -EFAULT;
24764 +       return ret;
24765 +}
24766 +
24767 +#ifdef CONFIG_COMPAT
24768 +
24769 +int vc_set_iattr_x32(uint32_t id, void __user *data)
24770 +{
24771 +       struct nameidata nd;
24772 +       struct vcmd_ctx_iattr_v1_x32 vc_data;
24773 +       int ret;
24774 +
24775 +       if (!capable(CAP_LINUX_IMMUTABLE))
24776 +               return -EPERM;
24777 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24778 +               return -EFAULT;
24779 +
24780 +       ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
24781 +       if (!ret) {
24782 +               ret = __vc_set_iattr(nd.dentry,
24783 +                       &vc_data.xid, &vc_data.flags, &vc_data.mask);
24784 +               path_release(&nd);
24785 +       }
24786 +
24787 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24788 +               ret = -EFAULT;
24789 +       return ret;
24790 +}
24791 +
24792 +#endif /* CONFIG_COMPAT */
24793 +
24794 +
24795 +#ifdef CONFIG_PROPAGATE
24796 +
24797 +int dx_parse_tag(char *string, tag_t *tag, int remove)
24798 +{
24799 +       static match_table_t tokens = {
24800 +               {1, "tagid=%u"},
24801 +               {0, NULL}
24802 +       };
24803 +       substring_t args[MAX_OPT_ARGS];
24804 +       int token, option = 0;
24805 +
24806 +       if (!string)
24807 +               return 0;
24808 +
24809 +       token = match_token(string, tokens, args);
24810 +       if (token && tag && !match_int(args, &option))
24811 +               *tag = option;
24812 +
24813 +       vxdprintk(VXD_CBIT(tag, 7),
24814 +               "dx_parse_tag(»%s«): %d:#%d",
24815 +               string, token, option);
24816 +
24817 +       if ((token == 1) && remove) {
24818 +               char *p = strstr(string, "tagid=");
24819 +               char *q = p;
24820 +
24821 +               if (p) {
24822 +                       while (*q != '\0' && *q != ',')
24823 +                               q++;
24824 +                       while (*q)
24825 +                               *p++ = *q++;
24826 +                       while (*p)
24827 +                               *p++ = '\0';
24828 +               }
24829 +       }
24830 +       return token;
24831 +}
24832 +
24833 +void __dx_propagate_tag(struct nameidata *nd, struct inode *inode)
24834 +{
24835 +       tag_t new_tag = 0;
24836 +       struct vfsmount *mnt;
24837 +       int propagate;
24838 +
24839 +       if (!nd)
24840 +               return;
24841 +       mnt = nd->mnt;
24842 +       if (!mnt)
24843 +               return;
24844 +
24845 +       propagate = (mnt->mnt_flags & MNT_TAGID);
24846 +       if (propagate)
24847 +               new_tag = mnt->mnt_tag;
24848 +
24849 +       vxdprintk(VXD_CBIT(tag, 7),
24850 +               "dx_propagate_tag(%p[#%lu.%d]): %d,%d",
24851 +               inode, inode->i_ino, inode->i_tag,
24852 +               new_tag, (propagate)?1:0);
24853 +
24854 +       if (propagate)
24855 +               inode->i_tag = new_tag;
24856 +}
24857 +
24858 +#include <linux/module.h>
24859 +
24860 +EXPORT_SYMBOL_GPL(__dx_propagate_tag);
24861 +
24862 +#endif /* CONFIG_PROPAGATE */
24863 +
24864 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/limit.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit.c
24865 --- linux-2.6.19.1/kernel/vserver/limit.c       1970-01-01 01:00:00 +0100
24866 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit.c     2006-11-30 19:32:53 +0100
24867 @@ -0,0 +1,317 @@
24868 +/*
24869 + *  linux/kernel/vserver/limit.c
24870 + *
24871 + *  Virtual Server: Context Limits
24872 + *
24873 + *  Copyright (C) 2004-2006  Herbert Pötzl
24874 + *
24875 + *  V0.01  broken out from vcontext V0.05
24876 + *  V0.02  changed vcmds to vxi arg
24877 + *
24878 + */
24879 +
24880 +#include <linux/module.h>
24881 +#include <linux/vs_context.h>
24882 +#include <linux/vs_limit.h>
24883 +#include <linux/vserver/limit.h>
24884 +#include <linux/vserver/switch.h>
24885 +#include <linux/vserver/limit_cmd.h>
24886 +
24887 +#include <asm/errno.h>
24888 +#include <asm/uaccess.h>
24889 +
24890 +
24891 +const char *vlimit_name[NUM_LIMITS] = {
24892 +       [RLIMIT_CPU]            = "CPU",
24893 +       [RLIMIT_RSS]            = "RSS",
24894 +       [RLIMIT_NPROC]          = "NPROC",
24895 +       [RLIMIT_NOFILE]         = "NOFILE",
24896 +       [RLIMIT_MEMLOCK]        = "VML",
24897 +       [RLIMIT_AS]             = "VM",
24898 +       [RLIMIT_LOCKS]          = "LOCKS",
24899 +       [RLIMIT_SIGPENDING]     = "SIGP",
24900 +       [RLIMIT_MSGQUEUE]       = "MSGQ",
24901 +
24902 +       [VLIMIT_NSOCK]          = "NSOCK",
24903 +       [VLIMIT_OPENFD]         = "OPENFD",
24904 +       [VLIMIT_ANON]           = "ANON",
24905 +       [VLIMIT_SHMEM]          = "SHMEM",
24906 +       [VLIMIT_DENTRY]         = "DENTRY",
24907 +};
24908 +
24909 +EXPORT_SYMBOL_GPL(vlimit_name);
24910 +
24911 +#define MASK_ENTRY(x)  (1 << (x))
24912 +
24913 +const struct vcmd_ctx_rlimit_mask_v0 vlimit_mask = {
24914 +               /* minimum */
24915 +       0
24916 +       ,       /* softlimit */
24917 +       MASK_ENTRY( RLIMIT_RSS          ) |
24918 +       MASK_ENTRY( VLIMIT_ANON         ) |
24919 +       0
24920 +       ,       /* maximum */
24921 +       MASK_ENTRY( RLIMIT_RSS          ) |
24922 +       MASK_ENTRY( RLIMIT_NPROC        ) |
24923 +       MASK_ENTRY( RLIMIT_NOFILE       ) |
24924 +       MASK_ENTRY( RLIMIT_MEMLOCK      ) |
24925 +       MASK_ENTRY( RLIMIT_AS           ) |
24926 +       MASK_ENTRY( RLIMIT_LOCKS        ) |
24927 +       MASK_ENTRY( RLIMIT_MSGQUEUE     ) |
24928 +
24929 +       MASK_ENTRY( VLIMIT_NSOCK        ) |
24930 +       MASK_ENTRY( VLIMIT_OPENFD       ) |
24931 +       MASK_ENTRY( VLIMIT_ANON         ) |
24932 +       MASK_ENTRY( VLIMIT_SHMEM        ) |
24933 +       MASK_ENTRY( VLIMIT_DENTRY       ) |
24934 +       0
24935 +};
24936 +               /* accounting only */
24937 +uint32_t account_mask =
24938 +       MASK_ENTRY( VLIMIT_SEMARY       ) |
24939 +       MASK_ENTRY( VLIMIT_NSEMS        ) |
24940 +       0;
24941 +
24942 +
24943 +static int is_valid_vlimit(int id)
24944 +{
24945 +       uint32_t mask = vlimit_mask.minimum |
24946 +               vlimit_mask.softlimit | vlimit_mask.maximum;
24947 +       return mask & (1 << id);
24948 +}
24949 +
24950 +static int is_accounted_vlimit(int id)
24951 +{
24952 +       if (is_valid_vlimit(id))
24953 +               return 1;
24954 +       return account_mask & (1 << id);
24955 +}
24956 +
24957 +
24958 +static inline uint64_t vc_get_soft(struct vx_info *vxi, int id)
24959 +{
24960 +       rlim_t limit = __rlim_soft(&vxi->limit, id);
24961 +       return VX_VLIM(limit);
24962 +}
24963 +
24964 +static inline uint64_t vc_get_hard(struct vx_info *vxi, int id)
24965 +{
24966 +       rlim_t limit = __rlim_hard(&vxi->limit, id);
24967 +       return VX_VLIM(limit);
24968 +}
24969 +
24970 +static int do_get_rlimit(struct vx_info *vxi, uint32_t id,
24971 +       uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
24972 +{
24973 +       if (!is_valid_vlimit(id))
24974 +               return -EINVAL;
24975 +
24976 +       if (minimum)
24977 +               *minimum = CRLIM_UNSET;
24978 +       if (softlimit)
24979 +               *softlimit = vc_get_soft(vxi, id);
24980 +       if (maximum)
24981 +               *maximum = vc_get_hard(vxi, id);
24982 +       return 0;
24983 +}
24984 +
24985 +int vc_get_rlimit(struct vx_info *vxi, void __user *data)
24986 +{
24987 +       struct vcmd_ctx_rlimit_v0 vc_data;
24988 +       int ret;
24989 +
24990 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
24991 +               return -EFAULT;
24992 +
24993 +       ret = do_get_rlimit(vxi, vc_data.id,
24994 +               &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
24995 +       if (ret)
24996 +               return ret;
24997 +
24998 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
24999 +               return -EFAULT;
25000 +       return 0;
25001 +}
25002 +
25003 +static int do_set_rlimit(struct vx_info *vxi, uint32_t id,
25004 +       uint64_t minimum, uint64_t softlimit, uint64_t maximum)
25005 +{
25006 +       if (!is_valid_vlimit(id))
25007 +               return -EINVAL;
25008 +
25009 +       if (maximum != CRLIM_KEEP)
25010 +               __rlim_hard(&vxi->limit, id) = VX_RLIM(maximum);
25011 +       if (softlimit != CRLIM_KEEP)
25012 +               __rlim_soft(&vxi->limit, id) = VX_RLIM(softlimit);
25013 +
25014 +       /* clamp soft limit */
25015 +       if (__rlim_soft(&vxi->limit, id) > __rlim_hard(&vxi->limit, id))
25016 +               __rlim_soft(&vxi->limit, id) = __rlim_hard(&vxi->limit, id);
25017 +
25018 +       return 0;
25019 +}
25020 +
25021 +int vc_set_rlimit(struct vx_info *vxi, void __user *data)
25022 +{
25023 +       struct vcmd_ctx_rlimit_v0 vc_data;
25024 +
25025 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25026 +               return -EFAULT;
25027 +
25028 +       return do_set_rlimit(vxi, vc_data.id,
25029 +               vc_data.minimum, vc_data.softlimit, vc_data.maximum);
25030 +}
25031 +
25032 +#ifdef CONFIG_IA32_EMULATION
25033 +
25034 +int vc_set_rlimit_x32(struct vx_info *vxi, void __user *data)
25035 +{
25036 +       struct vcmd_ctx_rlimit_v0_x32 vc_data;
25037 +
25038 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25039 +               return -EFAULT;
25040 +
25041 +       return do_set_rlimit(vxi, vc_data.id,
25042 +               vc_data.minimum, vc_data.softlimit, vc_data.maximum);
25043 +}
25044 +
25045 +int vc_get_rlimit_x32(struct vx_info *vxi, void __user *data)
25046 +{
25047 +       struct vcmd_ctx_rlimit_v0_x32 vc_data;
25048 +       int ret;
25049 +
25050 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25051 +               return -EFAULT;
25052 +
25053 +       ret = do_get_rlimit(vxi, vc_data.id,
25054 +               &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
25055 +       if (ret)
25056 +               return ret;
25057 +
25058 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25059 +               return -EFAULT;
25060 +       return 0;
25061 +}
25062 +
25063 +#endif /* CONFIG_IA32_EMULATION */
25064 +
25065 +
25066 +int vc_get_rlimit_mask(uint32_t id, void __user *data)
25067 +{
25068 +       if (copy_to_user(data, &vlimit_mask, sizeof(vlimit_mask)))
25069 +               return -EFAULT;
25070 +       return 0;
25071 +}
25072 +
25073 +
25074 +static inline void vx_reset_minmax(struct _vx_limit *limit)
25075 +{
25076 +       rlim_t value;
25077 +       int lim;
25078 +
25079 +       for (lim=0; lim<NUM_LIMITS; lim++) {
25080 +               value = __rlim_get(limit, lim);
25081 +               __rlim_rmax(limit, lim) = value;
25082 +               __rlim_rmin(limit, lim) = value;
25083 +       }
25084 +}
25085 +
25086 +
25087 +int vc_reset_minmax(struct vx_info *vxi, void __user *data)
25088 +{
25089 +       vx_reset_minmax(&vxi->limit);
25090 +       return 0;
25091 +}
25092 +
25093 +
25094 +int vc_rlimit_stat(struct vx_info *vxi, void __user *data)
25095 +{
25096 +       struct vcmd_rlimit_stat_v0 vc_data;
25097 +       struct _vx_limit *limit = &vxi->limit;
25098 +       int id;
25099 +
25100 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25101 +               return -EFAULT;
25102 +
25103 +       id = vc_data.id;
25104 +       if (!is_accounted_vlimit(id))
25105 +               return -EINVAL;
25106 +
25107 +       vc_data.hits = atomic_read(&__rlim_lhit(limit, id));
25108 +       vc_data.value = __rlim_get(limit, id);
25109 +       vc_data.minimum = __rlim_rmin(limit, id);
25110 +       vc_data.maximum = __rlim_rmax(limit, id);
25111 +
25112 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25113 +               return -EFAULT;
25114 +       return 0;
25115 +}
25116 +
25117 +
25118 +void vx_vsi_meminfo(struct sysinfo *val)
25119 +{
25120 +       struct vx_info *vxi = current->vx_info;
25121 +       unsigned long totalram, freeram;
25122 +       rlim_t v;
25123 +
25124 +       /* we blindly accept the max */
25125 +       v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
25126 +       totalram = (v != RLIM_INFINITY) ? v : val->totalram;
25127 +
25128 +       /* total minus used equals free */
25129 +       v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
25130 +       freeram = (v < totalram) ? totalram - v : 0;
25131 +
25132 +       val->totalram = totalram;
25133 +       val->freeram = freeram;
25134 +       val->bufferram = 0;
25135 +       val->totalhigh = 0;
25136 +       val->freehigh = 0;
25137 +       return;
25138 +}
25139 +
25140 +void vx_vsi_swapinfo(struct sysinfo *val)
25141 +{
25142 +       struct vx_info *vxi = current->vx_info;
25143 +       unsigned long totalswap, freeswap;
25144 +       rlim_t v, w;
25145 +
25146 +       v = __rlim_soft(&vxi->limit, RLIMIT_RSS);
25147 +       if (v == RLIM_INFINITY) {
25148 +               val->freeswap = val->totalswap;
25149 +               return;
25150 +       }
25151 +
25152 +       /* we blindly accept the max */
25153 +       w = __rlim_hard(&vxi->limit, RLIMIT_RSS);
25154 +       totalswap = (w != RLIM_INFINITY) ? (w - v) : val->totalswap;
25155 +
25156 +       /* currently 'used' swap */
25157 +       w = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
25158 +       w -= (w > v) ? v : w;
25159 +
25160 +       /* total minus used equals free */
25161 +       freeswap = (w < totalswap) ? totalswap - w : 0;
25162 +
25163 +       val->totalswap = totalswap;
25164 +       val->freeswap = freeswap;
25165 +       return;
25166 +}
25167 +
25168 +
25169 +unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm)
25170 +{
25171 +       struct vx_info *vxi = mm->mm_vx_info;
25172 +       unsigned long points;
25173 +       rlim_t v, w;
25174 +
25175 +       if (!vxi)
25176 +               return 0;
25177 +
25178 +       v = __vx_cres_array_fixup(&vxi->limit, VLA_RSS);
25179 +       w = __rlim_soft(&vxi->limit, RLIMIT_RSS);
25180 +       points = (v > w) ? (v - w) : 0;
25181 +
25182 +       return points;
25183 +}
25184 +
25185 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/limit_init.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit_init.h
25186 --- linux-2.6.19.1/kernel/vserver/limit_init.h  1970-01-01 01:00:00 +0100
25187 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit_init.h        2006-11-08 04:57:49 +0100
25188 @@ -0,0 +1,33 @@
25189 +
25190 +
25191 +static inline void vx_info_init_limit(struct _vx_limit *limit)
25192 +{
25193 +       int lim;
25194 +
25195 +       for (lim=0; lim<NUM_LIMITS; lim++) {
25196 +               __rlim_soft(limit, lim) = RLIM_INFINITY;
25197 +               __rlim_hard(limit, lim) = RLIM_INFINITY;
25198 +               __rlim_set(limit, lim, 0);
25199 +               atomic_set(&__rlim_lhit(limit, lim), 0);
25200 +               __rlim_rmin(limit, lim) = 0;
25201 +               __rlim_rmax(limit, lim) = 0;
25202 +       }
25203 +}
25204 +
25205 +static inline void vx_info_exit_limit(struct _vx_limit *limit)
25206 +{
25207 +#ifdef CONFIG_VSERVER_DEBUG
25208 +       rlim_t value;
25209 +       int lim;
25210 +
25211 +       for (lim=0; lim<NUM_LIMITS; lim++) {
25212 +               if ((1 << lim) & VLIM_NOCHECK)
25213 +                       continue;
25214 +               value = __rlim_get(limit, lim);
25215 +               vxwprintk(value,
25216 +                       "!!! limit: %p[%s,%d] = %ld on exit.",
25217 +                       limit, vlimit_name[lim], lim, (long)value);
25218 +       }
25219 +#endif
25220 +}
25221 +
25222 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/limit_proc.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit_proc.h
25223 --- linux-2.6.19.1/kernel/vserver/limit_proc.h  1970-01-01 01:00:00 +0100
25224 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/limit_proc.h        2006-11-30 19:31:41 +0100
25225 @@ -0,0 +1,76 @@
25226 +#ifndef _VX_LIMIT_PROC_H
25227 +#define _VX_LIMIT_PROC_H
25228 +
25229 +#include <linux/vserver/limit_int.h>
25230 +
25231 +static inline void vx_limit_fixup(struct _vx_limit *limit)
25232 +{
25233 +       rlim_t value;
25234 +       int res;
25235 +
25236 +       /* complex resources first */
25237 +       __vx_cres_array_fixup(limit, VLA_RSS);
25238 +
25239 +       for (res=0; res<NUM_LIMITS; res++) {
25240 +               value = __rlim_get(limit, res);
25241 +               __vx_cres_fixup(limit, res, value);
25242 +
25243 +               /* not supposed to happen, maybe warn? */
25244 +               if (__rlim_rmax(limit, res) > __rlim_hard(limit, res))
25245 +                       __rlim_rmax(limit, res) = __rlim_hard(limit, res);
25246 +       }
25247 +}
25248 +
25249 +
25250 +#define VX_LIMIT_FMT   ":\t%8ld\t%8ld/%8ld\t%8lld/%8lld\t%6d\n"
25251 +#define VX_LIMIT_TOP   \
25252 +       "Limit\t current\t     min/max\t\t    soft/hard\t\thits\n"
25253 +
25254 +#define VX_LIMIT_ARG(r)                                \
25255 +       ,(unsigned long)__rlim_get(limit, r)    \
25256 +       ,(unsigned long)__rlim_rmin(limit, r)   \
25257 +       ,(unsigned long)__rlim_rmax(limit, r)   \
25258 +       ,VX_VLIM(__rlim_soft(limit, r))         \
25259 +       ,VX_VLIM(__rlim_hard(limit, r))         \
25260 +       ,atomic_read(&__rlim_lhit(limit, r))
25261 +
25262 +static inline int vx_info_proc_limit(struct _vx_limit *limit, char *buffer)
25263 +{
25264 +       vx_limit_fixup(limit);
25265 +       return sprintf(buffer, VX_LIMIT_TOP
25266 +               "PROC"  VX_LIMIT_FMT
25267 +               "VM"    VX_LIMIT_FMT
25268 +               "VML"   VX_LIMIT_FMT
25269 +               "RSS"   VX_LIMIT_FMT
25270 +               "ANON"  VX_LIMIT_FMT
25271 +               "RMAP"  VX_LIMIT_FMT
25272 +               "FILES" VX_LIMIT_FMT
25273 +               "OFD"   VX_LIMIT_FMT
25274 +               "LOCKS" VX_LIMIT_FMT
25275 +               "SOCK"  VX_LIMIT_FMT
25276 +               "MSGQ"  VX_LIMIT_FMT
25277 +               "SHM"   VX_LIMIT_FMT
25278 +               "SEMA"  VX_LIMIT_FMT
25279 +               "SEMS"  VX_LIMIT_FMT
25280 +               "DENT"  VX_LIMIT_FMT
25281 +               VX_LIMIT_ARG(RLIMIT_NPROC)
25282 +               VX_LIMIT_ARG(RLIMIT_AS)
25283 +               VX_LIMIT_ARG(RLIMIT_MEMLOCK)
25284 +               VX_LIMIT_ARG(RLIMIT_RSS)
25285 +               VX_LIMIT_ARG(VLIMIT_ANON)
25286 +               VX_LIMIT_ARG(VLIMIT_MAPPED)
25287 +               VX_LIMIT_ARG(RLIMIT_NOFILE)
25288 +               VX_LIMIT_ARG(VLIMIT_OPENFD)
25289 +               VX_LIMIT_ARG(RLIMIT_LOCKS)
25290 +               VX_LIMIT_ARG(VLIMIT_NSOCK)
25291 +               VX_LIMIT_ARG(RLIMIT_MSGQUEUE)
25292 +               VX_LIMIT_ARG(VLIMIT_SHMEM)
25293 +               VX_LIMIT_ARG(VLIMIT_SEMARY)
25294 +               VX_LIMIT_ARG(VLIMIT_NSEMS)
25295 +               VX_LIMIT_ARG(VLIMIT_DENTRY)
25296 +               );
25297 +}
25298 +
25299 +#endif /* _VX_LIMIT_PROC_H */
25300 +
25301 +
25302 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/monitor.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/monitor.c
25303 --- linux-2.6.19.1/kernel/vserver/monitor.c     1970-01-01 01:00:00 +0100
25304 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/monitor.c   2006-11-08 04:57:48 +0100
25305 @@ -0,0 +1,142 @@
25306 +/*
25307 + *  kernel/vserver/monitor.c
25308 + *
25309 + *  Virtual Context Scheduler Monitor
25310 + *
25311 + *  Copyright (C) 2006 Herbert Pötzl
25312 + *
25313 + *  V0.01  basic design
25314 + *
25315 + */
25316 +
25317 +#include <linux/errno.h>
25318 +#include <linux/module.h>
25319 +#include <linux/types.h>
25320 +#include <linux/ctype.h>
25321 +
25322 +#include <asm/uaccess.h>
25323 +#include <asm/atomic.h>
25324 +#include <asm/unistd.h>
25325 +
25326 +#include <linux/vserver/monitor.h>
25327 +#include <linux/vserver/debug_cmd.h>
25328 +
25329 +
25330 +#ifdef CONFIG_VSERVER_MONITOR
25331 +#define VXM_SIZE       CONFIG_VSERVER_MONITOR_SIZE
25332 +#else
25333 +#define VXM_SIZE       64
25334 +#endif
25335 +
25336 +struct _vx_monitor {
25337 +       unsigned int counter;
25338 +
25339 +       struct _vx_mon_entry entry[VXM_SIZE+1];
25340 +};
25341 +
25342 +
25343 +DEFINE_PER_CPU(struct _vx_monitor, vx_monitor_buffer);
25344 +
25345 +unsigned volatile int vxm_active = 1;
25346 +
25347 +static atomic_t sequence = ATOMIC_INIT(0);
25348 +
25349 +
25350 +/*     vxm_advance()
25351 +
25352 +       * requires disabled preemption                          */
25353 +
25354 +struct _vx_mon_entry *vxm_advance(int cpu)
25355 +{
25356 +       struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu);
25357 +       struct _vx_mon_entry *entry;
25358 +       unsigned int index;
25359 +
25360 +       index = vxm_active ? (mon->counter++ % VXM_SIZE) : VXM_SIZE;
25361 +       entry = &mon->entry[index];
25362 +
25363 +       entry->ev.seq = atomic_inc_return(&sequence);
25364 +       entry->ev.jif = jiffies;
25365 +       return entry;
25366 +}
25367 +
25368 +EXPORT_SYMBOL_GPL(vxm_advance);
25369 +
25370 +
25371 +int do_read_monitor(struct __user _vx_mon_entry *data,
25372 +       int cpu, uint32_t *index, uint32_t *count)
25373 +{
25374 +       int pos, ret = 0;
25375 +       struct _vx_monitor *mon = &per_cpu(vx_monitor_buffer, cpu);
25376 +       int end = mon->counter;
25377 +       int start = end - VXM_SIZE + 2;
25378 +       int idx = *index;
25379 +
25380 +       /* special case: get current pos */
25381 +       if (!*count) {
25382 +               *index = end;
25383 +               return 0;
25384 +       }
25385 +
25386 +       /* have we lost some data? */
25387 +       if (idx < start)
25388 +               idx = start;
25389 +
25390 +       for (pos = 0; (pos < *count) && (idx < end); pos++, idx++) {
25391 +               struct _vx_mon_entry *entry =
25392 +                       &mon->entry[idx % VXM_SIZE];
25393 +
25394 +               /* send entry to userspace */
25395 +               ret = copy_to_user (&data[pos], entry, sizeof(*entry));
25396 +               if (ret)
25397 +                       break;
25398 +       }
25399 +       /* save new index and count */
25400 +       *index = idx;
25401 +       *count = pos;
25402 +       return ret ? ret : (*index < end);
25403 +}
25404 +
25405 +int vc_read_monitor(uint32_t id, void __user *data)
25406 +{
25407 +       struct vcmd_read_monitor_v0 vc_data;
25408 +       int ret;
25409 +
25410 +       if (id >= NR_CPUS)
25411 +               return -EINVAL;
25412 +
25413 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25414 +               return -EFAULT;
25415 +
25416 +       ret = do_read_monitor((struct __user _vx_mon_entry *)vc_data.data,
25417 +               id, &vc_data.index, &vc_data.count);
25418 +
25419 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25420 +               return -EFAULT;
25421 +       return ret;
25422 +}
25423 +
25424 +#ifdef CONFIG_COMPAT
25425 +
25426 +int vc_read_monitor_x32(uint32_t id, void __user *data)
25427 +{
25428 +       struct vcmd_read_monitor_v0_x32 vc_data;
25429 +       int ret;
25430 +
25431 +       if (id >= NR_CPUS)
25432 +               return -EINVAL;
25433 +
25434 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
25435 +               return -EFAULT;
25436 +
25437 +       ret = do_read_monitor((struct __user _vx_mon_entry *)
25438 +               compat_ptr(vc_data.data_ptr),
25439 +               id, &vc_data.index, &vc_data.count);
25440 +
25441 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25442 +               return -EFAULT;
25443 +       return ret;
25444 +}
25445 +
25446 +#endif /* CONFIG_COMPAT */
25447 +
25448 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/network.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/network.c
25449 --- linux-2.6.19.1/kernel/vserver/network.c     1970-01-01 01:00:00 +0100
25450 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/network.c   2006-12-17 05:38:36 +0100
25451 @@ -0,0 +1,626 @@
25452 +/*
25453 + *  linux/kernel/vserver/network.c
25454 + *
25455 + *  Virtual Server: Network Support
25456 + *
25457 + *  Copyright (C) 2003-2006  Herbert Pötzl
25458 + *
25459 + *  V0.01  broken out from vcontext V0.05
25460 + *  V0.02  cleaned up implementation
25461 + *  V0.03  added equiv nx commands
25462 + *  V0.04  switch to RCU based hash
25463 + *  V0.05  and back to locking again
25464 + *  V0.06  changed vcmds to nxi arg
25465 + *
25466 + */
25467 +
25468 +#include <linux/slab.h>
25469 +#include <linux/rcupdate.h>
25470 +#include <net/tcp.h>
25471 +
25472 +#include <asm/errno.h>
25473 +#include <linux/vserver/base.h>
25474 +#include <linux/vserver/network_cmd.h>
25475 +
25476 +
25477 +atomic_t nx_global_ctotal      = ATOMIC_INIT(0);
25478 +atomic_t nx_global_cactive     = ATOMIC_INIT(0);
25479 +
25480 +
25481 +/*     __alloc_nx_info()
25482 +
25483 +       * allocate an initialized nx_info struct
25484 +       * doesn't make it visible (hash)                        */
25485 +
25486 +static struct nx_info *__alloc_nx_info(nid_t nid)
25487 +{
25488 +       struct nx_info *new = NULL;
25489 +
25490 +       vxdprintk(VXD_CBIT(nid, 1), "alloc_nx_info(%d)*", nid);
25491 +
25492 +       /* would this benefit from a slab cache? */
25493 +       new = kmalloc(sizeof(struct nx_info), GFP_KERNEL);
25494 +       if (!new)
25495 +               return 0;
25496 +
25497 +       memset (new, 0, sizeof(struct nx_info));
25498 +       new->nx_id = nid;
25499 +       INIT_HLIST_NODE(&new->nx_hlist);
25500 +       atomic_set(&new->nx_usecnt, 0);
25501 +       atomic_set(&new->nx_tasks, 0);
25502 +       new->nx_state = 0;
25503 +
25504 +       new->nx_flags = NXF_INIT_SET;
25505 +
25506 +       /* rest of init goes here */
25507 +
25508 +       vxdprintk(VXD_CBIT(nid, 0),
25509 +               "alloc_nx_info(%d) = %p", nid, new);
25510 +       atomic_inc(&nx_global_ctotal);
25511 +       return new;
25512 +}
25513 +
25514 +/*     __dealloc_nx_info()
25515 +
25516 +       * final disposal of nx_info                             */
25517 +
25518 +static void __dealloc_nx_info(struct nx_info *nxi)
25519 +{
25520 +       vxdprintk(VXD_CBIT(nid, 0),
25521 +               "dealloc_nx_info(%p)", nxi);
25522 +
25523 +       nxi->nx_hlist.next = LIST_POISON1;
25524 +       nxi->nx_id = -1;
25525 +
25526 +       BUG_ON(atomic_read(&nxi->nx_usecnt));
25527 +       BUG_ON(atomic_read(&nxi->nx_tasks));
25528 +
25529 +       nxi->nx_state |= NXS_RELEASED;
25530 +       kfree(nxi);
25531 +       atomic_dec(&nx_global_ctotal);
25532 +}
25533 +
25534 +static void __shutdown_nx_info(struct nx_info *nxi)
25535 +{
25536 +       nxi->nx_state |= NXS_SHUTDOWN;
25537 +       vs_net_change(nxi, VSC_NETDOWN);
25538 +}
25539 +
25540 +/*     exported stuff                                          */
25541 +
25542 +void free_nx_info(struct nx_info *nxi)
25543 +{
25544 +       /* context shutdown is mandatory */
25545 +       BUG_ON(nxi->nx_state != NXS_SHUTDOWN);
25546 +
25547 +       /* context must not be hashed */
25548 +       BUG_ON(nxi->nx_state & NXS_HASHED);
25549 +
25550 +       BUG_ON(atomic_read(&nxi->nx_usecnt));
25551 +       BUG_ON(atomic_read(&nxi->nx_tasks));
25552 +
25553 +       __dealloc_nx_info(nxi);
25554 +}
25555 +
25556 +
25557 +void __nx_set_lback(struct nx_info *nxi)
25558 +{
25559 +       int nid = nxi->nx_id;
25560 +       uint32_t lback = htonl(INADDR_LOOPBACK ^ ((nid & 0xFFFF) << 8));
25561 +
25562 +       nxi->v4_lback = lback;
25563 +}
25564 +
25565 +
25566 +/*     hash table for nx_info hash */
25567 +
25568 +#define NX_HASH_SIZE   13
25569 +
25570 +struct hlist_head nx_info_hash[NX_HASH_SIZE];
25571 +
25572 +static spinlock_t nx_info_hash_lock = SPIN_LOCK_UNLOCKED;
25573 +
25574 +
25575 +static inline unsigned int __hashval(nid_t nid)
25576 +{
25577 +       return (nid % NX_HASH_SIZE);
25578 +}
25579 +
25580 +
25581 +
25582 +/*     __hash_nx_info()
25583 +
25584 +       * add the nxi to the global hash table
25585 +       * requires the hash_lock to be held                     */
25586 +
25587 +static inline void __hash_nx_info(struct nx_info *nxi)
25588 +{
25589 +       struct hlist_head *head;
25590 +
25591 +       vxd_assert_lock(&nx_info_hash_lock);
25592 +       vxdprintk(VXD_CBIT(nid, 4),
25593 +               "__hash_nx_info: %p[#%d]", nxi, nxi->nx_id);
25594 +
25595 +       /* context must not be hashed */
25596 +       BUG_ON(nx_info_state(nxi, NXS_HASHED));
25597 +
25598 +       nxi->nx_state |= NXS_HASHED;
25599 +       head = &nx_info_hash[__hashval(nxi->nx_id)];
25600 +       hlist_add_head(&nxi->nx_hlist, head);
25601 +       atomic_inc(&nx_global_cactive);
25602 +}
25603 +
25604 +/*     __unhash_nx_info()
25605 +
25606 +       * remove the nxi from the global hash table
25607 +       * requires the hash_lock to be held                     */
25608 +
25609 +static inline void __unhash_nx_info(struct nx_info *nxi)
25610 +{
25611 +       vxd_assert_lock(&nx_info_hash_lock);
25612 +       vxdprintk(VXD_CBIT(nid, 4),
25613 +               "__unhash_nx_info: %p[#%d]", nxi, nxi->nx_id);
25614 +
25615 +       /* context must be hashed */
25616 +       BUG_ON(!nx_info_state(nxi, NXS_HASHED));
25617 +
25618 +       nxi->nx_state &= ~NXS_HASHED;
25619 +       hlist_del(&nxi->nx_hlist);
25620 +       atomic_dec(&nx_global_cactive);
25621 +}
25622 +
25623 +
25624 +/*     __lookup_nx_info()
25625 +
25626 +       * requires the hash_lock to be held
25627 +       * doesn't increment the nx_refcnt                       */
25628 +
25629 +static inline struct nx_info *__lookup_nx_info(nid_t nid)
25630 +{
25631 +       struct hlist_head *head = &nx_info_hash[__hashval(nid)];
25632 +       struct hlist_node *pos;
25633 +       struct nx_info *nxi;
25634 +
25635 +       vxd_assert_lock(&nx_info_hash_lock);
25636 +       hlist_for_each(pos, head) {
25637 +               nxi = hlist_entry(pos, struct nx_info, nx_hlist);
25638 +
25639 +               if (nxi->nx_id == nid)
25640 +                       goto found;
25641 +       }
25642 +       nxi = NULL;
25643 +found:
25644 +       vxdprintk(VXD_CBIT(nid, 0),
25645 +               "__lookup_nx_info(#%u): %p[#%u]",
25646 +               nid, nxi, nxi?nxi->nx_id:0);
25647 +       return nxi;
25648 +}
25649 +
25650 +
25651 +/*     __create_nx_info()
25652 +
25653 +       * create the requested context
25654 +       * get() and hash it                                     */
25655 +
25656 +static struct nx_info * __create_nx_info(int id)
25657 +{
25658 +       struct nx_info *new, *nxi = NULL;
25659 +
25660 +       vxdprintk(VXD_CBIT(nid, 1), "create_nx_info(%d)*", id);
25661 +
25662 +       if (!(new = __alloc_nx_info(id)))
25663 +               return ERR_PTR(-ENOMEM);
25664 +
25665 +       /* required to make dynamic xids unique */
25666 +       spin_lock(&nx_info_hash_lock);
25667 +
25668 +       /* static context requested */
25669 +       if ((nxi = __lookup_nx_info(id))) {
25670 +               vxdprintk(VXD_CBIT(nid, 0),
25671 +                       "create_nx_info(%d) = %p (already there)", id, nxi);
25672 +               if (nx_info_flags(nxi, NXF_STATE_SETUP, 0))
25673 +                       nxi = ERR_PTR(-EBUSY);
25674 +               else
25675 +                       nxi = ERR_PTR(-EEXIST);
25676 +               goto out_unlock;
25677 +       }
25678 +       /* new context */
25679 +       vxdprintk(VXD_CBIT(nid, 0),
25680 +               "create_nx_info(%d) = %p (new)", id, new);
25681 +       __hash_nx_info(get_nx_info(new));
25682 +       nxi = new, new = NULL;
25683 +
25684 +out_unlock:
25685 +       spin_unlock(&nx_info_hash_lock);
25686 +       if (new)
25687 +               __dealloc_nx_info(new);
25688 +       return nxi;
25689 +}
25690 +
25691 +
25692 +
25693 +/*     exported stuff                                          */
25694 +
25695 +
25696 +void unhash_nx_info(struct nx_info *nxi)
25697 +{
25698 +       __shutdown_nx_info(nxi);
25699 +       spin_lock(&nx_info_hash_lock);
25700 +       __unhash_nx_info(nxi);
25701 +       spin_unlock(&nx_info_hash_lock);
25702 +}
25703 +
25704 +
25705 +/*     lookup_nx_info()
25706 +
25707 +       * search for a nx_info and get() it
25708 +       * negative id means current                             */
25709 +
25710 +struct nx_info *lookup_nx_info(int id)
25711 +{
25712 +       struct nx_info *nxi = NULL;
25713 +
25714 +       if (id < 0) {
25715 +               nxi = get_nx_info(current->nx_info);
25716 +       } else if (id > 1) {
25717 +               spin_lock(&nx_info_hash_lock);
25718 +               nxi = get_nx_info(__lookup_nx_info(id));
25719 +               spin_unlock(&nx_info_hash_lock);
25720 +       }
25721 +       return nxi;
25722 +}
25723 +
25724 +/*     nid_is_hashed()
25725 +
25726 +       * verify that nid is still hashed                       */
25727 +
25728 +int nid_is_hashed(nid_t nid)
25729 +{
25730 +       int hashed;
25731 +
25732 +       spin_lock(&nx_info_hash_lock);
25733 +       hashed = (__lookup_nx_info(nid) != NULL);
25734 +       spin_unlock(&nx_info_hash_lock);
25735 +       return hashed;
25736 +}
25737 +
25738 +
25739 +#ifdef CONFIG_PROC_FS
25740 +
25741 +/*     get_nid_list()
25742 +
25743 +       * get a subset of hashed nids for proc
25744 +       * assumes size is at least one                          */
25745 +
25746 +int get_nid_list(int index, unsigned int *nids, int size)
25747 +{
25748 +       int hindex, nr_nids = 0;
25749 +
25750 +       /* only show current and children */
25751 +       if (!nx_check(0, VS_ADMIN|VS_WATCH)) {
25752 +               if (index > 0)
25753 +                       return 0;
25754 +               nids[nr_nids] = nx_current_nid();
25755 +               return 1;
25756 +       }
25757 +
25758 +       for (hindex = 0; hindex < NX_HASH_SIZE; hindex++) {
25759 +               struct hlist_head *head = &nx_info_hash[hindex];
25760 +               struct hlist_node *pos;
25761 +
25762 +               spin_lock(&nx_info_hash_lock);
25763 +               hlist_for_each(pos, head) {
25764 +                       struct nx_info *nxi;
25765 +
25766 +                       if (--index > 0)
25767 +                               continue;
25768 +
25769 +                       nxi = hlist_entry(pos, struct nx_info, nx_hlist);
25770 +                       nids[nr_nids] = nxi->nx_id;
25771 +                       if (++nr_nids >= size) {
25772 +                               spin_unlock(&nx_info_hash_lock);
25773 +                               goto out;
25774 +                       }
25775 +               }
25776 +               /* keep the lock time short */
25777 +               spin_unlock(&nx_info_hash_lock);
25778 +       }
25779 +out:
25780 +       return nr_nids;
25781 +}
25782 +#endif
25783 +
25784 +
25785 +/*
25786 + *     migrate task to new network
25787 + *     gets nxi, puts old_nxi on change
25788 + */
25789 +
25790 +int nx_migrate_task(struct task_struct *p, struct nx_info *nxi)
25791 +{
25792 +       struct nx_info *old_nxi;
25793 +       int ret = 0;
25794 +
25795 +       if (!p || !nxi)
25796 +               BUG();
25797 +
25798 +       vxdprintk(VXD_CBIT(nid, 5),
25799 +               "nx_migrate_task(%p,%p[#%d.%d.%d])",
25800 +               p, nxi, nxi->nx_id,
25801 +               atomic_read(&nxi->nx_usecnt),
25802 +               atomic_read(&nxi->nx_tasks));
25803 +
25804 +       if (nx_info_flags(nxi, NXF_INFO_PRIVATE, 0) &&
25805 +               !nx_info_flags(nxi, NXF_STATE_SETUP, 0))
25806 +               return -EACCES;
25807 +
25808 +       /* maybe disallow this completely? */
25809 +       old_nxi = task_get_nx_info(p);
25810 +       if (old_nxi == nxi)
25811 +               goto out;
25812 +
25813 +       task_lock(p);
25814 +       if (old_nxi)
25815 +               clr_nx_info(&p->nx_info);
25816 +       claim_nx_info(nxi, p);
25817 +       set_nx_info(&p->nx_info, nxi);
25818 +       p->nid = nxi->nx_id;
25819 +       task_unlock(p);
25820 +
25821 +       vxdprintk(VXD_CBIT(nid, 5),
25822 +               "moved task %p into nxi:%p[#%d]",
25823 +               p, nxi, nxi->nx_id);
25824 +
25825 +       if (old_nxi)
25826 +               release_nx_info(old_nxi, p);
25827 +       ret = 0;
25828 +out:
25829 +       put_nx_info(old_nxi);
25830 +       return ret;
25831 +}
25832 +
25833 +
25834 +void nx_set_persistent(struct nx_info *nxi)
25835 +{
25836 +       get_nx_info(nxi);
25837 +       claim_nx_info(nxi, current);
25838 +}
25839 +
25840 +void nx_clear_persistent(struct nx_info *nxi)
25841 +{
25842 +       vxdprintk(VXD_CBIT(nid, 6),
25843 +               "nx_clear_persistent(%p[#%d])", nxi, nxi->nx_id);
25844 +
25845 +       release_nx_info(nxi, current);
25846 +       put_nx_info(nxi);
25847 +}
25848 +
25849 +void nx_update_persistent(struct nx_info *nxi)
25850 +{
25851 +       if (nx_info_flags(nxi, NXF_PERSISTENT, 0))
25852 +               nx_set_persistent(nxi);
25853 +       else
25854 +               nx_clear_persistent(nxi);
25855 +}
25856 +
25857 +/* vserver syscall commands below here */
25858 +
25859 +/* taks nid and nx_info functions */
25860 +
25861 +#include <asm/uaccess.h>
25862 +
25863 +
25864 +int vc_task_nid(uint32_t id, void __user *data)
25865 +{
25866 +       nid_t nid;
25867 +
25868 +       if (id) {
25869 +               struct task_struct *tsk;
25870 +
25871 +               if (!vx_check(0, VS_ADMIN|VS_WATCH))
25872 +                       return -EPERM;
25873 +
25874 +               read_lock(&tasklist_lock);
25875 +               tsk = find_task_by_real_pid(id);
25876 +               nid = (tsk) ? tsk->nid : -ESRCH;
25877 +               read_unlock(&tasklist_lock);
25878 +       }
25879 +       else
25880 +               nid = nx_current_nid();
25881 +       return nid;
25882 +}
25883 +
25884 +
25885 +int vc_nx_info(struct nx_info *nxi, void __user *data)
25886 +{
25887 +       struct vcmd_nx_info_v0 vc_data;
25888 +
25889 +       vc_data.nid = nxi->nx_id;
25890 +
25891 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
25892 +               return -EFAULT;
25893 +       return 0;
25894 +}
25895 +
25896 +
25897 +/* network functions */
25898 +
25899 +int vc_net_create(uint32_t nid, void __user *data)
25900 +{
25901 +       struct vcmd_net_create vc_data = { .flagword = NXF_INIT_SET };
25902 +       struct nx_info *new_nxi;
25903 +       int ret;
25904 +
25905 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
25906 +               return -EFAULT;
25907 +
25908 +       if ((nid > MAX_S_CONTEXT) || (nid < 2))
25909 +               return -EINVAL;
25910 +
25911 +       new_nxi = __create_nx_info(nid);
25912 +       if (IS_ERR(new_nxi))
25913 +               return PTR_ERR(new_nxi);
25914 +
25915 +       /* initial flags */
25916 +       new_nxi->nx_flags = vc_data.flagword;
25917 +
25918 +       /* get a reference for persistent contexts */
25919 +       if ((vc_data.flagword & NXF_PERSISTENT))
25920 +               nx_set_persistent(new_nxi);
25921 +
25922 +       ret = -ENOEXEC;
25923 +       if (vs_net_change(new_nxi, VSC_NETUP))
25924 +               goto out_unhash;
25925 +       ret = nx_migrate_task(current, new_nxi);
25926 +       if (!ret) {
25927 +               /* return context id on success */
25928 +               ret = new_nxi->nx_id;
25929 +               goto out;
25930 +       }
25931 +out_unhash:
25932 +       /* prepare for context disposal */
25933 +       new_nxi->nx_state |= NXS_SHUTDOWN;
25934 +       if ((vc_data.flagword & NXF_PERSISTENT))
25935 +               nx_clear_persistent(new_nxi);
25936 +       __unhash_nx_info(new_nxi);
25937 +out:
25938 +       put_nx_info(new_nxi);
25939 +       return ret;
25940 +}
25941 +
25942 +
25943 +int vc_net_migrate(struct nx_info *nxi, void __user *data)
25944 +{
25945 +       return nx_migrate_task(current, nxi);
25946 +}
25947 +
25948 +int vc_net_add(struct nx_info *nxi, void __user *data)
25949 +{
25950 +       struct vcmd_net_addr_v0 vc_data;
25951 +       int index, pos, ret = 0;
25952 +
25953 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
25954 +               return -EFAULT;
25955 +
25956 +       switch (vc_data.type) {
25957 +       case NXA_TYPE_IPV4:
25958 +               if ((vc_data.count < 1) || (vc_data.count > 4))
25959 +                       return -EINVAL;
25960 +               break;
25961 +
25962 +       default:
25963 +               break;
25964 +       }
25965 +
25966 +       switch (vc_data.type) {
25967 +       case NXA_TYPE_IPV4:
25968 +               index = 0;
25969 +               while ((index < vc_data.count) &&
25970 +                       ((pos = nxi->nbipv4) < NB_IPV4ROOT)) {
25971 +                       nxi->ipv4[pos] = vc_data.ip[index].s_addr;
25972 +                       nxi->mask[pos] = vc_data.mask[index].s_addr;
25973 +                       index++;
25974 +                       nxi->nbipv4++;
25975 +               }
25976 +               ret = index;
25977 +               break;
25978 +
25979 +       case NXA_TYPE_IPV4|NXA_MOD_BCAST:
25980 +               nxi->v4_bcast = vc_data.ip[0].s_addr;
25981 +               ret = 1;
25982 +               break;
25983 +
25984 +       case NXA_TYPE_IPV4|NXA_MOD_LBACK:
25985 +               nxi->v4_lback = vc_data.ip[0].s_addr;
25986 +               ret = 1;
25987 +               break;
25988 +
25989 +       default:
25990 +               ret = -EINVAL;
25991 +               break;
25992 +       }
25993 +       return ret;
25994 +}
25995 +
25996 +int vc_net_remove(struct nx_info * nxi, void __user *data)
25997 +{
25998 +       struct vcmd_net_addr_v0 vc_data;
25999 +
26000 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
26001 +               return -EFAULT;
26002 +
26003 +       switch (vc_data.type) {
26004 +       case NXA_TYPE_ANY:
26005 +               nxi->nbipv4 = 0;
26006 +               break;
26007 +
26008 +       default:
26009 +               return -EINVAL;
26010 +       }
26011 +       return 0;
26012 +}
26013 +
26014 +int vc_get_nflags(struct nx_info *nxi, void __user *data)
26015 +{
26016 +       struct vcmd_net_flags_v0 vc_data;
26017 +
26018 +       vc_data.flagword = nxi->nx_flags;
26019 +
26020 +       /* special STATE flag handling */
26021 +       vc_data.mask = vs_mask_flags(~0UL, nxi->nx_flags, NXF_ONE_TIME);
26022 +
26023 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
26024 +               return -EFAULT;
26025 +       return 0;
26026 +}
26027 +
26028 +int vc_set_nflags(struct nx_info *nxi, void __user *data)
26029 +{
26030 +       struct vcmd_net_flags_v0 vc_data;
26031 +       uint64_t mask, trigger;
26032 +
26033 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
26034 +               return -EFAULT;
26035 +
26036 +       /* special STATE flag handling */
26037 +       mask = vs_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME);
26038 +       trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword);
26039 +
26040 +       nxi->nx_flags = vs_mask_flags(nxi->nx_flags,
26041 +               vc_data.flagword, mask);
26042 +       if (trigger & NXF_PERSISTENT)
26043 +               nx_update_persistent(nxi);
26044 +
26045 +       return 0;
26046 +}
26047 +
26048 +int vc_get_ncaps(struct nx_info *nxi, void __user *data)
26049 +{
26050 +       struct vcmd_net_caps_v0 vc_data;
26051 +
26052 +       vc_data.ncaps = nxi->nx_ncaps;
26053 +       vc_data.cmask = ~0UL;
26054 +
26055 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
26056 +               return -EFAULT;
26057 +       return 0;
26058 +}
26059 +
26060 +int vc_set_ncaps(struct nx_info *nxi, void __user *data)
26061 +{
26062 +       struct vcmd_net_caps_v0 vc_data;
26063 +
26064 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
26065 +               return -EFAULT;
26066 +
26067 +       nxi->nx_ncaps = vs_mask_flags(nxi->nx_ncaps,
26068 +               vc_data.ncaps, vc_data.cmask);
26069 +       return 0;
26070 +}
26071 +
26072 +
26073 +#include <linux/module.h>
26074 +
26075 +EXPORT_SYMBOL_GPL(free_nx_info);
26076 +EXPORT_SYMBOL_GPL(unhash_nx_info);
26077 +
26078 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/proc.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/proc.c
26079 --- linux-2.6.19.1/kernel/vserver/proc.c        1970-01-01 01:00:00 +0100
26080 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/proc.c      2006-12-17 03:23:33 +0100
26081 @@ -0,0 +1,1009 @@
26082 +/*
26083 + *  linux/kernel/vserver/proc.c
26084 + *
26085 + *  Virtual Context Support
26086 + *
26087 + *  Copyright (C) 2003-2006  Herbert Pötzl
26088 + *
26089 + *  V0.01  basic structure
26090 + *  V0.02  adaptation vs1.3.0
26091 + *  V0.03  proc permissions
26092 + *  V0.04  locking/generic
26093 + *  V0.05  next generation procfs
26094 + *  V0.06  inode validation
26095 + *  V0.07  generic rewrite vid
26096 + *  V0.08  remove inode type
26097 + *
26098 + */
26099 +
26100 +#include <linux/errno.h>
26101 +#include <linux/proc_fs.h>
26102 +#include <linux/sched.h>
26103 +#include <linux/vs_context.h>
26104 +#include <linux/vs_network.h>
26105 +#include <linux/vs_cvirt.h>
26106 +
26107 +#include <linux/vserver/switch.h>
26108 +#include <linux/vserver/global.h>
26109 +
26110 +#include <asm/uaccess.h>
26111 +#include <asm/unistd.h>
26112 +
26113 +#include "cvirt_proc.h"
26114 +#include "cacct_proc.h"
26115 +#include "limit_proc.h"
26116 +#include "sched_proc.h"
26117 +#include "vci_config.h"
26118 +
26119 +static struct proc_dir_entry *proc_virtual;
26120 +
26121 +static struct proc_dir_entry *proc_virtnet;
26122 +
26123 +
26124 +
26125 +// #define PROC_VID_MASK       0x60
26126 +
26127 +
26128 +/* first the actual feeds */
26129 +
26130 +
26131 +static int proc_vci(char *buffer)
26132 +{
26133 +       return sprintf(buffer,
26134 +               "VCIVersion:\t%04x:%04x\n"
26135 +               "VCISyscall:\t%d\n"
26136 +               "VCIKernel:\t%08x\n"
26137 +               ,VCI_VERSION >> 16
26138 +               ,VCI_VERSION & 0xFFFF
26139 +               ,__NR_vserver
26140 +               ,vci_kernel_config()
26141 +               );
26142 +}
26143 +
26144 +static int proc_virtual_info(char *buffer)
26145 +{
26146 +       return proc_vci(buffer);
26147 +}
26148 +
26149 +static int proc_virtual_status(char *buffer)
26150 +{
26151 +       return sprintf(buffer,
26152 +               "#CTotal:\t%d\n"
26153 +               "#CActive:\t%d\n"
26154 +               ,atomic_read(&vx_global_ctotal)
26155 +               ,atomic_read(&vx_global_cactive)
26156 +               );
26157 +}
26158 +
26159 +
26160 +int proc_vxi_info (struct vx_info *vxi, char *buffer)
26161 +{
26162 +       int length;
26163 +
26164 +       length = sprintf(buffer,
26165 +               "ID:\t%d\n"
26166 +               "Info:\t%p\n"
26167 +               "Init:\t%d\n"
26168 +               ,vxi->vx_id
26169 +               ,vxi
26170 +               ,vxi->vx_initpid
26171 +               );
26172 +       return length;
26173 +}
26174 +
26175 +int proc_vxi_status (struct vx_info *vxi, char *buffer)
26176 +{
26177 +       int length;
26178 +
26179 +       length = sprintf(buffer,
26180 +               "UseCnt:\t%d\n"
26181 +               "Tasks:\t%d\n"
26182 +               "Flags:\t%016llx\n"
26183 +               "BCaps:\t%016llx\n"
26184 +               "CCaps:\t%016llx\n"
26185 +               "Spaces:\t%08lx\n"
26186 +//             "Ticks:\t%d\n"
26187 +               ,atomic_read(&vxi->vx_usecnt)
26188 +               ,atomic_read(&vxi->vx_tasks)
26189 +               ,(unsigned long long)vxi->vx_flags
26190 +               ,(unsigned long long)vxi->vx_bcaps
26191 +               ,(unsigned long long)vxi->vx_ccaps
26192 +               ,vxi->vx_nsmask
26193 +//             ,atomic_read(&vxi->limit.ticks)
26194 +               );
26195 +       return length;
26196 +}
26197 +
26198 +int proc_vxi_limit (struct vx_info *vxi, char *buffer)
26199 +{
26200 +       return vx_info_proc_limit(&vxi->limit, buffer);
26201 +}
26202 +
26203 +int proc_vxi_sched (struct vx_info *vxi, char *buffer)
26204 +{
26205 +       int cpu, length;
26206 +
26207 +       length = vx_info_proc_sched(&vxi->sched, buffer);
26208 +       for_each_online_cpu(cpu) {
26209 +               length += vx_info_proc_sched_pc(
26210 +                       &vx_per_cpu(vxi, sched_pc, cpu),
26211 +                       buffer + length, cpu);
26212 +       }
26213 +       return length;
26214 +}
26215 +
26216 +int proc_vxi_nsproxy (struct vx_info *vxi, char *buffer)
26217 +{
26218 +       return vx_info_proc_nsproxy(vxi->vx_nsproxy, buffer);
26219 +}
26220 +
26221 +int proc_vxi_cvirt (struct vx_info *vxi, char *buffer)
26222 +{
26223 +       int cpu, length;
26224 +
26225 +       vx_update_load(vxi);
26226 +       length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
26227 +       for_each_online_cpu(cpu) {
26228 +               length += vx_info_proc_cvirt_pc(
26229 +                       &vx_per_cpu(vxi, cvirt_pc, cpu),
26230 +                       buffer + length, cpu);
26231 +       }
26232 +       return length;
26233 +}
26234 +
26235 +int proc_vxi_cacct (struct vx_info *vxi, char *buffer)
26236 +{
26237 +       return vx_info_proc_cacct(&vxi->cacct, buffer);
26238 +}
26239 +
26240 +
26241 +static int proc_virtnet_info(char *buffer)
26242 +{
26243 +       return proc_vci(buffer);
26244 +}
26245 +
26246 +static int proc_virtnet_status(char *buffer)
26247 +{
26248 +       return sprintf(buffer,
26249 +               "#CTotal:\t%d\n"
26250 +               "#CActive:\t%d\n"
26251 +               ,atomic_read(&nx_global_ctotal)
26252 +               ,atomic_read(&nx_global_cactive)
26253 +               );
26254 +}
26255 +
26256 +int proc_nxi_info (struct nx_info *nxi, char *buffer)
26257 +{
26258 +       int length, i;
26259 +
26260 +       length = sprintf(buffer,
26261 +               "ID:\t%d\n"
26262 +               "Info:\t%p\n"
26263 +               ,nxi->nx_id
26264 +               ,nxi
26265 +               );
26266 +       for (i=0; i<nxi->nbipv4; i++) {
26267 +               length += sprintf(buffer + length,
26268 +                       "%d:\t" NIPQUAD_FMT "/" NIPQUAD_FMT "\n", i,
26269 +                       NIPQUAD(nxi->ipv4[i]), NIPQUAD(nxi->mask[i]));
26270 +       }
26271 +       return length;
26272 +}
26273 +
26274 +int proc_nxi_status (struct nx_info *nxi, char *buffer)
26275 +{
26276 +       int length;
26277 +
26278 +       length = sprintf(buffer,
26279 +               "UseCnt:\t%d\n"
26280 +               "Tasks:\t%d\n"
26281 +               ,atomic_read(&nxi->nx_usecnt)
26282 +               ,atomic_read(&nxi->nx_tasks)
26283 +               );
26284 +       return length;
26285 +}
26286 +
26287 +
26288 +
26289 +/* here the inode helpers */
26290 +
26291 +struct vs_entry {
26292 +       int len;
26293 +       char *name;
26294 +       mode_t mode;
26295 +       struct inode_operations *iop;
26296 +       struct file_operations *fop;
26297 +       union proc_op op;
26298 +};
26299 +
26300 +static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
26301 +{
26302 +       struct inode *inode = new_inode(sb);
26303 +
26304 +       if (!inode)
26305 +               goto out;
26306 +
26307 +       inode->i_mode = p->mode;
26308 +       if (p->iop)
26309 +               inode->i_op = p->iop;
26310 +       if (p->fop)
26311 +               inode->i_fop = p->fop;
26312 +
26313 +       inode->i_nlink = (p->mode & S_IFDIR) ? 2 : 1;
26314 +       inode->i_flags |= S_IMMUTABLE;
26315 +
26316 +       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
26317 +
26318 +       inode->i_uid = 0;
26319 +       inode->i_gid = 0;
26320 +       inode->i_tag = 0;
26321 +out:
26322 +       return inode;
26323 +}
26324 +
26325 +static struct dentry *vs_proc_instantiate(struct inode *dir,
26326 +       struct dentry *dentry, int id, void *ptr)
26327 +{
26328 +       struct vs_entry *p = ptr;
26329 +       struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
26330 +       struct dentry *error = ERR_PTR(-EINVAL);
26331 +
26332 +       if (!inode)
26333 +               goto out;
26334 +
26335 +       PROC_I(inode)->op = p->op;
26336 +       PROC_I(inode)->fd = id;
26337 +       d_add(dentry, inode);
26338 +       error = NULL;
26339 +out:
26340 +       return error;
26341 +}
26342 +
26343 +/* Lookups */
26344 +
26345 +typedef struct dentry *instantiate_t(struct inode *, struct dentry *, int, void *);
26346 +
26347 +/*
26348 + * Fill a directory entry.
26349 + *
26350 + * If possible create the dcache entry and derive our inode number and
26351 + * file type from dcache entry.
26352 + *
26353 + * Since all of the proc inode numbers are dynamically generated, the inode
26354 + * numbers do not exist until the inode is cache.  This means creating the
26355 + * the dcache entry in readdir is necessary to keep the inode numbers
26356 + * reported by readdir in sync with the inode numbers reported
26357 + * by stat.
26358 + */
26359 +static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
26360 +       char *name, int len, instantiate_t instantiate, int id, void *ptr)
26361 +{
26362 +       struct dentry *child, *dir = filp->f_dentry;
26363 +       struct inode *inode;
26364 +       struct qstr qname;
26365 +       ino_t ino = 0;
26366 +       unsigned type = DT_UNKNOWN;
26367 +
26368 +       qname.name = name;
26369 +       qname.len  = len;
26370 +       qname.hash = full_name_hash(name, len);
26371 +
26372 +       child = d_lookup(dir, &qname);
26373 +       if (!child) {
26374 +               struct dentry *new;
26375 +               new = d_alloc(dir, &qname);
26376 +               if (new) {
26377 +                       child = instantiate(dir->d_inode, new, id, ptr);
26378 +                       if (child)
26379 +                               dput(new);
26380 +                       else
26381 +                               child = new;
26382 +               }
26383 +       }
26384 +       if (!child || IS_ERR(child) || !child->d_inode)
26385 +               goto end_instantiate;
26386 +       inode = child->d_inode;
26387 +       if (inode) {
26388 +               ino = inode->i_ino;
26389 +               type = inode->i_mode >> 12;
26390 +       }
26391 +       dput(child);
26392 +end_instantiate:
26393 +       if (!ino)
26394 +               ino = find_inode_number(dir, &qname);
26395 +       if (!ino)
26396 +               ino = 1;
26397 +       return filldir(dirent, name, len, filp->f_pos, ino, type);
26398 +}
26399 +
26400 +
26401 +
26402 +/* get and revalidate vx_info/xid */
26403 +
26404 +static inline
26405 +struct vx_info *get_proc_vx_info(struct inode *inode)
26406 +{
26407 +       return lookup_vx_info(PROC_I(inode)->fd);
26408 +}
26409 +
26410 +static int proc_xid_revalidate(struct dentry * dentry, struct nameidata *nd)
26411 +{
26412 +       struct inode *inode = dentry->d_inode;
26413 +       xid_t xid = PROC_I(inode)->fd;
26414 +
26415 +       if (!xid || xid_is_hashed(xid))
26416 +               return 1;
26417 +       d_drop(dentry);
26418 +       return 0;
26419 +}
26420 +
26421 +
26422 +/* get and revalidate nx_info/nid */
26423 +
26424 +static int proc_nid_revalidate(struct dentry * dentry, struct nameidata *nd)
26425 +{
26426 +       struct inode *inode = dentry->d_inode;
26427 +       nid_t nid = PROC_I(inode)->fd;
26428 +
26429 +       if (!nid || nid_is_hashed(nid))
26430 +               return 1;
26431 +       d_drop(dentry);
26432 +       return 0;
26433 +}
26434 +
26435 +
26436 +
26437 +#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
26438 +
26439 +static ssize_t proc_vs_info_read(struct file * file, char __user * buf,
26440 +                         size_t count, loff_t *ppos)
26441 +{
26442 +       struct inode *inode = file->f_dentry->d_inode;
26443 +       unsigned long page;
26444 +       ssize_t length = 0;
26445 +
26446 +       if (count > PROC_BLOCK_SIZE)
26447 +               count = PROC_BLOCK_SIZE;
26448 +
26449 +       /* fade that out as soon as stable */
26450 +       WARN_ON(PROC_I(inode)->fd);
26451 +
26452 +       if (!(page = __get_free_page(GFP_KERNEL)))
26453 +               return -ENOMEM;
26454 +
26455 +       BUG_ON(!PROC_I(inode)->op.proc_vs_read);
26456 +       length = PROC_I(inode)->op.proc_vs_read((char*)page);
26457 +
26458 +       if (length >= 0)
26459 +               length = simple_read_from_buffer(buf, count, ppos,
26460 +                       (char *)page, length);
26461 +
26462 +       free_page(page);
26463 +       return length;
26464 +}
26465 +
26466 +static ssize_t proc_vx_info_read(struct file * file, char __user * buf,
26467 +                         size_t count, loff_t *ppos)
26468 +{
26469 +       struct inode *inode = file->f_dentry->d_inode;
26470 +       struct vx_info *vxi = NULL;
26471 +       xid_t xid = PROC_I(inode)->fd;
26472 +       unsigned long page;
26473 +       ssize_t length = 0;
26474 +
26475 +       if (count > PROC_BLOCK_SIZE)
26476 +               count = PROC_BLOCK_SIZE;
26477 +
26478 +       /* fade that out as soon as stable */
26479 +       WARN_ON(!xid);
26480 +       vxi = lookup_vx_info(xid);
26481 +       if (!vxi)
26482 +               goto out;
26483 +
26484 +       length = -ENOMEM;
26485 +       if (!(page = __get_free_page(GFP_KERNEL)))
26486 +               goto out_put;
26487 +
26488 +       BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
26489 +       length = PROC_I(inode)->op.proc_vxi_read(vxi, (char*)page);
26490 +
26491 +       if (length >= 0)
26492 +               length = simple_read_from_buffer(buf, count, ppos,
26493 +                       (char *)page, length);
26494 +
26495 +       free_page(page);
26496 +out_put:
26497 +       put_vx_info(vxi);
26498 +out:
26499 +       return length;
26500 +}
26501 +
26502 +static ssize_t proc_nx_info_read(struct file * file, char __user * buf,
26503 +                         size_t count, loff_t *ppos)
26504 +{
26505 +       struct inode *inode = file->f_dentry->d_inode;
26506 +       struct nx_info *nxi = NULL;
26507 +       nid_t nid = PROC_I(inode)->fd;
26508 +       unsigned long page;
26509 +       ssize_t length = 0;
26510 +
26511 +       if (count > PROC_BLOCK_SIZE)
26512 +               count = PROC_BLOCK_SIZE;
26513 +
26514 +       /* fade that out as soon as stable */
26515 +       WARN_ON(!nid);
26516 +       nxi = lookup_nx_info(nid);
26517 +       if (!nxi)
26518 +               goto out;
26519 +
26520 +       length = -ENOMEM;
26521 +       if (!(page = __get_free_page(GFP_KERNEL)))
26522 +               goto out_put;
26523 +
26524 +       BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
26525 +       length = PROC_I(inode)->op.proc_nxi_read(nxi, (char*)page);
26526 +
26527 +       if (length >= 0)
26528 +               length = simple_read_from_buffer(buf, count, ppos,
26529 +                       (char *)page, length);
26530 +
26531 +       free_page(page);
26532 +out_put:
26533 +       put_nx_info(nxi);
26534 +out:
26535 +       return length;
26536 +}
26537 +
26538 +
26539 +
26540 +/* here comes the lower level */
26541 +
26542 +
26543 +#define NOD(NAME, MODE, IOP, FOP, OP) {        \
26544 +       .len  = sizeof(NAME) - 1,       \
26545 +       .name = (NAME),                 \
26546 +       .mode = MODE,                   \
26547 +       .iop  = IOP,                    \
26548 +       .fop  = FOP,                    \
26549 +       .op   = OP,                     \
26550 +}
26551 +
26552 +
26553 +#define DIR(NAME, MODE, OTYPE)                         \
26554 +       NOD(NAME, (S_IFDIR|(MODE)),                     \
26555 +               &proc_##OTYPE##_inode_operations,       \
26556 +               &proc_##OTYPE##_file_operations, { } )
26557 +
26558 +#define INF(NAME, MODE, OTYPE)                         \
26559 +       NOD(NAME, (S_IFREG|(MODE)), NULL,               \
26560 +               &proc_vs_info_file_operations,          \
26561 +               { .proc_vs_read = &proc_##OTYPE } )
26562 +
26563 +#define VINF(NAME, MODE, OTYPE)                                \
26564 +       NOD(NAME, (S_IFREG|(MODE)), NULL,               \
26565 +               &proc_vx_info_file_operations,          \
26566 +               { .proc_vxi_read = &proc_##OTYPE } )
26567 +
26568 +#define NINF(NAME, MODE, OTYPE)                                \
26569 +       NOD(NAME, (S_IFREG|(MODE)), NULL,               \
26570 +               &proc_nx_info_file_operations,          \
26571 +               { .proc_nxi_read = &proc_##OTYPE } )
26572 +
26573 +
26574 +static struct file_operations proc_vs_info_file_operations = {
26575 +       .read =         proc_vs_info_read,
26576 +};
26577 +
26578 +static struct file_operations proc_vx_info_file_operations = {
26579 +       .read =         proc_vx_info_read,
26580 +};
26581 +
26582 +static struct dentry_operations proc_xid_dentry_operations = {
26583 +       .d_revalidate = proc_xid_revalidate,
26584 +};
26585 +
26586 +static struct vs_entry vx_base_stuff[] = {
26587 +       VINF("info",    S_IRUGO, vxi_info),
26588 +       VINF("status",  S_IRUGO, vxi_status),
26589 +       VINF("limit",   S_IRUGO, vxi_limit),
26590 +       VINF("sched",   S_IRUGO, vxi_sched),
26591 +       VINF("nsproxy", S_IRUGO, vxi_nsproxy),
26592 +       VINF("cvirt",   S_IRUGO, vxi_cvirt),
26593 +       VINF("cacct",   S_IRUGO, vxi_cacct),
26594 +       {}
26595 +};
26596 +
26597 +
26598 +
26599 +
26600 +static struct dentry *proc_xid_instantiate(struct inode *dir,
26601 +       struct dentry *dentry, int id, void *ptr)
26602 +{
26603 +       dentry->d_op = &proc_xid_dentry_operations;
26604 +       return vs_proc_instantiate(dir, dentry, id, ptr);
26605 +}
26606 +
26607 +static struct dentry *proc_xid_lookup(struct inode *dir,
26608 +       struct dentry *dentry, struct nameidata *nd)
26609 +{
26610 +       struct vs_entry *p = vx_base_stuff;
26611 +       struct dentry *error = ERR_PTR(-ENOENT);
26612 +
26613 +       for (; p->name; p++) {
26614 +               if (p->len != dentry->d_name.len)
26615 +                       continue;
26616 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
26617 +                       break;
26618 +       }
26619 +       if (!p->name)
26620 +               goto out;
26621 +
26622 +       error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
26623 +out:
26624 +       return error;
26625 +}
26626 +
26627 +static int proc_xid_readdir(struct file * filp,
26628 +       void * dirent, filldir_t filldir)
26629 +{
26630 +       struct dentry *dentry = filp->f_dentry;
26631 +       struct inode *inode = dentry->d_inode;
26632 +       struct vs_entry *p = vx_base_stuff;
26633 +       int size = sizeof(vx_base_stuff)/sizeof(struct vs_entry);
26634 +       int pos, index;
26635 +       u64 ino;
26636 +
26637 +       pos = filp->f_pos;
26638 +       switch (pos) {
26639 +       case 0:
26640 +               ino = inode->i_ino;
26641 +               if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
26642 +                       goto out;
26643 +               pos++;
26644 +               /* fall through */
26645 +       case 1:
26646 +               ino = parent_ino(dentry);
26647 +               if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
26648 +                       goto out;
26649 +               pos++;
26650 +               /* fall through */
26651 +       default:
26652 +               index = pos - 2;
26653 +               if (index >= size)
26654 +                       goto out;
26655 +               for (p += index; p->name; p++) {
26656 +                       if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
26657 +                               vs_proc_instantiate, PROC_I(inode)->fd, p))
26658 +                               goto out;
26659 +                       pos++;
26660 +               }
26661 +       }
26662 +out:
26663 +       filp->f_pos = pos;
26664 +       return 1;
26665 +}
26666 +
26667 +
26668 +
26669 +static struct file_operations proc_nx_info_file_operations = {
26670 +       .read =         proc_nx_info_read,
26671 +};
26672 +
26673 +static struct dentry_operations proc_nid_dentry_operations = {
26674 +       .d_revalidate = proc_nid_revalidate,
26675 +};
26676 +
26677 +static struct vs_entry nx_base_stuff[] = {
26678 +       NINF("info",    S_IRUGO, nxi_info),
26679 +       NINF("status",  S_IRUGO, nxi_status),
26680 +       {}
26681 +};
26682 +
26683 +
26684 +static struct dentry *proc_nid_instantiate(struct inode *dir,
26685 +       struct dentry *dentry, int id, void *ptr)
26686 +{
26687 +       dentry->d_op = &proc_nid_dentry_operations;
26688 +       return vs_proc_instantiate(dir, dentry, id, ptr);
26689 +}
26690 +
26691 +static struct dentry *proc_nid_lookup(struct inode *dir,
26692 +       struct dentry *dentry, struct nameidata *nd)
26693 +{
26694 +       struct vs_entry *p = nx_base_stuff;
26695 +       struct dentry *error = ERR_PTR(-ENOENT);
26696 +
26697 +       for (; p->name; p++) {
26698 +               if (p->len != dentry->d_name.len)
26699 +                       continue;
26700 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
26701 +                       break;
26702 +       }
26703 +       if (!p->name)
26704 +               goto out;
26705 +
26706 +       error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
26707 +out:
26708 +       return error;
26709 +}
26710 +
26711 +static int proc_nid_readdir(struct file * filp,
26712 +       void * dirent, filldir_t filldir)
26713 +{
26714 +       struct dentry *dentry = filp->f_dentry;
26715 +       struct inode *inode = dentry->d_inode;
26716 +       struct vs_entry *p = nx_base_stuff;
26717 +       int size = sizeof(nx_base_stuff)/sizeof(struct vs_entry);
26718 +       int pos, index;
26719 +       u64 ino;
26720 +
26721 +       pos = filp->f_pos;
26722 +       switch (pos) {
26723 +       case 0:
26724 +               ino = inode->i_ino;
26725 +               if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
26726 +                       goto out;
26727 +               pos++;
26728 +               /* fall through */
26729 +       case 1:
26730 +               ino = parent_ino(dentry);
26731 +               if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
26732 +                       goto out;
26733 +               pos++;
26734 +               /* fall through */
26735 +       default:
26736 +               index = pos - 2;
26737 +               if (index >= size)
26738 +                       goto out;
26739 +               for (p += index; p->name; p++) {
26740 +                       if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
26741 +                               vs_proc_instantiate, PROC_I(inode)->fd, p))
26742 +                               goto out;
26743 +                       pos++;
26744 +               }
26745 +       }
26746 +out:
26747 +       filp->f_pos = pos;
26748 +       return 1;
26749 +}
26750 +
26751 +
26752 +#define MAX_MULBY10    ((~0U-9)/10)
26753 +
26754 +static inline int atovid(const char *str, int len)
26755 +{
26756 +       int vid, c;
26757 +
26758 +       vid = 0;
26759 +       while (len-- > 0) {
26760 +               c = *str - '0';
26761 +               str++;
26762 +               if (c > 9)
26763 +                       return -1;
26764 +               if (vid >= MAX_MULBY10)
26765 +                       return -1;
26766 +               vid *= 10;
26767 +               vid += c;
26768 +               if (!vid)
26769 +                       return -1;
26770 +       }
26771 +       return vid;
26772 +}
26773 +
26774 +/* now the upper level (virtual) */
26775 +
26776 +
26777 +static struct file_operations proc_xid_file_operations = {
26778 +       .read =         generic_read_dir,
26779 +       .readdir =      proc_xid_readdir,
26780 +};
26781 +
26782 +static struct inode_operations proc_xid_inode_operations = {
26783 +       .lookup =       proc_xid_lookup,
26784 +};
26785 +
26786 +static struct vs_entry vx_virtual_stuff[] = {
26787 +       INF("info",     S_IRUGO, virtual_info),
26788 +       INF("status",   S_IRUGO, virtual_status),
26789 +       DIR(NULL,       S_IRUGO|S_IXUGO, xid),
26790 +};
26791 +
26792 +
26793 +static struct dentry *proc_virtual_lookup(struct inode *dir,
26794 +       struct dentry *dentry, struct nameidata *nd)
26795 +{
26796 +       struct vs_entry *p = vx_virtual_stuff;
26797 +       struct dentry *error = ERR_PTR(-ENOENT);
26798 +       int id = 0;
26799 +
26800 +       for (; p->name; p++) {
26801 +               if (p->len != dentry->d_name.len)
26802 +                       continue;
26803 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
26804 +                       break;
26805 +       }
26806 +       if (p->name)
26807 +               goto instantiate;
26808 +
26809 +       id = atovid(dentry->d_name.name, dentry->d_name.len);
26810 +       if ((id < 0) || !xid_is_hashed(id))
26811 +               goto out;
26812 +
26813 +instantiate:
26814 +       error = proc_xid_instantiate(dir, dentry, id, p);
26815 +out:
26816 +       return error;
26817 +}
26818 +
26819 +static struct file_operations proc_nid_file_operations = {
26820 +       .read =         generic_read_dir,
26821 +       .readdir =      proc_nid_readdir,
26822 +};
26823 +
26824 +static struct inode_operations proc_nid_inode_operations = {
26825 +       .lookup =       proc_nid_lookup,
26826 +};
26827 +
26828 +static struct vs_entry nx_virtnet_stuff[] = {
26829 +       INF("info",     S_IRUGO, virtnet_info),
26830 +       INF("status",   S_IRUGO, virtnet_status),
26831 +       DIR(NULL,       S_IRUGO|S_IXUGO, nid),
26832 +};
26833 +
26834 +
26835 +static struct dentry *proc_virtnet_lookup(struct inode *dir,
26836 +       struct dentry *dentry, struct nameidata *nd)
26837 +{
26838 +       struct vs_entry *p = nx_virtnet_stuff;
26839 +       struct dentry *error = ERR_PTR(-ENOENT);
26840 +       int id = 0;
26841 +
26842 +       for (; p->name; p++) {
26843 +               if (p->len != dentry->d_name.len)
26844 +                       continue;
26845 +               if (!memcmp(dentry->d_name.name, p->name, p->len))
26846 +                       break;
26847 +       }
26848 +       if (p->name)
26849 +               goto instantiate;
26850 +
26851 +       id = atovid(dentry->d_name.name, dentry->d_name.len);
26852 +       if ((id < 0) || !nid_is_hashed(id))
26853 +               goto out;
26854 +
26855 +instantiate:
26856 +       error = proc_nid_instantiate(dir, dentry, id, p);
26857 +out:
26858 +       return error;
26859 +}
26860 +
26861 +
26862 +
26863 +#define PROC_NUMBUF 10
26864 +#define PROC_MAXVIDS 32
26865 +
26866 +int proc_virtual_readdir(struct file * filp,
26867 +       void * dirent, filldir_t filldir)
26868 +{
26869 +       struct dentry *dentry = filp->f_dentry;
26870 +       struct inode *inode = dentry->d_inode;
26871 +       struct vs_entry *p = vx_virtual_stuff;
26872 +       int size = sizeof(vx_virtual_stuff)/sizeof(struct vs_entry);
26873 +       int pos, index;
26874 +       unsigned int xid_array[PROC_MAXVIDS];
26875 +       char buf[PROC_NUMBUF];
26876 +       unsigned int nr_xids, i;
26877 +       u64 ino;
26878 +
26879 +       pos = filp->f_pos;
26880 +       switch (pos) {
26881 +       case 0:
26882 +               ino = inode->i_ino;
26883 +               if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
26884 +                       goto out;
26885 +               pos++;
26886 +               /* fall through */
26887 +       case 1:
26888 +               ino = parent_ino(dentry);
26889 +               if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
26890 +                       goto out;
26891 +               pos++;
26892 +               /* fall through */
26893 +       default:
26894 +               index = pos - 2;
26895 +               if (index >= size)
26896 +                       goto entries;
26897 +               for (p += index; p->name; p++) {
26898 +                       if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
26899 +                               vs_proc_instantiate, 0, p))
26900 +                               goto out;
26901 +                       pos++;
26902 +               }
26903 +       entries:
26904 +               index = pos - size;
26905 +               p = &vx_virtual_stuff[size-1];
26906 +               nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
26907 +               for (i = 0; i < nr_xids; i++) {
26908 +                       int n, xid = xid_array[i];
26909 +                       unsigned int j = PROC_NUMBUF;
26910 +
26911 +                       n = xid;
26912 +                       do buf[--j] = '0' + (n % 10); while (n /= 10);
26913 +
26914 +                       if (proc_fill_cache(filp, dirent, filldir, buf+j, PROC_NUMBUF-j,
26915 +                               vs_proc_instantiate, xid, p))
26916 +                               goto out;
26917 +                       pos++;
26918 +               }
26919 +       }
26920 +out:
26921 +       filp->f_pos = pos;
26922 +       return 0;
26923 +}
26924 +
26925 +
26926 +static struct file_operations proc_virtual_dir_operations = {
26927 +       .read =         generic_read_dir,
26928 +       .readdir =      proc_virtual_readdir,
26929 +};
26930 +
26931 +static struct inode_operations proc_virtual_dir_inode_operations = {
26932 +       .lookup =       proc_virtual_lookup,
26933 +};
26934 +
26935 +
26936 +
26937 +
26938 +
26939 +int proc_virtnet_readdir(struct file * filp,
26940 +       void * dirent, filldir_t filldir)
26941 +{
26942 +       struct dentry *dentry = filp->f_dentry;
26943 +       struct inode *inode = dentry->d_inode;
26944 +       struct vs_entry *p = nx_virtnet_stuff;
26945 +       int size = sizeof(nx_virtnet_stuff)/sizeof(struct vs_entry);
26946 +       int pos, index;
26947 +       unsigned int nid_array[PROC_MAXVIDS];
26948 +       char buf[PROC_NUMBUF];
26949 +       unsigned int nr_nids, i;
26950 +       u64 ino;
26951 +
26952 +       pos = filp->f_pos;
26953 +       switch (pos) {
26954 +       case 0:
26955 +               ino = inode->i_ino;
26956 +               if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
26957 +                       goto out;
26958 +               pos++;
26959 +               /* fall through */
26960 +       case 1:
26961 +               ino = parent_ino(dentry);
26962 +               if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
26963 +                       goto out;
26964 +               pos++;
26965 +               /* fall through */
26966 +       default:
26967 +               index = pos - 2;
26968 +               if (index >= size)
26969 +                       goto entries;
26970 +               for (p += index; p->name; p++) {
26971 +                       if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
26972 +                               vs_proc_instantiate, 0, p))
26973 +                               goto out;
26974 +                       pos++;
26975 +               }
26976 +       entries:
26977 +               index = pos - size;
26978 +               p = &nx_virtnet_stuff[size-1];
26979 +               nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
26980 +               for (i = 0; i < nr_nids; i++) {
26981 +                       int n, nid = nid_array[i];
26982 +                       unsigned int j = PROC_NUMBUF;
26983 +
26984 +                       n = nid;
26985 +                       do buf[--j] = '0' + (n % 10); while (n /= 10);
26986 +
26987 +                       if (proc_fill_cache(filp, dirent, filldir, buf+j, PROC_NUMBUF-j,
26988 +                               vs_proc_instantiate, nid, p))
26989 +                               goto out;
26990 +                       pos++;
26991 +               }
26992 +       }
26993 +out:
26994 +       filp->f_pos = pos;
26995 +       return 0;
26996 +}
26997 +
26998 +
26999 +static struct file_operations proc_virtnet_dir_operations = {
27000 +       .read =         generic_read_dir,
27001 +       .readdir =      proc_virtnet_readdir,
27002 +};
27003 +
27004 +static struct inode_operations proc_virtnet_dir_inode_operations = {
27005 +       .lookup =       proc_virtnet_lookup,
27006 +};
27007 +
27008 +
27009 +
27010 +void proc_vx_init(void)
27011 +{
27012 +       struct proc_dir_entry *ent;
27013 +
27014 +       ent = proc_mkdir("virtual", 0);
27015 +       if (ent) {
27016 +               ent->proc_fops = &proc_virtual_dir_operations;
27017 +               ent->proc_iops = &proc_virtual_dir_inode_operations;
27018 +       }
27019 +       proc_virtual = ent;
27020 +
27021 +       ent = proc_mkdir("virtnet", 0);
27022 +       if (ent) {
27023 +               ent->proc_fops = &proc_virtnet_dir_operations;
27024 +               ent->proc_iops = &proc_virtnet_dir_inode_operations;
27025 +       }
27026 +       proc_virtnet = ent;
27027 +}
27028 +
27029 +
27030 +
27031 +
27032 +/* per pid info */
27033 +
27034 +
27035 +int proc_pid_vx_info(struct task_struct *p, char *buffer)
27036 +{
27037 +       struct vx_info *vxi;
27038 +       char * orig = buffer;
27039 +
27040 +       buffer += sprintf (buffer,"XID:\t%d\n", vx_task_xid(p));
27041 +
27042 +       vxi = task_get_vx_info(p);
27043 +       if (!vxi)
27044 +               goto out;
27045 +
27046 +       buffer += sprintf (buffer,"BCaps:\t%016llx\n"
27047 +               ,(unsigned long long)vxi->vx_bcaps);
27048 +       buffer += sprintf (buffer,"CCaps:\t%016llx\n"
27049 +               ,(unsigned long long)vxi->vx_ccaps);
27050 +       buffer += sprintf (buffer,"CFlags:\t%016llx\n"
27051 +               ,(unsigned long long)vxi->vx_flags);
27052 +       buffer += sprintf (buffer,"CIPid:\t%d\n"
27053 +               ,vxi->vx_initpid);
27054 +
27055 +       put_vx_info(vxi);
27056 +out:
27057 +       return buffer - orig;
27058 +}
27059 +
27060 +
27061 +int proc_pid_nx_info(struct task_struct *p, char *buffer)
27062 +{
27063 +       struct nx_info *nxi;
27064 +       char * orig = buffer;
27065 +       int i;
27066 +
27067 +       buffer += sprintf (buffer,"NID:\t%d\n", nx_task_nid(p));
27068 +
27069 +       nxi = task_get_nx_info(p);
27070 +       if (!nxi)
27071 +               goto out;
27072 +
27073 +       for (i=0; i<nxi->nbipv4; i++){
27074 +               buffer += sprintf (buffer,
27075 +                       "V4Root[%d]:\t%d.%d.%d.%d/%d.%d.%d.%d\n", i
27076 +                       ,NIPQUAD(nxi->ipv4[i])
27077 +                       ,NIPQUAD(nxi->mask[i]));
27078 +       }
27079 +       buffer += sprintf (buffer,
27080 +               "V4Root[bcast]:\t%d.%d.%d.%d\n"
27081 +               ,NIPQUAD(nxi->v4_bcast));
27082 +       buffer += sprintf (buffer,
27083 +               "V4Root[lback]:\t%d.%d.%d.%d\n"
27084 +               ,NIPQUAD(nxi->v4_lback));
27085 +
27086 +       put_nx_info(nxi);
27087 +out:
27088 +       return buffer - orig;
27089 +}
27090 +
27091 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/sched.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched.c
27092 --- linux-2.6.19.1/kernel/vserver/sched.c       1970-01-01 01:00:00 +0100
27093 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched.c     2006-12-17 04:30:06 +0100
27094 @@ -0,0 +1,289 @@
27095 +/*
27096 + *  linux/kernel/vserver/sched.c
27097 + *
27098 + *  Virtual Server: Scheduler Support
27099 + *
27100 + *  Copyright (C) 2004-2006  Herbert Pötzl
27101 + *
27102 + *  V0.01  adapted Sam Vilains version to 2.6.3
27103 + *  V0.02  removed legacy interface
27104 + *  V0.03  changed vcmds to vxi arg
27105 + *
27106 + */
27107 +
27108 +#include <linux/sched.h>
27109 +#include <linux/vs_context.h>
27110 +#include <linux/vs_sched.h>
27111 +#include <linux/vserver/sched_cmd.h>
27112 +
27113 +#include <asm/errno.h>
27114 +#include <asm/uaccess.h>
27115 +
27116 +#define vxd_check_range(val, min, max) do {            \
27117 +       vxlprintk((val<min) || (val>max),               \
27118 +               "check_range(%ld,%ld,%ld)",             \
27119 +               (long)val, (long)min, (long)max,        \
27120 +               __FILE__, __LINE__);                    \
27121 +       } while (0)
27122 +
27123 +
27124 +void vx_update_sched_param(struct _vx_sched *sched,
27125 +       struct _vx_sched_pc *sched_pc)
27126 +{
27127 +       unsigned int set_mask = sched->update_mask;
27128 +
27129 +       if (set_mask & VXSM_FILL_RATE)
27130 +               sched_pc->fill_rate[0] = sched->fill_rate[0];
27131 +       if (set_mask & VXSM_INTERVAL)
27132 +               sched_pc->interval[0] = sched->interval[0];
27133 +       if (set_mask & VXSM_FILL_RATE2)
27134 +               sched_pc->fill_rate[1] = sched->fill_rate[1];
27135 +       if (set_mask & VXSM_INTERVAL2)
27136 +               sched_pc->interval[1] = sched->interval[1];
27137 +       if (set_mask & VXSM_TOKENS)
27138 +               sched_pc->tokens = sched->tokens;
27139 +       if (set_mask & VXSM_TOKENS_MIN)
27140 +               sched_pc->tokens_min = sched->tokens_min;
27141 +       if (set_mask & VXSM_TOKENS_MAX)
27142 +               sched_pc->tokens_max = sched->tokens_max;
27143 +
27144 +       if (set_mask & VXSM_IDLE_TIME)
27145 +               sched_pc->flags |= VXSF_IDLE_TIME;
27146 +       else
27147 +               sched_pc->flags &= ~VXSF_IDLE_TIME;
27148 +
27149 +       /* reset time */
27150 +       sched_pc->norm_time = jiffies;
27151 +}
27152 +
27153 +
27154 +/*
27155 + * recalculate the context's scheduling tokens
27156 + *
27157 + * ret > 0 : number of tokens available
27158 + * ret < 0 : on hold, check delta_min[]
27159 + *          -1 only jiffies
27160 + *          -2 also idle time
27161 + *
27162 + */
27163 +int vx_tokens_recalc(struct _vx_sched_pc *sched_pc,
27164 +       unsigned long *norm_time, unsigned long *idle_time, int delta_min[2])
27165 +{
27166 +       long delta;
27167 +       long tokens = 0;
27168 +       int flags = sched_pc->flags;
27169 +
27170 +       /* how much time did pass? */
27171 +       delta = *norm_time - sched_pc->norm_time;
27172 +       vxd_check_range(delta, 0, INT_MAX);
27173 +
27174 +       if (delta >= sched_pc->interval[0]) {
27175 +               long tokens, integral;
27176 +
27177 +               /* calc integral token part */
27178 +               tokens = delta / sched_pc->interval[0];
27179 +               integral = tokens * sched_pc->interval[0];
27180 +               tokens *= sched_pc->fill_rate[0];
27181 +#ifdef CONFIG_VSERVER_HARDCPU
27182 +               delta_min[0] = delta - integral;
27183 +               vxd_check_range(delta_min[0], 0, sched_pc->interval[0]);
27184 +#endif
27185 +               /* advance time */
27186 +               sched_pc->norm_time += delta;
27187 +
27188 +               /* add tokens */
27189 +               sched_pc->tokens += tokens;
27190 +               sched_pc->token_time += tokens;
27191 +       }
27192 +       else
27193 +               delta_min[0] = delta;
27194 +
27195 +#ifdef CONFIG_VSERVER_IDLETIME
27196 +       if (!(flags & VXSF_IDLE_TIME))
27197 +               goto skip_idle;
27198 +
27199 +       /* how much was the idle skip? */
27200 +       delta = *idle_time - sched_pc->idle_time;
27201 +       vxd_check_range(delta, 0, INT_MAX);
27202 +
27203 +       if (delta >= sched_pc->interval[1]) {
27204 +               long tokens, integral;
27205 +
27206 +               /* calc fair share token part */
27207 +               tokens = delta / sched_pc->interval[1];
27208 +               integral = tokens * sched_pc->interval[1];
27209 +               tokens *= sched_pc->fill_rate[1];
27210 +               delta_min[1] = delta - integral;
27211 +               vxd_check_range(delta_min[1], 0, sched_pc->interval[1]);
27212 +
27213 +               /* advance idle time */
27214 +               sched_pc->idle_time += integral;
27215 +
27216 +               /* add tokens */
27217 +               sched_pc->tokens += tokens;
27218 +               sched_pc->token_time += tokens;
27219 +       }
27220 +       else
27221 +               delta_min[1] = delta;
27222 +skip_idle:
27223 +#endif
27224 +
27225 +       /* clip at maximum */
27226 +       if (sched_pc->tokens > sched_pc->tokens_max)
27227 +               sched_pc->tokens = sched_pc->tokens_max;
27228 +       tokens = sched_pc->tokens;
27229 +
27230 +       if ((flags & VXSF_ONHOLD)) {
27231 +               /* can we unhold? */
27232 +               if (tokens >= sched_pc->tokens_min) {
27233 +                       flags &= ~VXSF_ONHOLD;
27234 +                       sched_pc->hold_ticks +=
27235 +                               *norm_time - sched_pc->onhold;
27236 +               }
27237 +               else
27238 +                       goto on_hold;
27239 +       } else {
27240 +               /* put on hold? */
27241 +               if (tokens <= 0) {
27242 +                       flags |= VXSF_ONHOLD;
27243 +                       sched_pc->onhold = *norm_time;
27244 +                       goto on_hold;
27245 +               }
27246 +       }
27247 +       sched_pc->flags = flags;
27248 +       return tokens;
27249 +
27250 +on_hold:
27251 +       tokens = sched_pc->tokens_min - tokens;
27252 +       sched_pc->flags = flags;
27253 +       BUG_ON(tokens < 0);
27254 +
27255 +#ifdef CONFIG_VSERVER_HARDCPU
27256 +       /* next interval? */
27257 +       if (!sched_pc->fill_rate[0])
27258 +               delta_min[0] = HZ;
27259 +       else if (tokens > sched_pc->fill_rate[0])
27260 +               delta_min[0] += sched_pc->interval[0] *
27261 +                       tokens / sched_pc->fill_rate[0];
27262 +       else
27263 +               delta_min[0] = sched_pc->interval[0] - delta_min[0];
27264 +       vxd_check_range(delta_min[0], 0, INT_MAX);
27265 +
27266 +#ifdef CONFIG_VSERVER_IDLETIME
27267 +       if (!(flags & VXSF_IDLE_TIME))
27268 +               return -1;
27269 +
27270 +       /* next interval? */
27271 +       if (!sched_pc->fill_rate[1])
27272 +               delta_min[1] = HZ;
27273 +       else if (tokens > sched_pc->fill_rate[1])
27274 +               delta_min[1] += sched_pc->interval[1] *
27275 +                       tokens / sched_pc->fill_rate[1];
27276 +       else
27277 +               delta_min[1] = sched_pc->interval[1] - delta_min[1];
27278 +       vxd_check_range(delta_min[1], 0, INT_MAX);
27279 +
27280 +       return -2;
27281 +#else
27282 +       return -1;
27283 +#endif /* CONFIG_VSERVER_IDLETIME */
27284 +#else
27285 +       return 0;
27286 +#endif /* CONFIG_VSERVER_HARDCPU */
27287 +}
27288 +
27289 +
27290 +static int do_set_sched(struct vx_info *vxi, struct vcmd_set_sched_v4 *data)
27291 +{
27292 +       unsigned int set_mask = data->set_mask;
27293 +       unsigned int update_mask;
27294 +
27295 +       /* Sanity check data values */
27296 +       if (data->fill_rate < 0)
27297 +               data->fill_rate = 1;
27298 +       if (data->interval <= 0)
27299 +               data->interval = HZ;
27300 +       if (data->tokens_max <= 0)
27301 +               data->tokens_max = HZ;
27302 +       if (data->tokens_min < 0)
27303 +               data->tokens_min = data->fill_rate*3;
27304 +       if (data->tokens_min >= data->tokens_max)
27305 +               data->tokens_min = data->tokens_max;
27306 +
27307 +       if (data->prio_bias > MAX_PRIO_BIAS)
27308 +               data->prio_bias = MAX_PRIO_BIAS;
27309 +       if (data->prio_bias < MIN_PRIO_BIAS)
27310 +               data->prio_bias = MIN_PRIO_BIAS;
27311 +
27312 +       spin_lock(&vxi->sched.tokens_lock);
27313 +
27314 +       if (set_mask & VXSM_FILL_RATE)
27315 +               vxi->sched.fill_rate[0] = data->fill_rate;
27316 +       if (set_mask & VXSM_INTERVAL)
27317 +               vxi->sched.interval[0] = data->interval;
27318 +       if (set_mask & VXSM_FILL_RATE2)
27319 +               vxi->sched.fill_rate[1] = data->fill_rate;
27320 +       if (set_mask & VXSM_INTERVAL2)
27321 +               vxi->sched.interval[1] = data->interval;
27322 +       if (set_mask & VXSM_TOKENS)
27323 +               vxi->sched.tokens = data->tokens;
27324 +       if (set_mask & VXSM_TOKENS_MIN)
27325 +               vxi->sched.tokens_min = data->tokens_min;
27326 +       if (set_mask & VXSM_TOKENS_MAX)
27327 +               vxi->sched.tokens_max = data->tokens_max;
27328 +       if (set_mask & VXSM_PRIO_BIAS)
27329 +               vxi->sched.prio_bias = data->prio_bias;
27330 +
27331 +       update_mask = vxi->sched.update_mask & VXSM_SET_MASK;
27332 +       update_mask |= (set_mask & (VXSM_SET_MASK|VXSM_IDLE_TIME));
27333 +       vxi->sched.update_mask = update_mask;
27334 +#ifdef CONFIG_SMP
27335 +       rmb();
27336 +       if (set_mask & VXSM_CPU_ID)
27337 +               vxi->sched.update = cpumask_of_cpu(data->cpu_id);
27338 +       else
27339 +               vxi->sched.update = CPU_MASK_ALL;
27340 +       /* forced reload? */
27341 +       if (set_mask & VXSM_FORCE) {
27342 +               int cpu;
27343 +
27344 +               for_each_possible_cpu(cpu)
27345 +                       vx_update_sched_param(&vxi->sched,
27346 +                               &vx_per_cpu(vxi, sched_pc, cpu));
27347 +       }
27348 +#else
27349 +       /* on UP we update immediately */
27350 +       vx_update_sched_param(&vxi->sched,
27351 +               &vx_per_cpu(vxi, sched_pc, 0));
27352 +#endif
27353 +
27354 +       spin_unlock(&vxi->sched.tokens_lock);
27355 +       return 0;
27356 +}
27357 +
27358 +int vc_set_sched_v3(struct vx_info *vxi, void __user *data)
27359 +{
27360 +       struct vcmd_set_sched_v3 vc_data;
27361 +       struct vcmd_set_sched_v4 vc_data_v4;
27362 +
27363 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
27364 +               return -EFAULT;
27365 +
27366 +       /* structures are binary compatible */
27367 +       memcpy(&vc_data_v4, &vc_data, sizeof(vc_data));
27368 +       vc_data_v4.set_mask &= VXSM_V3_MASK;
27369 +       vc_data_v4.bucket_id = 0;
27370 +
27371 +       return do_set_sched(vxi, &vc_data_v4);
27372 +}
27373 +
27374 +int vc_set_sched(struct vx_info *vxi, void __user *data)
27375 +{
27376 +       struct vcmd_set_sched_v4 vc_data;
27377 +
27378 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
27379 +               return -EFAULT;
27380 +
27381 +       return do_set_sched(vxi, &vc_data);
27382 +}
27383 +
27384 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/sched_init.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched_init.h
27385 --- linux-2.6.19.1/kernel/vserver/sched_init.h  1970-01-01 01:00:00 +0100
27386 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched_init.h        2006-11-08 04:57:49 +0100
27387 @@ -0,0 +1,49 @@
27388 +
27389 +static inline void vx_info_init_sched(struct _vx_sched *sched)
27390 +{
27391 +       static struct lock_class_key tokens_lock_key;
27392 +
27393 +       /* scheduling; hard code starting values as constants */
27394 +       sched->fill_rate[0]     = 1;
27395 +       sched->interval[0]      = 4;
27396 +       sched->fill_rate[1]     = 1;
27397 +       sched->interval[1]      = 8;
27398 +       sched->tokens           = HZ >> 2;
27399 +       sched->tokens_min       = HZ >> 4;
27400 +       sched->tokens_max       = HZ >> 1;
27401 +       sched->tokens_lock      = SPIN_LOCK_UNLOCKED;
27402 +       sched->prio_bias        = 0;
27403 +       sched->vavavoom         = 0;
27404 +
27405 +       lockdep_set_class(&sched->tokens_lock, &tokens_lock_key);
27406 +}
27407 +
27408 +static inline
27409 +void vx_info_init_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
27410 +{
27411 +       sched_pc->fill_rate[0]  = 1;
27412 +       sched_pc->interval[0]   = 4;
27413 +       sched_pc->fill_rate[1]  = 1;
27414 +       sched_pc->interval[1]   = 8;
27415 +       sched_pc->tokens        = HZ >> 2;
27416 +       sched_pc->tokens_min    = HZ >> 4;
27417 +       sched_pc->tokens_max    = HZ >> 1;
27418 +       sched_pc->token_time    = 0;
27419 +       sched_pc->idle_time     = 0;
27420 +       sched_pc->norm_time     = jiffies;
27421 +
27422 +       sched_pc->user_ticks = 0;
27423 +       sched_pc->sys_ticks = 0;
27424 +       sched_pc->hold_ticks = 0;
27425 +}
27426 +
27427 +static inline void vx_info_exit_sched(struct _vx_sched *sched)
27428 +{
27429 +       return;
27430 +}
27431 +
27432 +static inline
27433 +void vx_info_exit_sched_pc(struct _vx_sched_pc *sched_pc, int cpu)
27434 +{
27435 +       return;
27436 +}
27437 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/sched_proc.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched_proc.h
27438 --- linux-2.6.19.1/kernel/vserver/sched_proc.h  1970-01-01 01:00:00 +0100
27439 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sched_proc.h        2006-11-08 04:57:49 +0100
27440 @@ -0,0 +1,59 @@
27441 +#ifndef _VX_SCHED_PROC_H
27442 +#define _VX_SCHED_PROC_H
27443 +
27444 +
27445 +static inline
27446 +int vx_info_proc_sched(struct _vx_sched *sched, char *buffer)
27447 +{
27448 +       int length = 0;
27449 +
27450 +       length += sprintf(buffer,
27451 +               "FillRate:\t%8d,%d\n"
27452 +               "Interval:\t%8d,%d\n"
27453 +               "TokensMin:\t%8d\n"
27454 +               "TokensMax:\t%8d\n"
27455 +               "PrioBias:\t%8d\n"
27456 +               "VaVaVoom:\t%8d\n"
27457 +               ,sched->fill_rate[0]
27458 +               ,sched->fill_rate[1]
27459 +               ,sched->interval[0]
27460 +               ,sched->interval[1]
27461 +               ,sched->tokens_min
27462 +               ,sched->tokens_max
27463 +               ,sched->prio_bias
27464 +               ,sched->vavavoom
27465 +               );
27466 +       return length;
27467 +}
27468 +
27469 +static inline
27470 +int vx_info_proc_sched_pc(struct _vx_sched_pc *sched_pc,
27471 +       char *buffer, int cpu)
27472 +{
27473 +       int length = 0;
27474 +
27475 +       length += sprintf(buffer + length,
27476 +               "cpu %d: %lld %lld %lld %ld %ld"
27477 +               ,cpu
27478 +               ,(unsigned long long)sched_pc->user_ticks
27479 +               ,(unsigned long long)sched_pc->sys_ticks
27480 +               ,(unsigned long long)sched_pc->hold_ticks
27481 +               ,sched_pc->token_time
27482 +               ,sched_pc->idle_time
27483 +               );
27484 +       length += sprintf(buffer + length,
27485 +               " %c%c %d %d %d %d/%d %d/%d\n"
27486 +               ,(sched_pc->flags & VXSF_ONHOLD) ? 'H' : 'R'
27487 +               ,(sched_pc->flags & VXSF_IDLE_TIME) ? 'I' : '-'
27488 +               ,sched_pc->tokens
27489 +               ,sched_pc->tokens_min
27490 +               ,sched_pc->tokens_max
27491 +               ,sched_pc->fill_rate[0]
27492 +               ,sched_pc->interval[0]
27493 +               ,sched_pc->fill_rate[1]
27494 +               ,sched_pc->interval[1]
27495 +               );
27496 +       return length;
27497 +}
27498 +
27499 +#endif /* _VX_SCHED_PROC_H */
27500 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/signal.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/signal.c
27501 --- linux-2.6.19.1/kernel/vserver/signal.c      1970-01-01 01:00:00 +0100
27502 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/signal.c    2006-11-08 04:57:45 +0100
27503 @@ -0,0 +1,136 @@
27504 +/*
27505 + *  linux/kernel/vserver/signal.c
27506 + *
27507 + *  Virtual Server: Signal Support
27508 + *
27509 + *  Copyright (C) 2003-2006  Herbert Pötzl
27510 + *
27511 + *  V0.01  broken out from vcontext V0.05
27512 + *  V0.02  changed vcmds to vxi arg
27513 + *
27514 + */
27515 +
27516 +#include <linux/sched.h>
27517 +
27518 +#include <asm/errno.h>
27519 +#include <asm/uaccess.h>
27520 +
27521 +#include <linux/vs_context.h>
27522 +#include <linux/vserver/signal_cmd.h>
27523 +
27524 +
27525 +int vx_info_kill(struct vx_info *vxi, int pid, int sig)
27526 +{
27527 +       int retval, count=0;
27528 +       struct task_struct *p;
27529 +       unsigned long priv = 0;
27530 +
27531 +       retval = -ESRCH;
27532 +       vxdprintk(VXD_CBIT(misc, 4),
27533 +               "vx_info_kill(%p[#%d],%d,%d)*",
27534 +               vxi, vxi->vx_id, pid, sig);
27535 +       read_lock(&tasklist_lock);
27536 +       switch (pid) {
27537 +       case  0:
27538 +               priv = 1;
27539 +       case -1:
27540 +               for_each_process(p) {
27541 +                       int err = 0;
27542 +
27543 +                       if (vx_task_xid(p) != vxi->vx_id || p->pid <= 1 ||
27544 +                               (pid && vxi->vx_initpid == p->pid))
27545 +                               continue;
27546 +
27547 +                       err = group_send_sig_info(sig, (void*)priv, p);
27548 +                       ++count;
27549 +                       if (err != -EPERM)
27550 +                               retval = err;
27551 +               }
27552 +               break;
27553 +
27554 +       case 1:
27555 +               if (vxi->vx_initpid) {
27556 +                       pid = vxi->vx_initpid;
27557 +                       /* for now, only SIGINT to private init ... */
27558 +                       if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
27559 +                               /* ... as long as there are tasks left */
27560 +                               (atomic_read(&vxi->vx_tasks) > 1))
27561 +                               sig = SIGINT;
27562 +                       priv = 1;
27563 +               }
27564 +               /* fallthrough */
27565 +       default:
27566 +               p = find_task_by_real_pid(pid);
27567 +               if (p) {
27568 +                       if (vx_task_xid(p) == vxi->vx_id)
27569 +                               retval = group_send_sig_info(sig,
27570 +                                       (void*)priv, p);
27571 +               }
27572 +               break;
27573 +       }
27574 +       read_unlock(&tasklist_lock);
27575 +       vxdprintk(VXD_CBIT(misc, 4),
27576 +               "vx_info_kill(%p[#%d],%d,%d) = %d",
27577 +               vxi, vxi->vx_id, pid, sig, retval);
27578 +       return retval;
27579 +}
27580 +
27581 +int vc_ctx_kill(struct vx_info *vxi, void __user *data)
27582 +{
27583 +       struct vcmd_ctx_kill_v0 vc_data;
27584 +
27585 +       if (copy_from_user (&vc_data, data, sizeof(vc_data)))
27586 +               return -EFAULT;
27587 +
27588 +       /* special check to allow guest shutdown */
27589 +       if (!vx_info_flags(vxi, VXF_STATE_ADMIN, 0) &&
27590 +               /* forbid killall pid=0 when init is present */
27591 +               (((vc_data.pid < 1) && vxi->vx_initpid) ||
27592 +               (vc_data.pid > 1)))
27593 +               return -EACCES;
27594 +
27595 +       return vx_info_kill(vxi, vc_data.pid, vc_data.sig);
27596 +}
27597 +
27598 +
27599 +static int __wait_exit(struct vx_info *vxi)
27600 +{
27601 +       DECLARE_WAITQUEUE(wait, current);
27602 +       int ret = 0;
27603 +
27604 +       add_wait_queue(&vxi->vx_wait, &wait);
27605 +       set_current_state(TASK_INTERRUPTIBLE);
27606 +
27607 +wait:
27608 +       if (vx_info_state(vxi,
27609 +               VXS_SHUTDOWN|VXS_HASHED|VXS_HELPER) == VXS_SHUTDOWN)
27610 +               goto out;
27611 +       if (signal_pending(current)) {
27612 +               ret = -ERESTARTSYS;
27613 +               goto out;
27614 +       }
27615 +       schedule();
27616 +       goto wait;
27617 +
27618 +out:
27619 +       set_current_state(TASK_RUNNING);
27620 +       remove_wait_queue(&vxi->vx_wait, &wait);
27621 +       return ret;
27622 +}
27623 +
27624 +
27625 +
27626 +int vc_wait_exit(struct vx_info *vxi, void __user *data)
27627 +{
27628 +       struct vcmd_wait_exit_v0 vc_data;
27629 +       int ret;
27630 +
27631 +       ret = __wait_exit(vxi);
27632 +       vc_data.reboot_cmd = vxi->reboot_cmd;
27633 +       vc_data.exit_code = vxi->exit_code;
27634 +
27635 +       if (copy_to_user (data, &vc_data, sizeof(vc_data)))
27636 +               ret = -EFAULT;
27637 +       return ret;
27638 +}
27639 +
27640 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/space.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/space.c
27641 --- linux-2.6.19.1/kernel/vserver/space.c       1970-01-01 01:00:00 +0100
27642 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/space.c     2006-12-17 19:44:46 +0100
27643 @@ -0,0 +1,223 @@
27644 +/*
27645 + *  linux/kernel/vserver/space.c
27646 + *
27647 + *  Virtual Server: Context Space Support
27648 + *
27649 + *  Copyright (C) 2003-2006  Herbert Pötzl
27650 + *
27651 + *  V0.01  broken out from context.c 0.07
27652 + *  V0.02  added task locking for namespace
27653 + *  V0.03  broken out vx_enter_namespace
27654 + *  V0.04  added *space support and commands
27655 + *
27656 + */
27657 +
27658 +#include <linux/utsname.h>
27659 +#include <linux/sched.h>
27660 +#include <linux/vs_context.h>
27661 +#include <linux/vserver/space.h>
27662 +#include <linux/vserver/space_cmd.h>
27663 +#include <linux/dcache.h>
27664 +#include <linux/mount.h>
27665 +#include <linux/fs.h>
27666 +
27667 +#include <asm/errno.h>
27668 +#include <asm/uaccess.h>
27669 +
27670 +
27671 +/* namespace functions */
27672 +
27673 +#include <linux/namespace.h>
27674 +
27675 +const struct vcmd_space_mask space_mask = {
27676 +       .mask = CLONE_NEWNS |
27677 +               CLONE_NEWUTS |
27678 +               CLONE_NEWIPC |
27679 +               CLONE_FS
27680 +};
27681 +
27682 +
27683 +/*
27684 + *     build a new nsproxy mix
27685 + *      assumes that both proxies are 'const'
27686 + *     does not touch nsproxy refcounts
27687 + */
27688 +
27689 +struct nsproxy *vs_mix_nsproxy(struct nsproxy *old_nsproxy,
27690 +       struct nsproxy *new_nsproxy, unsigned long mask)
27691 +{
27692 +       struct namespace *old_ns;
27693 +       struct uts_namespace *old_uts;
27694 +       struct ipc_namespace *old_ipc;
27695 +       struct nsproxy *nsproxy;
27696 +
27697 +       old_ns = old_nsproxy->namespace;
27698 +       old_uts = old_nsproxy->uts_ns;
27699 +       old_ipc = old_nsproxy->ipc_ns;
27700 +
27701 +       nsproxy = dup_namespaces(old_nsproxy);
27702 +       if (!nsproxy)
27703 +               goto out;
27704 +
27705 +       if (mask & CLONE_NEWNS) {
27706 +               nsproxy->namespace = new_nsproxy->namespace;
27707 +               if (nsproxy->namespace)
27708 +                       get_namespace(nsproxy->namespace);
27709 +       } else
27710 +               old_ns = NULL;
27711 +
27712 +       if (mask & CLONE_NEWUTS) {
27713 +               nsproxy->uts_ns = new_nsproxy->uts_ns;
27714 +               if (nsproxy->uts_ns)
27715 +                       get_uts_ns(nsproxy->uts_ns);
27716 +       } else
27717 +               old_uts = NULL;
27718 +
27719 +       if (mask & CLONE_NEWIPC) {
27720 +               nsproxy->ipc_ns = new_nsproxy->ipc_ns;
27721 +               if (nsproxy->ipc_ns)
27722 +                       get_ipc_ns(nsproxy->ipc_ns);
27723 +       } else
27724 +               old_ipc = NULL;
27725 +
27726 +       if (old_ns)
27727 +               put_namespace(old_ns);
27728 +       if (old_uts)
27729 +               put_uts_ns(old_uts);
27730 +       if (old_ipc)
27731 +               put_ipc_ns(old_ipc);
27732 +out:
27733 +       return nsproxy;
27734 +}
27735 +
27736 +static inline
27737 +void __vs_merge_nsproxy(struct nsproxy **ptr,
27738 +       struct nsproxy *nsproxy, unsigned long mask)
27739 +{
27740 +       struct nsproxy *old = *ptr;
27741 +       struct nsproxy null_proxy = { .namespace = NULL };
27742 +
27743 +       BUG_ON(!nsproxy);
27744 +
27745 +       if (mask)
27746 +               *ptr = vs_mix_nsproxy(old ? old : &null_proxy,
27747 +                       nsproxy, mask);
27748 +       else {
27749 +               *ptr = nsproxy;
27750 +               get_nsproxy(nsproxy);
27751 +       }
27752 +       if (old)
27753 +               put_nsproxy(old);
27754 +}
27755 +
27756 +static inline
27757 +void __vs_merge_fs(struct fs_struct **ptr, struct fs_struct *fs)
27758 +{
27759 +       struct fs_struct *old = *ptr;
27760 +
27761 +       *ptr = fs;
27762 +       atomic_inc(&fs->count);
27763 +       if (old)
27764 +               put_fs_struct(old);
27765 +}
27766 +
27767 +
27768 +int vx_enter_space(struct vx_info *vxi, unsigned long mask)
27769 +{
27770 +       struct fs_struct *fs = NULL;
27771 +       struct nsproxy *nsproxy;
27772 +
27773 +       if (vx_info_flags(vxi, VXF_INFO_PRIVATE, 0))
27774 +               return -EACCES;
27775 +
27776 +       if (!mask)
27777 +               mask = vxi->vx_nsmask;
27778 +
27779 +       if ((mask & vxi->vx_nsmask) != mask)
27780 +               return -EINVAL;
27781 +
27782 +       nsproxy = vxi->vx_nsproxy;
27783 +       if ((mask & CLONE_FS)) {
27784 +               BUG_ON(!vxi->vx_fs);
27785 +               fs = copy_fs_struct(vxi->vx_fs);
27786 +               if (!fs)
27787 +                       return -ENOMEM;
27788 +       }
27789 +
27790 +       task_lock(current);
27791 +       if (nsproxy)
27792 +               __vs_merge_nsproxy(&current->nsproxy, nsproxy, mask);
27793 +       if (fs)
27794 +               __vs_merge_fs(&current->fs, fs);
27795 +       task_unlock(current);
27796 +       return 0;
27797 +}
27798 +
27799 +
27800 +int vx_set_space(struct vx_info *vxi, unsigned long mask)
27801 +{
27802 +       struct fs_struct *fs, *fs_copy = NULL;
27803 +       struct nsproxy *nsproxy;
27804 +       int ret;
27805 +
27806 +       if (!mask)
27807 +               mask = space_mask.mask;
27808 +
27809 +       if ((mask & space_mask.mask) != mask)
27810 +               return -EINVAL;
27811 +
27812 +       task_lock(current);
27813 +       fs = current->fs;
27814 +       atomic_inc(&fs->count);
27815 +       nsproxy = current->nsproxy;
27816 +       get_nsproxy(nsproxy);
27817 +       task_unlock(current);
27818 +
27819 +       ret = -ENOMEM;
27820 +       if ((mask & CLONE_FS)) {
27821 +               fs_copy = copy_fs_struct(fs);
27822 +               if (!fs_copy)
27823 +                       goto out_put;
27824 +       }
27825 +
27826 +       if (nsproxy)
27827 +               __vs_merge_nsproxy(&vxi->vx_nsproxy, nsproxy, mask);
27828 +       if (fs_copy)
27829 +               __vs_merge_fs(&vxi->vx_fs, fs_copy);
27830 +       vxi->vx_nsmask |= mask;
27831 +
27832 +       ret = 0;
27833 +out_put:
27834 +       put_fs_struct(fs);
27835 +       put_nsproxy(nsproxy);
27836 +       return ret;
27837 +}
27838 +
27839 +
27840 +int vc_enter_space(struct vx_info *vxi, void __user *data)
27841 +{
27842 +       struct vcmd_space_mask vc_data = { .mask = 0 };
27843 +
27844 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
27845 +               return -EFAULT;
27846 +
27847 +       return vx_enter_space(vxi, vc_data.mask);
27848 +}
27849 +
27850 +int vc_set_space(struct vx_info *vxi, void __user *data)
27851 +{
27852 +       struct vcmd_space_mask vc_data = { .mask = 0 };
27853 +
27854 +       if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
27855 +               return -EFAULT;
27856 +
27857 +       return vx_set_space(vxi, vc_data.mask);
27858 +}
27859 +
27860 +int vc_get_space_mask(struct vx_info *vxi, void __user *data)
27861 +{
27862 +       if (copy_to_user(data, &space_mask, sizeof(space_mask)))
27863 +               return -EFAULT;
27864 +       return 0;
27865 +}
27866 +
27867 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/switch.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/switch.c
27868 --- linux-2.6.19.1/kernel/vserver/switch.c      1970-01-01 01:00:00 +0100
27869 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/switch.c    2006-12-17 04:45:00 +0100
27870 @@ -0,0 +1,456 @@
27871 +/*
27872 + *  linux/kernel/vserver/switch.c
27873 + *
27874 + *  Virtual Server: Syscall Switch
27875 + *
27876 + *  Copyright (C) 2003-2006  Herbert Pötzl
27877 + *
27878 + *  V0.01  syscall switch
27879 + *  V0.02  added signal to context
27880 + *  V0.03  added rlimit functions
27881 + *  V0.04  added iattr, task/xid functions
27882 + *  V0.05  added debug/history stuff
27883 + *  V0.06  added compat32 layer
27884 + *  V0.07  vcmd args and perms
27885 + *  V0.08  added status commands
27886 + *
27887 + */
27888 +
27889 +#include <linux/linkage.h>
27890 +#include <linux/sched.h>
27891 +#include <linux/compat.h>
27892 +#include <asm/errno.h>
27893 +
27894 +#include <linux/vs_context.h>
27895 +#include <linux/vs_network.h>
27896 +#include <linux/vserver/switch.h>
27897 +
27898 +static inline
27899 +int vc_get_version(uint32_t id)
27900 +{
27901 +       return VCI_VERSION;
27902 +}
27903 +
27904 +#include "vci_config.h"
27905 +
27906 +static inline
27907 +int vc_get_vci(uint32_t id)
27908 +{
27909 +       return vci_kernel_config();
27910 +}
27911 +
27912 +#include <linux/vserver/context_cmd.h>
27913 +#include <linux/vserver/cvirt_cmd.h>
27914 +#include <linux/vserver/cacct_cmd.h>
27915 +#include <linux/vserver/limit_cmd.h>
27916 +#include <linux/vserver/network_cmd.h>
27917 +#include <linux/vserver/sched_cmd.h>
27918 +#include <linux/vserver/debug_cmd.h>
27919 +#include <linux/vserver/inode_cmd.h>
27920 +#include <linux/vserver/dlimit_cmd.h>
27921 +#include <linux/vserver/signal_cmd.h>
27922 +#include <linux/vserver/space_cmd.h>
27923 +
27924 +#include <linux/vserver/inode.h>
27925 +#include <linux/vserver/dlimit.h>
27926 +
27927 +
27928 +#ifdef CONFIG_COMPAT
27929 +#define __COMPAT(name, id, data, compat)       \
27930 +       (compat) ? name ## _x32 (id, data) : name (id, data)
27931 +#else
27932 +#define __COMPAT(name, id, data, compat)       \
27933 +       name (id, data)
27934 +#endif
27935 +
27936 +
27937 +static inline
27938 +long do_vcmd(uint32_t cmd, uint32_t id,
27939 +       struct vx_info *vxi, struct nx_info *nxi,
27940 +       void __user *data, int compat)
27941 +{
27942 +       switch (cmd) {
27943 +
27944 +       case VCMD_get_version:
27945 +               return vc_get_version(id);
27946 +       case VCMD_get_vci:
27947 +               return vc_get_vci(id);
27948 +
27949 +       case VCMD_task_xid:
27950 +               return vc_task_xid(id, data);
27951 +       case VCMD_vx_info:
27952 +               return vc_vx_info(vxi, data);
27953 +
27954 +       case VCMD_task_nid:
27955 +               return vc_task_nid(id, data);
27956 +       case VCMD_nx_info:
27957 +               return vc_nx_info(nxi, data);
27958 +
27959 +       case VCMD_set_space_v0:
27960 +       /* this is version 1 */
27961 +       case VCMD_set_space:
27962 +               return vc_set_space(vxi, data);
27963 +
27964 +       case VCMD_get_space_mask:
27965 +               return vc_get_space_mask(vxi, data);
27966 +
27967 +#ifdef CONFIG_IA32_EMULATION
27968 +       case VCMD_get_rlimit:
27969 +               return __COMPAT(vc_get_rlimit, vxi, data, compat);
27970 +       case VCMD_set_rlimit:
27971 +               return __COMPAT(vc_set_rlimit, vxi, data, compat);
27972 +#else
27973 +       case VCMD_get_rlimit:
27974 +               return vc_get_rlimit(vxi, data);
27975 +       case VCMD_set_rlimit:
27976 +               return vc_set_rlimit(vxi, data);
27977 +#endif
27978 +       case VCMD_get_rlimit_mask:
27979 +               return vc_get_rlimit_mask(id, data);
27980 +       case VCMD_reset_minmax:
27981 +               return vc_reset_minmax(vxi, data);
27982 +
27983 +       case VCMD_get_vhi_name:
27984 +               return vc_get_vhi_name(vxi, data);
27985 +       case VCMD_set_vhi_name:
27986 +               return vc_set_vhi_name(vxi, data);
27987 +
27988 +       case VCMD_ctx_stat:
27989 +               return vc_ctx_stat(vxi, data);
27990 +       case VCMD_virt_stat:
27991 +               return vc_virt_stat(vxi, data);
27992 +       case VCMD_sock_stat:
27993 +               return vc_sock_stat(vxi, data);
27994 +       case VCMD_rlimit_stat:
27995 +               return vc_rlimit_stat(vxi, data);
27996 +
27997 +       case VCMD_set_cflags:
27998 +               return vc_set_cflags(vxi, data);
27999 +       case VCMD_get_cflags:
28000 +               return vc_get_cflags(vxi, data);
28001 +
28002 +       case VCMD_set_ccaps_v0:
28003 +               return vc_set_ccaps_v0(vxi, data);
28004 +       /* this is version 1 */
28005 +       case VCMD_set_ccaps:
28006 +               return vc_set_ccaps(vxi, data);
28007 +       case VCMD_get_ccaps_v0:
28008 +               return vc_get_ccaps_v0(vxi, data);
28009 +       /* this is version 1 */
28010 +       case VCMD_get_ccaps:
28011 +               return vc_get_ccaps(vxi, data);
28012 +       case VCMD_set_bcaps:
28013 +               return vc_set_bcaps(vxi, data);
28014 +       case VCMD_get_bcaps:
28015 +               return vc_get_bcaps(vxi, data);
28016 +
28017 +       case VCMD_set_nflags:
28018 +               return vc_set_nflags(nxi, data);
28019 +       case VCMD_get_nflags:
28020 +               return vc_get_nflags(nxi, data);
28021 +
28022 +       case VCMD_set_ncaps:
28023 +               return vc_set_ncaps(nxi, data);
28024 +       case VCMD_get_ncaps:
28025 +               return vc_get_ncaps(nxi, data);
28026 +
28027 +       case VCMD_set_sched_v3:
28028 +               return vc_set_sched_v3(vxi, data);
28029 +       /* this is version 4 */
28030 +       case VCMD_set_sched:
28031 +               return vc_set_sched(vxi, data);
28032 +
28033 +       case VCMD_add_dlimit:
28034 +               return __COMPAT(vc_add_dlimit, id, data, compat);
28035 +       case VCMD_rem_dlimit:
28036 +               return __COMPAT(vc_rem_dlimit, id, data, compat);
28037 +       case VCMD_set_dlimit:
28038 +               return __COMPAT(vc_set_dlimit, id, data, compat);
28039 +       case VCMD_get_dlimit:
28040 +               return __COMPAT(vc_get_dlimit, id, data, compat);
28041 +
28042 +       case VCMD_ctx_kill:
28043 +               return vc_ctx_kill(vxi, data);
28044 +
28045 +       case VCMD_wait_exit:
28046 +               return vc_wait_exit(vxi, data);
28047 +
28048 +       case VCMD_get_iattr:
28049 +               return __COMPAT(vc_get_iattr, id, data, compat);
28050 +       case VCMD_set_iattr:
28051 +               return __COMPAT(vc_set_iattr, id, data, compat);
28052 +
28053 +       case VCMD_enter_space_v0:
28054 +               return vc_enter_space(vxi, NULL);
28055 +       /* this is version 1 */
28056 +       case VCMD_enter_space:
28057 +               return vc_enter_space(vxi, data);
28058 +
28059 +       case VCMD_ctx_create_v0:
28060 +               return vc_ctx_create(id, NULL);
28061 +       case VCMD_ctx_create:
28062 +               return vc_ctx_create(id, data);
28063 +       case VCMD_ctx_migrate_v0:
28064 +               return vc_ctx_migrate(vxi, NULL);
28065 +       case VCMD_ctx_migrate:
28066 +               return vc_ctx_migrate(vxi, data);
28067 +
28068 +       case VCMD_net_create_v0:
28069 +               return vc_net_create(id, NULL);
28070 +       case VCMD_net_create:
28071 +               return vc_net_create(id, data);
28072 +       case VCMD_net_migrate:
28073 +               return vc_net_migrate(nxi, data);
28074 +       case VCMD_net_add:
28075 +               return vc_net_add(nxi, data);
28076 +       case VCMD_net_remove:
28077 +               return vc_net_remove(nxi, data);
28078 +
28079 +#ifdef CONFIG_VSERVER_HISTORY
28080 +       case VCMD_dump_history:
28081 +               return vc_dump_history(id);
28082 +       case VCMD_read_history:
28083 +               return __COMPAT(vc_read_history, id, data, compat);
28084 +#endif
28085 +#ifdef CONFIG_VSERVER_MONITOR
28086 +       case VCMD_read_monitor:
28087 +               return __COMPAT(vc_read_monitor, id, data, compat);
28088 +#endif
28089 +       default:
28090 +               vxwprintk(1, "unimplemented VCMD_%02d_%d[%d]",
28091 +                       VC_CATEGORY(cmd), VC_COMMAND(cmd), VC_VERSION(cmd));
28092 +       }
28093 +       return -ENOSYS;
28094 +}
28095 +
28096 +
28097 +#define        __VCMD(vcmd, _perm, _args, _flags)              \
28098 +       case VCMD_ ## vcmd: perm = _perm;               \
28099 +               args = _args; flags = _flags; break
28100 +
28101 +
28102 +#define VCA_NONE       0x00
28103 +#define VCA_VXI                0x01
28104 +#define VCA_NXI                0x02
28105 +
28106 +#define VCF_NONE       0x00
28107 +#define VCF_INFO       0x01
28108 +#define VCF_ADMIN      0x02
28109 +#define VCF_ARES       0x06    /* includes admin */
28110 +#define VCF_SETUP      0x08
28111 +
28112 +
28113 +static inline
28114 +long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
28115 +{
28116 +       long ret;
28117 +       int permit = -1, state = 0;
28118 +       int perm = -1, args = 0, flags = 0;
28119 +       struct vx_info *vxi = NULL;
28120 +       struct nx_info *nxi = NULL;
28121 +
28122 +       switch (cmd) {
28123 +       /* unpriviledged commands */
28124 +       __VCMD(get_version,      0, VCA_NONE,   0);
28125 +       __VCMD(get_vci,          0, VCA_NONE,   0);
28126 +       __VCMD(get_rlimit_mask,  0, VCA_NONE,   0);
28127 +       __VCMD(get_space_mask,   0, VCA_NONE,   0);
28128 +
28129 +       /* info commands */
28130 +       __VCMD(task_xid,         2, VCA_NONE,   0);
28131 +       __VCMD(reset_minmax,     2, VCA_VXI,    0);
28132 +       __VCMD(vx_info,          3, VCA_VXI,    VCF_INFO);
28133 +       __VCMD(get_bcaps,        3, VCA_VXI,    VCF_INFO);
28134 +       __VCMD(get_ccaps_v0,     3, VCA_VXI,    VCF_INFO);
28135 +       __VCMD(get_ccaps,        3, VCA_VXI,    VCF_INFO);
28136 +       __VCMD(get_cflags,       3, VCA_VXI,    VCF_INFO);
28137 +       __VCMD(get_vhi_name,     3, VCA_VXI,    VCF_INFO);
28138 +       __VCMD(get_rlimit,       3, VCA_VXI,    VCF_INFO);
28139 +
28140 +       __VCMD(ctx_stat,         3, VCA_VXI,    VCF_INFO);
28141 +       __VCMD(virt_stat,        3, VCA_VXI,    VCF_INFO);
28142 +       __VCMD(sock_stat,        3, VCA_VXI,    VCF_INFO);
28143 +       __VCMD(rlimit_stat,      3, VCA_VXI,    VCF_INFO);
28144 +
28145 +       __VCMD(task_nid,         2, VCA_NONE,   0);
28146 +       __VCMD(nx_info,          3, VCA_NXI,    VCF_INFO);
28147 +       __VCMD(get_ncaps,        3, VCA_NXI,    VCF_INFO);
28148 +       __VCMD(get_nflags,       3, VCA_NXI,    VCF_INFO);
28149 +
28150 +       __VCMD(get_iattr,        2, VCA_NONE,   0);
28151 +       __VCMD(get_dlimit,       3, VCA_NONE,   VCF_INFO);
28152 +
28153 +       /* lower admin commands */
28154 +       __VCMD(wait_exit,        4, VCA_VXI,    VCF_INFO);
28155 +       __VCMD(ctx_create_v0,    5, VCA_NONE,   0);
28156 +       __VCMD(ctx_create,       5, VCA_NONE,   0);
28157 +       __VCMD(ctx_migrate_v0,   5, VCA_VXI,    VCF_ADMIN);
28158 +       __VCMD(ctx_migrate,      5, VCA_VXI,    VCF_ADMIN);
28159 +       __VCMD(enter_space_v0,   5, VCA_VXI,    VCF_ADMIN);
28160 +       __VCMD(enter_space,      5, VCA_VXI,    VCF_ADMIN);
28161 +
28162 +       __VCMD(net_create_v0,    5, VCA_NONE,   0);
28163 +       __VCMD(net_create,       5, VCA_NONE,   0);
28164 +       __VCMD(net_migrate,      5, VCA_NXI,    VCF_ADMIN);
28165 +
28166 +       /* higher admin commands */
28167 +       __VCMD(ctx_kill,         6, VCA_VXI,    VCF_ARES);
28168 +       __VCMD(set_space_v0,     7, VCA_VXI,    VCF_ARES|VCF_SETUP);
28169 +       __VCMD(set_space,        7, VCA_VXI,    VCF_ARES|VCF_SETUP);
28170 +
28171 +       __VCMD(set_ccaps_v0,     7, VCA_VXI,    VCF_ARES|VCF_SETUP);
28172 +       __VCMD(set_ccaps,        7, VCA_VXI,    VCF_ARES|VCF_SETUP);
28173 +       __VCMD(set_bcaps,        7, VCA_VXI,    VCF_ARES|VCF_SETUP);
28174 +       __VCMD(set_cflags,       7, VCA_VXI,    VCF_ARES|VCF_SETUP);
28175 +
28176 +       __VCMD(set_vhi_name,     7, VCA_VXI,    VCF_ARES|VCF_SETUP);
28177 +       __VCMD(set_rlimit,       7, VCA_VXI,    VCF_ARES|VCF_SETUP);
28178 +       __VCMD(set_sched,        7, VCA_VXI,    VCF_ARES|VCF_SETUP);
28179 +       __VCMD(set_sched_v2,     7, VCA_VXI,    VCF_ARES|VCF_SETUP);
28180 +       __VCMD(set_sched_v3,     7, VCA_VXI,    VCF_ARES|VCF_SETUP);
28181 +
28182 +       __VCMD(set_ncaps,        7, VCA_NXI,    VCF_ARES|VCF_SETUP);
28183 +       __VCMD(set_nflags,       7, VCA_NXI,    VCF_ARES|VCF_SETUP);
28184 +       __VCMD(net_add,          8, VCA_NXI,    VCF_ARES|VCF_SETUP);
28185 +       __VCMD(net_remove,       8, VCA_NXI,    VCF_ARES|VCF_SETUP);
28186 +
28187 +       __VCMD(set_iattr,        7, VCA_NONE,   0);
28188 +       __VCMD(set_dlimit,       7, VCA_NONE,   VCF_ARES);
28189 +       __VCMD(add_dlimit,       8, VCA_NONE,   VCF_ARES);
28190 +       __VCMD(rem_dlimit,       8, VCA_NONE,   VCF_ARES);
28191 +
28192 +       /* debug level admin commands */
28193 +#ifdef CONFIG_VSERVER_HISTORY
28194 +       __VCMD(dump_history,     9, VCA_NONE,   0);
28195 +       __VCMD(read_history,     9, VCA_NONE,   0);
28196 +#endif
28197 +#ifdef CONFIG_VSERVER_MONITOR
28198 +       __VCMD(read_monitor,     9, VCA_NONE,   0);
28199 +#endif
28200 +       default:
28201 +               perm = -1;
28202 +       }
28203 +
28204 +       vxdprintk(VXD_CBIT(switch, 0),
28205 +               "vc: VCMD_%02d_%d[%d], %d,%p [%d,%d,%x,%x]",
28206 +               VC_CATEGORY(cmd), VC_COMMAND(cmd),
28207 +               VC_VERSION(cmd), id, data, compat,
28208 +               perm, args, flags);
28209 +
28210 +       ret = -ENOSYS;
28211 +       if (perm < 0)
28212 +               goto out;
28213 +
28214 +       state = 1;
28215 +       if (!capable(CAP_CONTEXT))
28216 +               goto out;
28217 +
28218 +       state = 2;
28219 +       /* moved here from the individual commands */
28220 +       ret = -EPERM;
28221 +       if ((perm > 1) && !capable(CAP_SYS_ADMIN))
28222 +               goto out;
28223 +
28224 +       state = 3;
28225 +       /* vcmd involves resource management  */
28226 +       ret = -EPERM;
28227 +       if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
28228 +               goto out;
28229 +
28230 +       state = 4;
28231 +       /* various legacy exceptions */
28232 +       switch (cmd) {
28233 +       /* will go away when admin is a cap */
28234 +       case VCMD_ctx_migrate_v0:
28235 +       case VCMD_ctx_migrate:
28236 +               if (id == 1) {
28237 +                       current->xid = 1;
28238 +                       ret = 1;
28239 +                       goto out;
28240 +               }
28241 +               break;
28242 +
28243 +       /* legacy special casing */
28244 +       case VCMD_set_space_v0:
28245 +               id = -1;
28246 +               break;
28247 +       }
28248 +
28249 +       /* vcmds are fine by default */
28250 +       permit = 1;
28251 +
28252 +       /* admin type vcmds require admin ... */
28253 +       if (flags & VCF_ADMIN)
28254 +               permit = vx_check(0, VS_ADMIN) ? 1 : 0;
28255 +
28256 +       /* ... but setup type vcmds override that */
28257 +       if (!permit && (flags & VCF_SETUP))
28258 +               permit = vx_flags(VXF_STATE_SETUP, 0) ? 2 : 0;
28259 +
28260 +       state = 5;
28261 +       ret = -EPERM;
28262 +       if (!permit)
28263 +               goto out;
28264 +
28265 +       state = 6;
28266 +       ret = -ESRCH;
28267 +       if (args & VCA_VXI) {
28268 +               vxi = lookup_vx_info(id);
28269 +               if (!vxi)
28270 +                       goto out;
28271 +
28272 +               if ((flags & VCF_ADMIN) &&
28273 +                       /* special case kill for shutdown */
28274 +                       (cmd != VCMD_ctx_kill) &&
28275 +                       /* can context be administrated? */
28276 +                       !vx_info_flags(vxi, VXF_STATE_ADMIN, 0)) {
28277 +                       ret = -EACCES;
28278 +                       goto out_vxi;
28279 +               }
28280 +       }
28281 +       state = 7;
28282 +       if (args & VCA_NXI) {
28283 +               nxi = lookup_nx_info(id);
28284 +               if (!nxi)
28285 +                       goto out_vxi;
28286 +
28287 +               if ((flags & VCF_ADMIN) &&
28288 +                       /* can context be administrated? */
28289 +                       !nx_info_flags(nxi, NXF_STATE_ADMIN, 0)) {
28290 +                       ret = -EACCES;
28291 +                       goto out_nxi;
28292 +               }
28293 +       }
28294 +
28295 +       state = 8;
28296 +       ret = do_vcmd(cmd, id, vxi, nxi, data, compat);
28297 +
28298 +out_nxi:
28299 +       if (args & VCA_NXI)
28300 +               put_nx_info(nxi);
28301 +out_vxi:
28302 +       if (args & VCA_VXI)
28303 +               put_vx_info(vxi);
28304 +out:
28305 +       vxdprintk(VXD_CBIT(switch, 1),
28306 +               "vc: VCMD_%02d_%d[%d] = %08lx(%ld) [%d,%d]",
28307 +               VC_CATEGORY(cmd), VC_COMMAND(cmd),
28308 +               VC_VERSION(cmd), ret, ret, state, permit);
28309 +       return ret;
28310 +}
28311 +
28312 +asmlinkage long
28313 +sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
28314 +{
28315 +       return do_vserver(cmd, id, data, 0);
28316 +}
28317 +
28318 +#ifdef CONFIG_COMPAT
28319 +
28320 +asmlinkage long
28321 +sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
28322 +{
28323 +       return do_vserver(cmd, id, data, 1);
28324 +}
28325 +
28326 +#endif /* CONFIG_COMPAT */
28327 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/sysctl.c linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sysctl.c
28328 --- linux-2.6.19.1/kernel/vserver/sysctl.c      1970-01-01 01:00:00 +0100
28329 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/sysctl.c    2006-11-08 04:57:40 +0100
28330 @@ -0,0 +1,242 @@
28331 +/*
28332 + *  kernel/vserver/sysctl.c
28333 + *
28334 + *  Virtual Context Support
28335 + *
28336 + *  Copyright (C) 2004-2005  Herbert Pötzl
28337 + *
28338 + *  V0.01  basic structure
28339 + *
28340 + */
28341 +
28342 +#include <linux/errno.h>
28343 +#include <linux/module.h>
28344 +#include <linux/types.h>
28345 +#include <linux/ctype.h>
28346 +#include <linux/sysctl.h>
28347 +#include <linux/parser.h>
28348 +#include <linux/fs.h>
28349 +
28350 +#include <asm/uaccess.h>
28351 +#include <asm/unistd.h>
28352 +
28353 +
28354 +#define CTL_VSERVER    4242    /* unused? */
28355 +
28356 +enum {
28357 +       CTL_DEBUG_ERROR         = 0,
28358 +       CTL_DEBUG_SWITCH        = 1,
28359 +       CTL_DEBUG_XID,
28360 +       CTL_DEBUG_NID,
28361 +       CTL_DEBUG_TAG,
28362 +       CTL_DEBUG_NET,
28363 +       CTL_DEBUG_LIMIT,
28364 +       CTL_DEBUG_CRES,
28365 +       CTL_DEBUG_DLIM,
28366 +       CTL_DEBUG_QUOTA,
28367 +       CTL_DEBUG_CVIRT,
28368 +       CTL_DEBUG_MISC,
28369 +};
28370 +
28371 +
28372 +unsigned int vx_debug_switch   = 0;
28373 +unsigned int vx_debug_xid      = 0;
28374 +unsigned int vx_debug_nid      = 0;
28375 +unsigned int vx_debug_tag      = 0;
28376 +unsigned int vx_debug_net      = 0;
28377 +unsigned int vx_debug_limit    = 0;
28378 +unsigned int vx_debug_cres     = 0;
28379 +unsigned int vx_debug_dlim     = 0;
28380 +unsigned int vx_debug_quota    = 0;
28381 +unsigned int vx_debug_cvirt    = 0;
28382 +unsigned int vx_debug_misc     = 0;
28383 +
28384 +
28385 +static struct ctl_table_header *vserver_table_header;
28386 +static ctl_table vserver_table[];
28387 +
28388 +
28389 +void vserver_register_sysctl(void)
28390 +{
28391 +       if (!vserver_table_header) {
28392 +               vserver_table_header = register_sysctl_table(vserver_table, 1);
28393 +       }
28394 +
28395 +}
28396 +
28397 +void vserver_unregister_sysctl(void)
28398 +{
28399 +       if (vserver_table_header) {
28400 +               unregister_sysctl_table(vserver_table_header);
28401 +               vserver_table_header = NULL;
28402 +       }
28403 +}
28404 +
28405 +
28406 +static int proc_dodebug(ctl_table *table, int write,
28407 +       struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
28408 +{
28409 +       char            tmpbuf[20], *p, c;
28410 +       unsigned int    value;
28411 +       size_t          left, len;
28412 +
28413 +       if ((*ppos && !write) || !*lenp) {
28414 +               *lenp = 0;
28415 +               return 0;
28416 +       }
28417 +
28418 +       left = *lenp;
28419 +
28420 +       if (write) {
28421 +               if (!access_ok(VERIFY_READ, buffer, left))
28422 +                       return -EFAULT;
28423 +               p = (char *) buffer;
28424 +               while (left && __get_user(c, p) >= 0 && isspace(c))
28425 +                       left--, p++;
28426 +               if (!left)
28427 +                       goto done;
28428 +
28429 +               if (left > sizeof(tmpbuf) - 1)
28430 +                       return -EINVAL;
28431 +               if (copy_from_user(tmpbuf, p, left))
28432 +                       return -EFAULT;
28433 +               tmpbuf[left] = '\0';
28434 +
28435 +               for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
28436 +                       value = 10 * value + (*p - '0');
28437 +               if (*p && !isspace(*p))
28438 +                       return -EINVAL;
28439 +               while (left && isspace(*p))
28440 +                       left--, p++;
28441 +               *(unsigned int *) table->data = value;
28442 +       } else {
28443 +               if (!access_ok(VERIFY_WRITE, buffer, left))
28444 +                       return -EFAULT;
28445 +               len = sprintf(tmpbuf, "%d", *(unsigned int *) table->data);
28446 +               if (len > left)
28447 +                       len = left;
28448 +               if (__copy_to_user(buffer, tmpbuf, len))
28449 +                       return -EFAULT;
28450 +               if ((left -= len) > 0) {
28451 +                       if (put_user('\n', (char *)buffer + len))
28452 +                               return -EFAULT;
28453 +                       left--;
28454 +               }
28455 +       }
28456 +
28457 +done:
28458 +       *lenp -= left;
28459 +       *ppos += *lenp;
28460 +       return 0;
28461 +}
28462 +
28463 +
28464 +#define        CTL_ENTRY(ctl, name)                            \
28465 +       {                                               \
28466 +               .ctl_name       = ctl,                  \
28467 +               .procname       = #name,                \
28468 +               .data           = &vx_##name,           \
28469 +               .maxlen         = sizeof(int),          \
28470 +               .mode           = 0644,                 \
28471 +               .proc_handler   = &proc_dodebug         \
28472 +       }
28473 +
28474 +static ctl_table debug_table[] = {
28475 +       CTL_ENTRY (CTL_DEBUG_SWITCH,    debug_switch),
28476 +       CTL_ENTRY (CTL_DEBUG_XID,       debug_xid),
28477 +       CTL_ENTRY (CTL_DEBUG_NID,       debug_nid),
28478 +       CTL_ENTRY (CTL_DEBUG_TAG,       debug_tag),
28479 +       CTL_ENTRY (CTL_DEBUG_NET,       debug_net),
28480 +       CTL_ENTRY (CTL_DEBUG_LIMIT,     debug_limit),
28481 +       CTL_ENTRY (CTL_DEBUG_CRES,      debug_cres),
28482 +       CTL_ENTRY (CTL_DEBUG_DLIM,      debug_dlim),
28483 +       CTL_ENTRY (CTL_DEBUG_QUOTA,     debug_quota),
28484 +       CTL_ENTRY (CTL_DEBUG_CVIRT,     debug_cvirt),
28485 +       CTL_ENTRY (CTL_DEBUG_MISC,      debug_misc),
28486 +       { .ctl_name = 0 }
28487 +};
28488 +
28489 +static ctl_table vserver_table[] = {
28490 +       {
28491 +               .ctl_name       = CTL_VSERVER,
28492 +               .procname       = "vserver",
28493 +               .mode           = 0555,
28494 +               .child          = debug_table
28495 +       },
28496 +       { .ctl_name = 0 }
28497 +};
28498 +
28499 +
28500 +static match_table_t tokens = {
28501 +       { CTL_DEBUG_SWITCH,     "switch=%x"     },
28502 +       { CTL_DEBUG_XID,        "xid=%x"        },
28503 +       { CTL_DEBUG_NID,        "nid=%x"        },
28504 +       { CTL_DEBUG_TAG,        "tag=%x"        },
28505 +       { CTL_DEBUG_NET,        "net=%x"        },
28506 +       { CTL_DEBUG_LIMIT,      "limit=%x"      },
28507 +       { CTL_DEBUG_CRES,       "cres=%x"       },
28508 +       { CTL_DEBUG_DLIM,       "dlim=%x"       },
28509 +       { CTL_DEBUG_QUOTA,      "quota=%x"      },
28510 +       { CTL_DEBUG_CVIRT,      "cvirt=%x"      },
28511 +       { CTL_DEBUG_MISC,       "misc=%x"       },
28512 +       { CTL_DEBUG_ERROR,      NULL            }
28513 +};
28514 +
28515 +#define        HANDLE_CASE(id, name, val)                              \
28516 +       case CTL_DEBUG_ ## id:                                  \
28517 +               vx_debug_ ## name = val;                        \
28518 +               printk("vs_debug_" #name "=0x%x\n", val);       \
28519 +               break
28520 +
28521 +
28522 +static int __init vs_debug_setup(char *str)
28523 +{
28524 +       char *p;
28525 +       int token;
28526 +
28527 +       printk("vs_debug_setup(%s)\n", str);
28528 +       while ((p = strsep(&str, ",")) != NULL) {
28529 +               substring_t args[MAX_OPT_ARGS];
28530 +               unsigned int value;
28531 +
28532 +               if (!*p)
28533 +                       continue;
28534 +
28535 +               token = match_token(p, tokens, args);
28536 +               value = (token>0)?simple_strtoul(args[0].from, NULL, 0):0;
28537 +
28538 +               switch (token) {
28539 +               HANDLE_CASE(SWITCH, switch, value);
28540 +               HANDLE_CASE(XID,    xid,    value);
28541 +               HANDLE_CASE(NID,    nid,    value);
28542 +               HANDLE_CASE(TAG,    tag,    value);
28543 +               HANDLE_CASE(NET,    net,    value);
28544 +               HANDLE_CASE(LIMIT,  limit,  value);
28545 +               HANDLE_CASE(CRES,   cres,   value);
28546 +               HANDLE_CASE(DLIM,   dlim,   value);
28547 +               HANDLE_CASE(QUOTA,  quota,  value);
28548 +               HANDLE_CASE(CVIRT,  cvirt,  value);
28549 +               HANDLE_CASE(MISC,   misc,   value);
28550 +               default:
28551 +                       return -EINVAL;
28552 +                       break;
28553 +               }
28554 +       }
28555 +       return 1;
28556 +}
28557 +
28558 +__setup("vsdebug=", vs_debug_setup);
28559 +
28560 +
28561 +
28562 +EXPORT_SYMBOL_GPL(vx_debug_switch);
28563 +EXPORT_SYMBOL_GPL(vx_debug_xid);
28564 +EXPORT_SYMBOL_GPL(vx_debug_nid);
28565 +EXPORT_SYMBOL_GPL(vx_debug_net);
28566 +EXPORT_SYMBOL_GPL(vx_debug_limit);
28567 +EXPORT_SYMBOL_GPL(vx_debug_cres);
28568 +EXPORT_SYMBOL_GPL(vx_debug_dlim);
28569 +EXPORT_SYMBOL_GPL(vx_debug_quota);
28570 +EXPORT_SYMBOL_GPL(vx_debug_cvirt);
28571 +EXPORT_SYMBOL_GPL(vx_debug_misc);
28572 +
28573 diff -NurpP --minimal linux-2.6.19.1/kernel/vserver/vci_config.h linux-2.6.19.1-vs2.3.0.6/kernel/vserver/vci_config.h
28574 --- linux-2.6.19.1/kernel/vserver/vci_config.h  1970-01-01 01:00:00 +0100
28575 +++ linux-2.6.19.1-vs2.3.0.6/kernel/vserver/vci_config.h        2006-12-17 04:40:29 +0100
28576 @@ -0,0 +1,74 @@
28577 +
28578 +enum {
28579 +       VCI_KCBIT_NO_DYNAMIC = 0,
28580 +       VCI_KCBIT_LEGACY = 1,
28581 +       VCI_KCBIT_LEGACYNET = 2,
28582 +       VCI_KCBIT_NGNET = 3,
28583 +
28584 +       VCI_KCBIT_PROC_SECURE = 4,
28585 +       VCI_KCBIT_HARDCPU = 5,
28586 +       VCI_KCBIT_IDLELIMIT = 6,
28587 +       VCI_KCBIT_IDLETIME = 7,
28588 +
28589 +       VCI_KCBIT_COWBL = 8,
28590 +       VCI_KCBIT_FULLCOWBL = 9,
28591 +       VCI_KCBIT_SPACES = 10,
28592 +
28593 +       VCI_KCBIT_LEGACY_VERSION = 15,
28594 +       VCI_KCBIT_DEBUG = 16,
28595 +       VCI_KCBIT_HISTORY = 20,
28596 +       VCI_KCBIT_TAGGED = 24,
28597 +};
28598 +
28599 +
28600 +static inline uint32_t vci_kernel_config(void)
28601 +{
28602 +       return
28603 +       (1 << VCI_KCBIT_NO_DYNAMIC) |
28604 +       (1 << VCI_KCBIT_NGNET) |
28605 +
28606 +       /* configured features */
28607 +#ifdef CONFIG_VSERVER_PROC_SECURE
28608 +       (1 << VCI_KCBIT_PROC_SECURE) |
28609 +#endif
28610 +#ifdef CONFIG_VSERVER_HARDCPU
28611 +       (1 << VCI_KCBIT_HARDCPU) |
28612 +#endif
28613 +#ifdef CONFIG_VSERVER_IDLELIMIT
28614 +       (1 << VCI_KCBIT_IDLELIMIT) |
28615 +#endif
28616 +#ifdef CONFIG_VSERVER_IDLETIME
28617 +       (1 << VCI_KCBIT_IDLETIME) |
28618 +#endif
28619 +#ifdef CONFIG_VSERVER_COWBL
28620 +       (1 << VCI_KCBIT_COWBL) |
28621 +       (1 << VCI_KCBIT_FULLCOWBL) |
28622 +#endif
28623 +       (1 << VCI_KCBIT_SPACES) |
28624 +
28625 +       /* debug options */
28626 +#ifdef CONFIG_VSERVER_DEBUG
28627 +       (1 << VCI_KCBIT_DEBUG) |
28628 +#endif
28629 +#ifdef CONFIG_VSERVER_HISTORY
28630 +       (1 << VCI_KCBIT_HISTORY) |
28631 +#endif
28632 +       /* inode context tagging */
28633 +#if    defined(CONFIG_TAGGING_NONE)
28634 +       (0 << VCI_KCBIT_TAGGED) |
28635 +#elif  defined(CONFIG_TAGGING_UID16)
28636 +       (1 << VCI_KCBIT_TAGGED) |
28637 +#elif  defined(CONFIG_TAGGING_GID16)
28638 +       (2 << VCI_KCBIT_TAGGED) |
28639 +#elif  defined(CONFIG_TAGGING_ID24)
28640 +       (3 << VCI_KCBIT_TAGGED) |
28641 +#elif  defined(CONFIG_TAGGING_INTERN)
28642 +       (4 << VCI_KCBIT_TAGGED) |
28643 +#elif  defined(CONFIG_TAGGING_RUNTIME)
28644 +       (5 << VCI_KCBIT_TAGGED) |
28645 +#else
28646 +       (7 << VCI_KCBIT_TAGGED) |
28647 +#endif
28648 +       0;
28649 +}
28650 +
28651 diff -NurpP --minimal linux-2.6.19.1/mm/filemap.c linux-2.6.19.1-vs2.3.0.6/mm/filemap.c
28652 --- linux-2.6.19.1/mm/filemap.c 2006-11-30 21:19:44 +0100
28653 +++ linux-2.6.19.1-vs2.3.0.6/mm/filemap.c       2006-11-08 22:42:35 +0100
28654 @@ -1236,6 +1236,31 @@ int file_send_actor(read_descriptor_t * 
28655         return written;
28656  }
28657  
28658 +/* FIXME: It would be as simple as this, if we had a (void __user*) to write.
28659 + * We already have a kernel buffer, so it should be even simpler, right? ;)
28660 + *
28661 + * Yes, sorta.  After duplicating the complete path of generic_file_write(),
28662 + * at least some special cases could be removed, so the copy is simpler than
28663 + * the original.  But it remains a copy, so overall complexity increases.
28664 + */
28665 +static ssize_t
28666 +generic_kernel_file_write(struct file *, const char *, size_t, loff_t *);
28667 +
28668 +ssize_t generic_file_sendpage(struct file *file, struct page *page,
28669 +               int offset, size_t size, loff_t *ppos, int more)
28670 +{
28671 +       ssize_t ret;
28672 +       char *kaddr;
28673 +
28674 +       kaddr = kmap(page);
28675 +       ret = generic_kernel_file_write(file, kaddr + offset, size, ppos);
28676 +       kunmap(page);
28677 +
28678 +       return ret;
28679 +}
28680 +
28681 +EXPORT_SYMBOL(generic_file_sendpage);
28682 +
28683  ssize_t generic_file_sendfile(struct file *in_file, loff_t *ppos,
28684                          size_t count, read_actor_t actor, void *target)
28685  {
28686 @@ -1913,6 +1938,19 @@ int remove_suid(struct dentry *dentry)
28687  }
28688  EXPORT_SYMBOL(remove_suid);
28689  
28690 +static inline size_t
28691 +filemap_copy_from_kernel(struct page *page, unsigned long offset,
28692 +                        const char *buf, unsigned bytes)
28693 +{
28694 +       char *kaddr;
28695 +
28696 +       kaddr = kmap(page);
28697 +       memcpy(kaddr + offset, buf, bytes);
28698 +       kunmap(page);
28699 +
28700 +       return bytes;
28701 +}
28702 +
28703  size_t
28704  __filemap_copy_from_user_iovec_inatomic(char *vaddr,
28705                         const struct iovec *iov, size_t base, size_t bytes)
28706 @@ -2219,6 +2257,175 @@ zero_length_segment:
28707  }
28708  EXPORT_SYMBOL(generic_file_buffered_write);
28709  
28710 +static inline void
28711 +filemap_set_next_kvec(const struct kvec **iovp, size_t *basep, size_t bytes)
28712 +{
28713 +       const struct kvec *iov = *iovp;
28714 +       size_t base = *basep;
28715 +
28716 +       while (bytes) {
28717 +               int copy = min(bytes, iov->iov_len - base);
28718 +
28719 +               bytes -= copy;
28720 +               base += copy;
28721 +               if (iov->iov_len == base) {
28722 +                       iov++;
28723 +                       base = 0;
28724 +               }
28725 +       }
28726 +       *iovp = iov;
28727 +       *basep = base;
28728 +}
28729 +
28730 +/*
28731 + * TODO:
28732 + * This largely tries to copy generic_file_aio_write_nolock(), although it
28733 + * doesn't have to be nearly as generic.  A real cleanup should either
28734 + * merge this into generic_file_aio_write_nolock() as well or keep it special
28735 + * and remove as much code as possible.
28736 + */
28737 +static ssize_t
28738 +generic_kernel_file_aio_write_nolock(struct kiocb *iocb, const struct kvec*iov,
28739 +                                    unsigned long nr_segs, loff_t *ppos)
28740 +{
28741 +       struct file *file = iocb->ki_filp;
28742 +       struct address_space * mapping = file->f_mapping;
28743 +       const struct address_space_operations *a_ops = mapping->a_ops;
28744 +       size_t ocount;          /* original count */
28745 +       size_t count;           /* after file limit checks */
28746 +       struct inode    *inode = mapping->host;
28747 +       long            status = 0;
28748 +       loff_t          pos;
28749 +       struct page     *page;
28750 +       struct page     *cached_page = NULL;
28751 +       const int       isblk = S_ISBLK(inode->i_mode);
28752 +       ssize_t         written;
28753 +       ssize_t         err;
28754 +       size_t          bytes;
28755 +       struct pagevec  lru_pvec;
28756 +       const struct kvec *cur_iov = iov; /* current kvec */
28757 +       size_t          iov_base = 0;      /* offset in the current kvec */
28758 +       unsigned long   seg;
28759 +       char            *buf;
28760 +
28761 +       ocount = 0;
28762 +       for (seg = 0; seg < nr_segs; seg++) {
28763 +               const struct kvec *iv = &iov[seg];
28764 +
28765 +               /*
28766 +                * If any segment has a negative length, or the cumulative
28767 +                * length ever wraps negative then return -EINVAL.
28768 +                */
28769 +               ocount += iv->iov_len;
28770 +               if (unlikely((ssize_t)(ocount|iv->iov_len) < 0))
28771 +                       return -EINVAL;
28772 +       }
28773 +
28774 +       count = ocount;
28775 +       pos = *ppos;
28776 +       pagevec_init(&lru_pvec, 0);
28777 +
28778 +       /* We can write back this queue in page reclaim */
28779 +       current->backing_dev_info = mapping->backing_dev_info;
28780 +       written = 0;
28781 +
28782 +       err = generic_write_checks(file, &pos, &count, isblk);
28783 +       if (err)
28784 +               goto out;
28785 +
28786 +
28787 +       if (count == 0)
28788 +               goto out;
28789 +
28790 +       remove_suid(file->f_dentry);
28791 +       file_update_time(file);
28792 +
28793 +       /* There is no sane reason to use O_DIRECT */
28794 +       BUG_ON(file->f_flags & O_DIRECT);
28795 +
28796 +       buf = iov->iov_base;
28797 +       do {
28798 +               unsigned long index;
28799 +               unsigned long offset;
28800 +               size_t copied;
28801 +
28802 +               offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
28803 +               index = pos >> PAGE_CACHE_SHIFT;
28804 +               bytes = PAGE_CACHE_SIZE - offset;
28805 +               if (bytes > count)
28806 +                       bytes = count;
28807 +
28808 +               page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
28809 +               if (!page) {
28810 +                       status = -ENOMEM;
28811 +                       break;
28812 +               }
28813 +
28814 +               status = a_ops->prepare_write(file, page, offset, offset+bytes);
28815 +               if (unlikely(status)) {
28816 +                       loff_t isize = i_size_read(inode);
28817 +                       /*
28818 +                        * prepare_write() may have instantiated a few blocks
28819 +                        * outside i_size.  Trim these off again.
28820 +                        */
28821 +                       unlock_page(page);
28822 +                       page_cache_release(page);
28823 +                       if (pos + bytes > isize)
28824 +                               vmtruncate(inode, isize);
28825 +                       break;
28826 +               }
28827 +
28828 +               BUG_ON(nr_segs != 1);
28829 +               copied = filemap_copy_from_kernel(page, offset, buf, bytes);
28830 +
28831 +               flush_dcache_page(page);
28832 +               status = a_ops->commit_write(file, page, offset, offset+bytes);
28833 +               if (likely(copied > 0)) {
28834 +                       if (!status)
28835 +                               status = copied;
28836 +
28837 +                       if (status >= 0) {
28838 +                               written += status;
28839 +                               count -= status;
28840 +                               pos += status;
28841 +                               buf += status;
28842 +                               if (unlikely(nr_segs > 1))
28843 +                                       filemap_set_next_kvec(&cur_iov,
28844 +                                                       &iov_base, status);
28845 +                       }
28846 +               }
28847 +               if (unlikely(copied != bytes))
28848 +                       if (status >= 0)
28849 +                               status = -EFAULT;
28850 +               unlock_page(page);
28851 +               mark_page_accessed(page);
28852 +               page_cache_release(page);
28853 +               if (status < 0)
28854 +                       break;
28855 +               balance_dirty_pages_ratelimited(mapping);
28856 +               cond_resched();
28857 +       } while (count);
28858 +       *ppos = pos;
28859 +
28860 +       if (cached_page)
28861 +               page_cache_release(cached_page);
28862 +
28863 +       /*
28864 +        * For now, when the user asks for O_SYNC, we'll actually give O_DSYNC
28865 +        */
28866 +       if (status >= 0) {
28867 +               if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
28868 +                       status = generic_osync_inode(inode, mapping,
28869 +                                       OSYNC_METADATA|OSYNC_DATA);
28870 +       }
28871 +
28872 +       err = written ? written : status;
28873 +out:
28874 +       pagevec_lru_add(&lru_pvec);
28875 +       current->backing_dev_info = 0;
28876 +       return err;
28877 +}
28878 +
28879  static ssize_t
28880  __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
28881                                 unsigned long nr_segs, loff_t *ppos)
28882 @@ -2335,6 +2542,36 @@ out:
28883         return written ? written : err;
28884  }
28885  
28886 +static ssize_t
28887 +generic_kernel_file_write_nolock(struct file *file, const struct kvec *iov,
28888 +                                unsigned long nr_segs, loff_t *ppos)
28889 +{
28890 +       struct kiocb kiocb;
28891 +       ssize_t ret;
28892 +
28893 +       init_sync_kiocb(&kiocb, file);
28894 +       ret = generic_kernel_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
28895 +       if (ret == -EIOCBQUEUED)
28896 +               ret = wait_on_sync_kiocb(&kiocb);
28897 +       return ret;
28898 +}
28899 +
28900 +static ssize_t generic_kernel_file_write(struct file *file, const char *buf,
28901 +                                        size_t count, loff_t *ppos)
28902 +{
28903 +       struct inode    *inode = file->f_mapping->host;
28904 +       ssize_t         err;
28905 +       struct kvec local_iov = { .iov_base = (char *) buf,
28906 +                                 .iov_len = count };
28907 +
28908 +       mutex_lock(&inode->i_mutex);
28909 +       err = generic_kernel_file_write_nolock(file, &local_iov, 1, ppos);
28910 +       mutex_unlock(&inode->i_mutex);
28911 +
28912 +       return err;
28913 +}
28914 +
28915 +
28916  ssize_t generic_file_aio_write_nolock(struct kiocb *iocb,
28917                 const struct iovec *iov, unsigned long nr_segs, loff_t pos)
28918  {
28919 diff -NurpP --minimal linux-2.6.19.1/mm/filemap_xip.c linux-2.6.19.1-vs2.3.0.6/mm/filemap_xip.c
28920 --- linux-2.6.19.1/mm/filemap_xip.c     2006-09-20 16:58:44 +0200
28921 +++ linux-2.6.19.1-vs2.3.0.6/mm/filemap_xip.c   2006-11-08 04:57:40 +0100
28922 @@ -13,6 +13,7 @@
28923  #include <linux/module.h>
28924  #include <linux/uio.h>
28925  #include <linux/rmap.h>
28926 +#include <linux/vs_memory.h>
28927  #include <asm/tlbflush.h>
28928  #include "filemap.h"
28929  
28930 diff -NurpP --minimal linux-2.6.19.1/mm/fremap.c linux-2.6.19.1-vs2.3.0.6/mm/fremap.c
28931 --- linux-2.6.19.1/mm/fremap.c  2006-11-30 21:19:44 +0100
28932 +++ linux-2.6.19.1-vs2.3.0.6/mm/fremap.c        2006-11-30 19:31:41 +0100
28933 @@ -15,6 +15,7 @@
28934  #include <linux/rmap.h>
28935  #include <linux/module.h>
28936  #include <linux/syscalls.h>
28937 +#include <linux/vs_memory.h>
28938  
28939  #include <asm/mmu_context.h>
28940  #include <asm/cacheflush.h>
28941 @@ -74,6 +75,8 @@ int install_page(struct mm_struct *mm, s
28942         err = -ENOMEM;
28943         if (page_mapcount(page) > INT_MAX/2)
28944                 goto unlock;
28945 +       if (!vx_rss_avail(mm, 1))
28946 +               goto unlock;
28947  
28948         if (pte_none(*pte) || !zap_pte(mm, vma, addr, pte))
28949                 inc_mm_counter(mm, file_rss);
28950 diff -NurpP --minimal linux-2.6.19.1/mm/hugetlb.c linux-2.6.19.1-vs2.3.0.6/mm/hugetlb.c
28951 --- linux-2.6.19.1/mm/hugetlb.c 2006-11-30 21:19:44 +0100
28952 +++ linux-2.6.19.1-vs2.3.0.6/mm/hugetlb.c       2006-11-08 04:57:40 +0100
28953 @@ -19,6 +19,7 @@
28954  #include <asm/pgtable.h>
28955  
28956  #include <linux/hugetlb.h>
28957 +#include <linux/vs_memory.h>
28958  #include "internal.h"
28959  
28960  const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
28961 diff -NurpP --minimal linux-2.6.19.1/mm/memory.c linux-2.6.19.1-vs2.3.0.6/mm/memory.c
28962 --- linux-2.6.19.1/mm/memory.c  2006-11-30 21:19:44 +0100
28963 +++ linux-2.6.19.1-vs2.3.0.6/mm/memory.c        2006-11-30 19:31:41 +0100
28964 @@ -498,6 +498,9 @@ static int copy_pte_range(struct mm_stru
28965         int progress = 0;
28966         int rss[2];
28967  
28968 +       if (!vx_rss_avail(dst_mm, ((end - addr)/PAGE_SIZE + 1)))
28969 +               return -ENOMEM;
28970 +
28971  again:
28972         rss[1] = rss[0] = 0;
28973         dst_pte = pte_alloc_map_lock(dst_mm, dst_pmd, addr, &dst_ptl);
28974 @@ -2011,6 +2014,11 @@ static int do_swap_page(struct mm_struct
28975                 grab_swap_token();
28976         }
28977  
28978 +       if (!vx_rss_avail(mm, 1)) {
28979 +               ret = VM_FAULT_OOM;
28980 +               goto out;
28981 +       }
28982 +
28983         delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
28984         mark_page_accessed(page);
28985         lock_page(page);
28986 @@ -2083,6 +2091,8 @@ static int do_anonymous_page(struct mm_s
28987                 /* Allocate our own private page. */
28988                 pte_unmap(page_table);
28989  
28990 +               if (!vx_rss_avail(mm, 1))
28991 +                       goto oom;
28992                 if (unlikely(anon_vma_prepare(vma)))
28993                         goto oom;
28994                 page = alloc_zeroed_user_highpage(vma, address);
28995 @@ -2156,6 +2166,9 @@ static int do_no_page(struct mm_struct *
28996         pte_unmap(page_table);
28997         BUG_ON(vma->vm_flags & VM_PFNMAP);
28998  
28999 +       if (!vx_rss_avail(mm, 1))
29000 +               return VM_FAULT_OOM;
29001 +
29002         if (vma->vm_file) {
29003                 mapping = vma->vm_file->f_mapping;
29004                 sequence = mapping->truncate_count;
29005 @@ -2380,6 +2393,7 @@ static inline int handle_pte_fault(struc
29006         pte_t entry;
29007         pte_t old_entry;
29008         spinlock_t *ptl;
29009 +       int ret, type = VXPT_UNKNOWN;
29010  
29011         old_entry = entry = *pte;
29012         if (!pte_present(entry)) {
29013 @@ -2408,9 +2422,12 @@ static inline int handle_pte_fault(struc
29014         if (unlikely(!pte_same(*pte, entry)))
29015                 goto unlock;
29016         if (write_access) {
29017 -               if (!pte_write(entry))
29018 -                       return do_wp_page(mm, vma, address,
29019 +               if (!pte_write(entry)) {
29020 +                       ret = do_wp_page(mm, vma, address,
29021                                         pte, pmd, ptl, entry);
29022 +                       type = VXPT_WRITE;
29023 +                       goto out;
29024 +               }
29025                 entry = pte_mkdirty(entry);
29026         }
29027         entry = pte_mkyoung(entry);
29028 @@ -2430,7 +2447,10 @@ static inline int handle_pte_fault(struc
29029         }
29030  unlock:
29031         pte_unmap_unlock(pte, ptl);
29032 -       return VM_FAULT_MINOR;
29033 +       ret = VM_FAULT_MINOR;
29034 +out:
29035 +       vx_page_fault(mm, vma, type, ret);
29036 +       return ret;
29037  }
29038  
29039  /*
29040 diff -NurpP --minimal linux-2.6.19.1/mm/mlock.c linux-2.6.19.1-vs2.3.0.6/mm/mlock.c
29041 --- linux-2.6.19.1/mm/mlock.c   2006-04-09 13:49:58 +0200
29042 +++ linux-2.6.19.1-vs2.3.0.6/mm/mlock.c 2006-11-08 04:57:47 +0100
29043 @@ -10,6 +10,7 @@
29044  #include <linux/mm.h>
29045  #include <linux/mempolicy.h>
29046  #include <linux/syscalls.h>
29047 +#include <linux/vs_memory.h>
29048  
29049  
29050  static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
29051 @@ -65,7 +66,7 @@ success:
29052                         ret = make_pages_present(start, end);
29053         }
29054  
29055 -       vma->vm_mm->locked_vm -= pages;
29056 +       vx_vmlocked_sub(vma->vm_mm, pages);
29057  out:
29058         if (ret == -ENOMEM)
29059                 ret = -EAGAIN;
29060 @@ -123,7 +124,7 @@ static int do_mlock(unsigned long start,
29061  
29062  asmlinkage long sys_mlock(unsigned long start, size_t len)
29063  {
29064 -       unsigned long locked;
29065 +       unsigned long locked, grow;
29066         unsigned long lock_limit;
29067         int error = -ENOMEM;
29068  
29069 @@ -134,8 +135,10 @@ asmlinkage long sys_mlock(unsigned long 
29070         len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
29071         start &= PAGE_MASK;
29072  
29073 -       locked = len >> PAGE_SHIFT;
29074 -       locked += current->mm->locked_vm;
29075 +       grow = len >> PAGE_SHIFT;
29076 +       if (!vx_vmlocked_avail(current->mm, grow))
29077 +               goto out;
29078 +       locked = current->mm->locked_vm + grow;
29079  
29080         lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
29081         lock_limit >>= PAGE_SHIFT;
29082 @@ -143,6 +146,7 @@ asmlinkage long sys_mlock(unsigned long 
29083         /* check against resource limits */
29084         if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
29085                 error = do_mlock(start, len, 1);
29086 +out:
29087         up_write(&current->mm->mmap_sem);
29088         return error;
29089  }
29090 @@ -202,6 +206,8 @@ asmlinkage long sys_mlockall(int flags)
29091         lock_limit >>= PAGE_SHIFT;
29092  
29093         ret = -ENOMEM;
29094 +       if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
29095 +               goto out;
29096         if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
29097             capable(CAP_IPC_LOCK))
29098                 ret = do_mlockall(flags);
29099 diff -NurpP --minimal linux-2.6.19.1/mm/mmap.c linux-2.6.19.1-vs2.3.0.6/mm/mmap.c
29100 --- linux-2.6.19.1/mm/mmap.c    2006-11-30 21:19:44 +0100
29101 +++ linux-2.6.19.1-vs2.3.0.6/mm/mmap.c  2006-11-20 21:12:32 +0100
29102 @@ -1141,10 +1141,10 @@ munmap_back:
29103                 kmem_cache_free(vm_area_cachep, vma);
29104         }
29105  out:   
29106 -       mm->total_vm += len >> PAGE_SHIFT;
29107 +       vx_vmpages_add(mm, len >> PAGE_SHIFT);
29108         vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
29109         if (vm_flags & VM_LOCKED) {
29110 -               mm->locked_vm += len >> PAGE_SHIFT;
29111 +               vx_vmlocked_add(mm, len >> PAGE_SHIFT);
29112                 make_pages_present(addr, addr + len);
29113         }
29114         if (flags & MAP_POPULATE) {
29115 @@ -1504,9 +1504,9 @@ static int acct_stack_growth(struct vm_a
29116                 return -ENOMEM;
29117  
29118         /* Ok, everything looks good - let it rip */
29119 -       mm->total_vm += grow;
29120 +       vx_vmpages_add(mm, grow);
29121         if (vma->vm_flags & VM_LOCKED)
29122 -               mm->locked_vm += grow;
29123 +               vx_vmlocked_add(mm, grow);
29124         vm_stat_account(mm, vma->vm_flags, vma->vm_file, grow);
29125         return 0;
29126  }
29127 @@ -1659,9 +1659,9 @@ static void remove_vma_list(struct mm_st
29128         do {
29129                 long nrpages = vma_pages(vma);
29130  
29131 -               mm->total_vm -= nrpages;
29132 +               vx_vmpages_sub(mm, nrpages);
29133                 if (vma->vm_flags & VM_LOCKED)
29134 -                       mm->locked_vm -= nrpages;
29135 +                       vx_vmlocked_sub(mm, nrpages);
29136                 vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
29137                 vma = remove_vma(vma);
29138         } while (vma);
29139 @@ -1900,6 +1900,8 @@ unsigned long do_brk(unsigned long addr,
29140                 lock_limit >>= PAGE_SHIFT;
29141                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
29142                         return -EAGAIN;
29143 +               if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
29144 +                       return -ENOMEM;
29145         }
29146  
29147         /*
29148 @@ -1926,7 +1928,8 @@ unsigned long do_brk(unsigned long addr,
29149         if (mm->map_count > sysctl_max_map_count)
29150                 return -ENOMEM;
29151  
29152 -       if (security_vm_enough_memory(len >> PAGE_SHIFT))
29153 +       if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
29154 +               !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
29155                 return -ENOMEM;
29156  
29157         /* Can we just expand an old private anonymous mapping? */
29158 @@ -1952,9 +1955,9 @@ unsigned long do_brk(unsigned long addr,
29159                                 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
29160         vma_link(mm, vma, prev, rb_link, rb_parent);
29161  out:
29162 -       mm->total_vm += len >> PAGE_SHIFT;
29163 +       vx_vmpages_add(mm, len >> PAGE_SHIFT);
29164         if (flags & VM_LOCKED) {
29165 -               mm->locked_vm += len >> PAGE_SHIFT;
29166 +               vx_vmlocked_add(mm, len >> PAGE_SHIFT);
29167                 make_pages_present(addr, addr + len);
29168         }
29169         return addr;
29170 @@ -1980,6 +1983,11 @@ void exit_mmap(struct mm_struct *mm)
29171         free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0);
29172         tlb_finish_mmu(tlb, 0, end);
29173  
29174 +       set_mm_counter(mm, file_rss, 0);
29175 +       set_mm_counter(mm, anon_rss, 0);
29176 +       vx_vmpages_sub(mm, mm->total_vm);
29177 +       vx_vmlocked_sub(mm, mm->locked_vm);
29178 +
29179         /*
29180          * Walk the list again, actually closing and freeing it,
29181          * with preemption enabled, without holding any MM locks.
29182 @@ -2019,7 +2027,8 @@ int insert_vm_struct(struct mm_struct * 
29183         if (__vma && __vma->vm_start < vma->vm_end)
29184                 return -ENOMEM;
29185         if ((vma->vm_flags & VM_ACCOUNT) &&
29186 -            security_vm_enough_memory(vma_pages(vma)))
29187 +               (security_vm_enough_memory(vma_pages(vma)) ||
29188 +               !vx_vmpages_avail(mm, vma_pages(vma))))
29189                 return -ENOMEM;
29190         vma_link(mm, vma, prev, rb_link, rb_parent);
29191         return 0;
29192 @@ -2092,5 +2101,7 @@ int may_expand_vm(struct mm_struct *mm, 
29193  
29194         if (cur + npages > lim)
29195                 return 0;
29196 +       if (!vx_vmpages_avail(mm, npages))
29197 +               return 0;
29198         return 1;
29199  }
29200 diff -NurpP --minimal linux-2.6.19.1/mm/mremap.c linux-2.6.19.1-vs2.3.0.6/mm/mremap.c
29201 --- linux-2.6.19.1/mm/mremap.c  2006-11-30 21:19:44 +0100
29202 +++ linux-2.6.19.1-vs2.3.0.6/mm/mremap.c        2006-11-08 04:57:47 +0100
29203 @@ -18,6 +18,7 @@
29204  #include <linux/highmem.h>
29205  #include <linux/security.h>
29206  #include <linux/syscalls.h>
29207 +#include <linux/vs_memory.h>
29208  
29209  #include <asm/uaccess.h>
29210  #include <asm/cacheflush.h>
29211 @@ -213,7 +214,7 @@ static unsigned long move_vma(struct vm_
29212          * If this were a serious issue, we'd add a flag to do_munmap().
29213          */
29214         hiwater_vm = mm->hiwater_vm;
29215 -       mm->total_vm += new_len >> PAGE_SHIFT;
29216 +       vx_vmpages_add(mm, new_len >> PAGE_SHIFT);
29217         vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
29218  
29219         if (do_munmap(mm, old_addr, old_len) < 0) {
29220 @@ -231,7 +232,7 @@ static unsigned long move_vma(struct vm_
29221         }
29222  
29223         if (vm_flags & VM_LOCKED) {
29224 -               mm->locked_vm += new_len >> PAGE_SHIFT;
29225 +               vx_vmlocked_add(mm, new_len >> PAGE_SHIFT);
29226                 if (new_len > old_len)
29227                         make_pages_present(new_addr + old_len,
29228                                            new_addr + new_len);
29229 @@ -338,6 +339,9 @@ unsigned long do_mremap(unsigned long ad
29230                 ret = -EAGAIN;
29231                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
29232                         goto out;
29233 +               if (!vx_vmlocked_avail(current->mm,
29234 +                       (new_len - old_len) >> PAGE_SHIFT))
29235 +                       goto out;
29236         }
29237         if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT)) {
29238                 ret = -ENOMEM;
29239 @@ -366,10 +370,10 @@ unsigned long do_mremap(unsigned long ad
29240                         vma_adjust(vma, vma->vm_start,
29241                                 addr + new_len, vma->vm_pgoff, NULL);
29242  
29243 -                       mm->total_vm += pages;
29244 +                       vx_vmpages_add(mm, pages);
29245                         vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
29246                         if (vma->vm_flags & VM_LOCKED) {
29247 -                               mm->locked_vm += pages;
29248 +                               vx_vmlocked_add(mm, pages);
29249                                 make_pages_present(addr + old_len,
29250                                                    addr + new_len);
29251                         }
29252 diff -NurpP --minimal linux-2.6.19.1/mm/nommu.c linux-2.6.19.1-vs2.3.0.6/mm/nommu.c
29253 --- linux-2.6.19.1/mm/nommu.c   2006-11-30 21:19:44 +0100
29254 +++ linux-2.6.19.1-vs2.3.0.6/mm/nommu.c 2006-11-08 04:57:47 +0100
29255 @@ -921,7 +921,7 @@ unsigned long do_mmap_pgoff(struct file 
29256         realalloc += kobjsize(vma);
29257         askedalloc += sizeof(*vma);
29258  
29259 -       current->mm->total_vm += len >> PAGE_SHIFT;
29260 +       vx_vmpages_add(current->mm, len >> PAGE_SHIFT);
29261  
29262         add_nommu_vma(vma);
29263  
29264 @@ -1046,7 +1046,7 @@ int do_munmap(struct mm_struct *mm, unsi
29265         kfree(vml);
29266  
29267         update_hiwater_vm(mm);
29268 -       mm->total_vm -= len >> PAGE_SHIFT;
29269 +       vx_vmpages_sub(mm, len >> PAGE_SHIFT);
29270  
29271  #ifdef DEBUG
29272         show_process_blocks();
29273 @@ -1078,7 +1078,7 @@ void exit_mmap(struct mm_struct * mm)
29274                 printk("Exit_mmap:\n");
29275  #endif
29276  
29277 -               mm->total_vm = 0;
29278 +               vx_vmpages_sub(mm, mm->total_vm);
29279  
29280                 while ((tmp = mm->context.vmlist)) {
29281                         mm->context.vmlist = tmp->next;
29282 diff -NurpP --minimal linux-2.6.19.1/mm/oom_kill.c linux-2.6.19.1-vs2.3.0.6/mm/oom_kill.c
29283 --- linux-2.6.19.1/mm/oom_kill.c        2006-11-30 21:19:44 +0100
29284 +++ linux-2.6.19.1-vs2.3.0.6/mm/oom_kill.c      2006-11-30 19:33:42 +0100
29285 @@ -24,6 +24,7 @@
29286  #include <linux/cpuset.h>
29287  #include <linux/module.h>
29288  #include <linux/notifier.h>
29289 +#include <linux/vs_memory.h>
29290  
29291  int sysctl_panic_on_oom;
29292  /* #define DEBUG */
29293 @@ -72,6 +73,12 @@ unsigned long badness(struct task_struct
29294         points = mm->total_vm;
29295  
29296         /*
29297 +        * add points for context badness
29298 +        */
29299 +
29300 +       points += vx_badness(p, mm);
29301 +
29302 +       /*
29303          * After this unlock we can no longer dereference local variable `mm'
29304          */
29305         task_unlock(p);
29306 @@ -154,8 +161,8 @@ unsigned long badness(struct task_struct
29307         }
29308  
29309  #ifdef DEBUG
29310 -       printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n",
29311 -       p->pid, p->comm, points);
29312 +       printk(KERN_DEBUG "OOMkill: task %d:#%u (%s) got %d points\n",
29313 +               p->pid, p->xid, p->comm, points);
29314  #endif
29315         return points;
29316  }
29317 @@ -279,8 +286,8 @@ static void __oom_kill_task(struct task_
29318         }
29319  
29320         if (message) {
29321 -               printk(KERN_ERR "%s: Killed process %d (%s).\n",
29322 -                               message, p->pid, p->comm);
29323 +               printk(KERN_ERR "%s: Killed process %d:#%u (%s).\n",
29324 +                               message, p->pid, p->xid, p->comm);
29325         }
29326  
29327         /*
29328 @@ -341,8 +348,8 @@ static int oom_kill_process(struct task_
29329                 return 0;
29330         }
29331  
29332 -       printk(KERN_ERR "Out of Memory: Kill process %d (%s) score %li"
29333 -                       " and children.\n", p->pid, p->comm, points);
29334 +       printk(KERN_ERR "Out of Memory: Kill process %d:#%u (%s) score %li"
29335 +                       " and children.\n", p->pid, p->xid, p->comm, points);
29336         /* Try to kill a child first */
29337         list_for_each(tsk, &p->children) {
29338                 c = list_entry(tsk, struct task_struct, sibling);
29339 diff -NurpP --minimal linux-2.6.19.1/mm/page_alloc.c linux-2.6.19.1-vs2.3.0.6/mm/page_alloc.c
29340 --- linux-2.6.19.1/mm/page_alloc.c      2006-11-30 21:19:44 +0100
29341 +++ linux-2.6.19.1-vs2.3.0.6/mm/page_alloc.c    2006-11-30 20:55:45 +0100
29342 @@ -40,6 +40,8 @@
29343  #include <linux/sort.h>
29344  #include <linux/pfn.h>
29345  #include <linux/backing-dev.h>
29346 +#include <linux/vs_base.h>
29347 +#include <linux/vs_limit.h>
29348  
29349  #include <asm/tlbflush.h>
29350  #include <asm/div64.h>
29351 @@ -1274,6 +1276,9 @@ void si_meminfo(struct sysinfo *val)
29352         val->totalhigh = totalhigh_pages;
29353         val->freehigh = nr_free_highpages();
29354         val->mem_unit = PAGE_SIZE;
29355 +
29356 +       if (vx_flags(VXF_VIRT_MEM, 0))
29357 +               vx_vsi_meminfo(val);
29358  }
29359  
29360  EXPORT_SYMBOL(si_meminfo);
29361 @@ -1293,6 +1298,9 @@ void si_meminfo_node(struct sysinfo *val
29362         val->freehigh = 0;
29363  #endif
29364         val->mem_unit = PAGE_SIZE;
29365 +
29366 +       if (vx_flags(VXF_VIRT_MEM, 0))
29367 +               vx_vsi_meminfo(val);
29368  }
29369  #endif
29370  
29371 diff -NurpP --minimal linux-2.6.19.1/mm/rmap.c linux-2.6.19.1-vs2.3.0.6/mm/rmap.c
29372 --- linux-2.6.19.1/mm/rmap.c    2006-11-30 21:19:44 +0100
29373 +++ linux-2.6.19.1-vs2.3.0.6/mm/rmap.c  2006-11-08 04:57:40 +0100
29374 @@ -47,6 +47,7 @@
29375  #include <linux/rmap.h>
29376  #include <linux/rcupdate.h>
29377  #include <linux/module.h>
29378 +#include <linux/vs_memory.h>
29379  
29380  #include <asm/tlbflush.h>
29381  
29382 diff -NurpP --minimal linux-2.6.19.1/mm/shmem.c linux-2.6.19.1-vs2.3.0.6/mm/shmem.c
29383 --- linux-2.6.19.1/mm/shmem.c   2006-11-30 21:19:44 +0100
29384 +++ linux-2.6.19.1-vs2.3.0.6/mm/shmem.c 2006-11-08 04:57:53 +0100
29385 @@ -55,7 +55,6 @@
29386  #include <asm/pgtable.h>
29387  
29388  /* This magic number is used in glibc for posix shared memory */
29389 -#define TMPFS_MAGIC    0x01021994
29390  
29391  #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
29392  #define ENTRIES_PER_PAGEPAGE (ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)
29393 @@ -1658,7 +1657,7 @@ static int shmem_statfs(struct dentry *d
29394  {
29395         struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
29396  
29397 -       buf->f_type = TMPFS_MAGIC;
29398 +       buf->f_type = TMPFS_SUPER_MAGIC;
29399         buf->f_bsize = PAGE_CACHE_SIZE;
29400         buf->f_namelen = NAME_MAX;
29401         spin_lock(&sbinfo->stat_lock);
29402 @@ -2232,7 +2231,7 @@ static int shmem_fill_super(struct super
29403         sb->s_maxbytes = SHMEM_MAX_BYTES;
29404         sb->s_blocksize = PAGE_CACHE_SIZE;
29405         sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
29406 -       sb->s_magic = TMPFS_MAGIC;
29407 +       sb->s_magic = TMPFS_SUPER_MAGIC;
29408         sb->s_op = &shmem_ops;
29409         sb->s_time_gran = 1;
29410  #ifdef CONFIG_TMPFS_POSIX_ACL
29411 diff -NurpP --minimal linux-2.6.19.1/mm/slab.c linux-2.6.19.1-vs2.3.0.6/mm/slab.c
29412 --- linux-2.6.19.1/mm/slab.c    2006-11-30 21:19:44 +0100
29413 +++ linux-2.6.19.1-vs2.3.0.6/mm/slab.c  2006-11-08 21:52:09 +0100
29414 @@ -499,6 +499,8 @@ struct kmem_cache {
29415  #define STATS_INC_FREEMISS(x)  do { } while (0)
29416  #endif
29417  
29418 +#include "slab_vs.h"
29419 +
29420  #if DEBUG
29421  
29422  /*
29423 @@ -3109,6 +3111,8 @@ static __always_inline void *__cache_all
29424          */
29425         if (NUMA_BUILD && !objp)
29426                 objp = __cache_alloc_node(cachep, flags, numa_node_id());
29427 +
29428 +       vx_slab_alloc(cachep, flags);
29429         local_irq_restore(save_flags);
29430         objp = cache_alloc_debugcheck_after(cachep, flags, objp,
29431                                             caller);
29432 @@ -3202,6 +3206,7 @@ retry:
29433  
29434         obj = slab_get_obj(cachep, slabp, nodeid);
29435         check_slabp(cachep, slabp);
29436 +       vx_slab_alloc(cachep, flags);
29437         l3->free_objects--;
29438         /* move slabp to correct slabp list: */
29439         list_del(&slabp->list);
29440 @@ -3339,6 +3344,7 @@ static inline void __cache_free(struct k
29441  
29442         check_irq_off();
29443         objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
29444 +       vx_slab_free(cachep);
29445  
29446         if (cache_free_alien(cachep, objp))
29447                 return;
29448 diff -NurpP --minimal linux-2.6.19.1/mm/slab_vs.h linux-2.6.19.1-vs2.3.0.6/mm/slab_vs.h
29449 --- linux-2.6.19.1/mm/slab_vs.h 1970-01-01 01:00:00 +0100
29450 +++ linux-2.6.19.1-vs2.3.0.6/mm/slab_vs.h       2006-11-30 18:53:18 +0100
29451 @@ -0,0 +1,27 @@
29452 +
29453 +#include <linux/vserver/context.h>
29454 +
29455 +#include <linux/vs_context.h>
29456 +
29457 +static inline
29458 +void vx_slab_alloc(struct kmem_cache *cachep, gfp_t flags)
29459 +{
29460 +       int what = gfp_zone(cachep->gfpflags);
29461 +
29462 +       if (!current->vx_info)
29463 +               return;
29464 +
29465 +       atomic_add(cachep->buffer_size, &current->vx_info->cacct.slab[what]);
29466 +}
29467 +
29468 +static inline
29469 +void vx_slab_free(struct kmem_cache *cachep)
29470 +{
29471 +       int what = gfp_zone(cachep->gfpflags);
29472 +
29473 +       if (!current->vx_info)
29474 +               return;
29475 +
29476 +       atomic_sub(cachep->buffer_size, &current->vx_info->cacct.slab[what]);
29477 +}
29478 +
29479 diff -NurpP --minimal linux-2.6.19.1/mm/swapfile.c linux-2.6.19.1-vs2.3.0.6/mm/swapfile.c
29480 --- linux-2.6.19.1/mm/swapfile.c        2006-11-30 21:19:44 +0100
29481 +++ linux-2.6.19.1-vs2.3.0.6/mm/swapfile.c      2006-11-08 06:23:28 +0100
29482 @@ -31,6 +31,8 @@
29483  #include <asm/pgtable.h>
29484  #include <asm/tlbflush.h>
29485  #include <linux/swapops.h>
29486 +#include <linux/vs_base.h>
29487 +#include <linux/vs_memory.h>
29488  
29489  DEFINE_SPINLOCK(swap_lock);
29490  unsigned int nr_swapfiles;
29491 @@ -1667,6 +1669,8 @@ void si_swapinfo(struct sysinfo *val)
29492         val->freeswap = nr_swap_pages + nr_to_be_unused;
29493         val->totalswap = total_swap_pages + nr_to_be_unused;
29494         spin_unlock(&swap_lock);
29495 +       if (vx_flags(VXF_VIRT_MEM, 0))
29496 +               vx_vsi_swapinfo(val);
29497  }
29498  
29499  /*
29500 diff -NurpP --minimal linux-2.6.19.1/net/core/dev.c linux-2.6.19.1-vs2.3.0.6/net/core/dev.c
29501 --- linux-2.6.19.1/net/core/dev.c       2006-11-30 21:19:44 +0100
29502 +++ linux-2.6.19.1-vs2.3.0.6/net/core/dev.c     2006-12-17 03:23:33 +0100
29503 @@ -117,6 +117,7 @@
29504  #include <linux/dmaengine.h>
29505  #include <linux/err.h>
29506  #include <linux/ctype.h>
29507 +#include <linux/vs_inet.h>
29508  
29509  /*
29510   *     The list of packet types we will receive (as opposed to discard)
29511 @@ -2051,6 +2052,8 @@ static int dev_ifconf(char __user *arg)
29512  
29513         total = 0;
29514         for (dev = dev_base; dev; dev = dev->next) {
29515 +               if (!nx_dev_visible(current->nx_info, dev))
29516 +                       continue;
29517                 for (i = 0; i < NPROTO; i++) {
29518                         if (gifconf_list[i]) {
29519                                 int done;
29520 @@ -2111,6 +2114,8 @@ void dev_seq_stop(struct seq_file *seq, 
29521  
29522  static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
29523  {
29524 +       if (!nx_dev_visible(current->nx_info, dev))
29525 +               return;
29526         if (dev->get_stats) {
29527                 struct net_device_stats *stats = dev->get_stats(dev);
29528  
29529 diff -NurpP --minimal linux-2.6.19.1/net/core/rtnetlink.c linux-2.6.19.1-vs2.3.0.6/net/core/rtnetlink.c
29530 --- linux-2.6.19.1/net/core/rtnetlink.c 2006-11-30 21:19:44 +0100
29531 +++ linux-2.6.19.1-vs2.3.0.6/net/core/rtnetlink.c       2006-12-17 03:34:44 +0100
29532 @@ -359,6 +359,8 @@ static int rtnl_dump_ifinfo(struct sk_bu
29533         for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
29534                 if (idx < s_idx)
29535                         continue;
29536 +               if (!nx_dev_visible(skb->sk->sk_nx_info, dev))
29537 +                       continue;
29538                 if (rtnl_fill_ifinfo(skb, dev, NULL, 0, RTM_NEWLINK,
29539                                      NETLINK_CB(cb->skb).pid,
29540                                      cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0)
29541 @@ -639,6 +641,9 @@ void rtmsg_ifinfo(int type, struct net_d
29542         struct sk_buff *skb;
29543         int err = -ENOBUFS;
29544  
29545 +       if (!nx_dev_visible(current->nx_info, dev))
29546 +               return;
29547 +
29548         skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
29549         if (skb == NULL)
29550                 goto errout;
29551 diff -NurpP --minimal linux-2.6.19.1/net/core/sock.c linux-2.6.19.1-vs2.3.0.6/net/core/sock.c
29552 --- linux-2.6.19.1/net/core/sock.c      2006-11-30 21:19:44 +0100
29553 +++ linux-2.6.19.1-vs2.3.0.6/net/core/sock.c    2006-11-08 21:52:09 +0100
29554 @@ -124,6 +124,9 @@
29555  #include <linux/ipsec.h>
29556  
29557  #include <linux/filter.h>
29558 +#include <linux/vs_socket.h>
29559 +#include <linux/vs_limit.h>
29560 +#include <linux/vs_context.h>
29561  
29562  #ifdef CONFIG_INET
29563  #include <net/tcp.h>
29564 @@ -855,6 +858,8 @@ struct sock *sk_alloc(int family, gfp_t 
29565                         sk->sk_prot = sk->sk_prot_creator = prot;
29566                         sock_lock_init(sk);
29567                 }
29568 +               sock_vx_init(sk);
29569 +               sock_nx_init(sk);
29570                 
29571                 if (security_sk_alloc(sk, family, priority))
29572                         goto out_free;
29573 @@ -893,6 +898,11 @@ void sk_free(struct sock *sk)
29574                        __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
29575  
29576         security_sk_free(sk);
29577 +       vx_sock_dec(sk);
29578 +       clr_vx_info(&sk->sk_vx_info);
29579 +       sk->sk_xid = -1;
29580 +       clr_nx_info(&sk->sk_nx_info);
29581 +       sk->sk_nid = -1;
29582         if (sk->sk_prot_creator->slab != NULL)
29583                 kmem_cache_free(sk->sk_prot_creator->slab, sk);
29584         else
29585 @@ -910,6 +920,8 @@ struct sock *sk_clone(const struct sock 
29586                 sock_copy(newsk, sk);
29587  
29588                 /* SANITY */
29589 +               sock_vx_init(newsk);
29590 +               sock_nx_init(newsk);
29591                 sk_node_init(&newsk->sk_node);
29592                 sock_lock_init(newsk);
29593                 bh_lock_sock(newsk);
29594 @@ -955,6 +967,12 @@ struct sock *sk_clone(const struct sock 
29595                 newsk->sk_priority = 0;
29596                 atomic_set(&newsk->sk_refcnt, 2);
29597  
29598 +               set_vx_info(&newsk->sk_vx_info, sk->sk_vx_info);
29599 +               newsk->sk_xid = sk->sk_xid;
29600 +               vx_sock_inc(newsk);
29601 +               set_nx_info(&newsk->sk_nx_info, sk->sk_nx_info);
29602 +               newsk->sk_nid = sk->sk_nid;
29603 +
29604                 /*
29605                  * Increment the counter in the same struct proto as the master
29606                  * sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
29607 @@ -1524,6 +1542,11 @@ void sock_init_data(struct socket *sock,
29608         sk->sk_stamp.tv_sec     = -1L;
29609         sk->sk_stamp.tv_usec    = -1L;
29610  
29611 +       set_vx_info(&sk->sk_vx_info, current->vx_info);
29612 +       sk->sk_xid = vx_current_xid();
29613 +       vx_sock_inc(sk);
29614 +       set_nx_info(&sk->sk_nx_info, current->nx_info);
29615 +       sk->sk_nid = nx_current_nid();
29616         atomic_set(&sk->sk_refcnt, 1);
29617  }
29618  
29619 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/af_inet.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/af_inet.c
29620 --- linux-2.6.19.1/net/ipv4/af_inet.c   2006-11-30 21:19:45 +0100
29621 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/af_inet.c 2006-11-08 04:57:50 +0100
29622 @@ -114,6 +114,7 @@
29623  #ifdef CONFIG_IP_MROUTE
29624  #include <linux/mroute.h>
29625  #endif
29626 +#include <linux/vs_limit.h>
29627  
29628  DEFINE_SNMP_STAT(struct linux_mib, net_statistics) __read_mostly;
29629  
29630 @@ -282,9 +283,11 @@ lookup_protocol:
29631         }
29632  
29633         err = -EPERM;
29634 +       if ((protocol == IPPROTO_ICMP) && vx_ccaps(VXC_RAW_ICMP))
29635 +               goto override;
29636         if (answer->capability > 0 && !capable(answer->capability))
29637                 goto out_rcu_unlock;
29638 -
29639 +override:
29640         sock->ops = answer->ops;
29641         answer_prot = answer->prot;
29642         answer_no_check = answer->no_check;
29643 @@ -401,6 +404,10 @@ int inet_bind(struct socket *sock, struc
29644         unsigned short snum;
29645         int chk_addr_ret;
29646         int err;
29647 +       __u32 s_addr;   /* Address used for validation */
29648 +       __u32 s_addr1;  /* Address used for socket */
29649 +       __u32 s_addr2;  /* Broadcast address for the socket */
29650 +       struct nx_info *nxi = sk->sk_nx_info;
29651  
29652         /* If the socket has its own bind function then use it. (RAW) */
29653         if (sk->sk_prot->bind) {
29654 @@ -411,7 +418,40 @@ int inet_bind(struct socket *sock, struc
29655         if (addr_len < sizeof(struct sockaddr_in))
29656                 goto out;
29657  
29658 -       chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
29659 +       s_addr = addr->sin_addr.s_addr;
29660 +       s_addr1 = s_addr;
29661 +       s_addr2 = 0xffffffffl;
29662 +
29663 +       vxdprintk(VXD_CBIT(net, 3),
29664 +               "inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d",
29665 +               sk, sk->sk_nx_info, sk->sk_socket,
29666 +               (sk->sk_socket?sk->sk_socket->flags:0),
29667 +               VXD_QUAD(s_addr));
29668 +       if (nxi) {
29669 +               __u32 v4_bcast = nxi->v4_bcast;
29670 +               __u32 ipv4root = nxi->ipv4[0];
29671 +               int nbipv4 = nxi->nbipv4;
29672 +
29673 +               if (s_addr == 0) {
29674 +                       /* bind to any for 1-n */
29675 +                       s_addr = ipv4root;
29676 +                       s_addr1 = (nbipv4 > 1) ? 0 : s_addr;
29677 +                       s_addr2 = v4_bcast;
29678 +               } else if (s_addr == IPI_LOOPBACK) {
29679 +                       /* rewrite localhost to ipv4root */
29680 +                       s_addr = ipv4root;
29681 +                       s_addr1 = ipv4root;
29682 +               } else if (s_addr != v4_bcast) {
29683 +                       /* normal address bind */
29684 +                       if (!addr_in_nx_info(nxi, s_addr))
29685 +                               return -EADDRNOTAVAIL;
29686 +               }
29687 +       }
29688 +       chk_addr_ret = inet_addr_type(s_addr);
29689 +
29690 +       vxdprintk(VXD_CBIT(net, 3),
29691 +               "inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d",
29692 +               sk, VXD_QUAD(s_addr), VXD_QUAD(s_addr1), VXD_QUAD(s_addr2));
29693  
29694         /* Not specified by any standard per-se, however it breaks too
29695          * many applications when removed.  It is unfortunate since
29696 @@ -423,7 +463,7 @@ int inet_bind(struct socket *sock, struc
29697         err = -EADDRNOTAVAIL;
29698         if (!sysctl_ip_nonlocal_bind &&
29699             !inet->freebind &&
29700 -           addr->sin_addr.s_addr != INADDR_ANY &&
29701 +           s_addr != INADDR_ANY &&
29702             chk_addr_ret != RTN_LOCAL &&
29703             chk_addr_ret != RTN_MULTICAST &&
29704             chk_addr_ret != RTN_BROADCAST)
29705 @@ -448,7 +488,8 @@ int inet_bind(struct socket *sock, struc
29706         if (sk->sk_state != TCP_CLOSE || inet->num)
29707                 goto out_release_sock;
29708  
29709 -       inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr;
29710 +       inet->rcv_saddr = inet->saddr = s_addr1;
29711 +       inet->rcv_saddr2 = s_addr2;
29712         if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
29713                 inet->saddr = 0;  /* Use device */
29714  
29715 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/devinet.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/devinet.c
29716 --- linux-2.6.19.1/net/ipv4/devinet.c   2006-11-30 21:19:45 +0100
29717 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/devinet.c 2006-12-17 03:23:33 +0100
29718 @@ -675,6 +675,8 @@ int devinet_ioctl(unsigned int cmd, void
29719                 *colon = ':';
29720  
29721         if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) {
29722 +               struct nx_info *nxi = current->nx_info;
29723 +
29724                 if (tryaddrmatch) {
29725                         /* Matthias Andree */
29726                         /* compare label and address (4.4BSD style) */
29727 @@ -683,6 +685,8 @@ int devinet_ioctl(unsigned int cmd, void
29728                            This is checked above. */
29729                         for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
29730                              ifap = &ifa->ifa_next) {
29731 +                               if (!nx_ifa_visible(nxi, ifa))
29732 +                                       continue;
29733                                 if (!strcmp(ifr.ifr_name, ifa->ifa_label) &&
29734                                     sin_orig.sin_addr.s_addr ==
29735                                                         ifa->ifa_address) {
29736 @@ -695,9 +699,12 @@ int devinet_ioctl(unsigned int cmd, void
29737                    comparing just the label */
29738                 if (!ifa) {
29739                         for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
29740 -                            ifap = &ifa->ifa_next)
29741 +                            ifap = &ifa->ifa_next) {
29742 +                               if (!nx_ifa_visible(nxi, ifa))
29743 +                                       continue;
29744                                 if (!strcmp(ifr.ifr_name, ifa->ifa_label))
29745                                         break;
29746 +                       }
29747                 }
29748         }
29749  
29750 @@ -848,6 +855,8 @@ static int inet_gifconf(struct net_devic
29751                 goto out;
29752  
29753         for (; ifa; ifa = ifa->ifa_next) {
29754 +               if (!nx_ifa_visible(current->nx_info, ifa))
29755 +                       continue;
29756                 if (!buf) {
29757                         done += sizeof(ifr);
29758                         continue;
29759 @@ -1164,6 +1173,7 @@ static int inet_dump_ifaddr(struct sk_bu
29760         struct net_device *dev;
29761         struct in_device *in_dev;
29762         struct in_ifaddr *ifa;
29763 +       struct sock *sk = skb->sk;
29764         int s_ip_idx, s_idx = cb->args[0];
29765  
29766         s_ip_idx = ip_idx = cb->args[1];
29767 @@ -1181,6 +1191,8 @@ static int inet_dump_ifaddr(struct sk_bu
29768  
29769                 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
29770                      ifa = ifa->ifa_next, ip_idx++) {
29771 +                       if (sk && !nx_ifa_visible(sk->sk_nx_info, ifa))
29772 +                               continue;
29773                         if (ip_idx < s_ip_idx)
29774                                 continue;
29775                         if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
29776 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/fib_hash.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/fib_hash.c
29777 --- linux-2.6.19.1/net/ipv4/fib_hash.c  2006-11-30 21:19:45 +0100
29778 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/fib_hash.c        2006-12-17 03:23:33 +0100
29779 @@ -1011,7 +1011,7 @@ static int fib_seq_show(struct seq_file 
29780         prefix  = f->fn_key;
29781         mask    = FZ_MASK(iter->zone);
29782         flags   = fib_flag_trans(fa->fa_type, mask, fi);
29783 -       if (fi)
29784 +       if (fi && nx_dev_visible(current->nx_info, fi->fib_dev))
29785                 snprintf(bf, sizeof(bf),
29786                          "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
29787                          fi->fib_dev ? fi->fib_dev->name : "*", prefix,
29788 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/inet_connection_sock.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_connection_sock.c
29789 --- linux-2.6.19.1/net/ipv4/inet_connection_sock.c      2006-11-30 21:19:45 +0100
29790 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_connection_sock.c    2006-11-08 04:57:42 +0100
29791 @@ -39,7 +39,6 @@ int sysctl_local_port_range[2] = { 1024,
29792  int inet_csk_bind_conflict(const struct sock *sk,
29793                            const struct inet_bind_bucket *tb)
29794  {
29795 -       const __be32 sk_rcv_saddr = inet_rcv_saddr(sk);
29796         struct sock *sk2;
29797         struct hlist_node *node;
29798         int reuse = sk->sk_reuse;
29799 @@ -52,9 +51,8 @@ int inet_csk_bind_conflict(const struct 
29800                      sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
29801                         if (!reuse || !sk2->sk_reuse ||
29802                             sk2->sk_state == TCP_LISTEN) {
29803 -                               const __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
29804 -                               if (!sk2_rcv_saddr || !sk_rcv_saddr ||
29805 -                                   sk2_rcv_saddr == sk_rcv_saddr)
29806 +                               if (nx_addr_conflict(sk->sk_nx_info,
29807 +                                       inet_rcv_saddr(sk), sk2))
29808                                         break;
29809                         }
29810                 }
29811 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/inet_diag.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_diag.c
29812 --- linux-2.6.19.1/net/ipv4/inet_diag.c 2006-11-30 21:19:45 +0100
29813 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_diag.c       2006-12-04 05:06:57 +0100
29814 @@ -18,6 +18,7 @@
29815  #include <linux/cache.h>
29816  #include <linux/init.h>
29817  #include <linux/time.h>
29818 +// #include <linux/vs_base.h>
29819  
29820  #include <net/icmp.h>
29821  #include <net/tcp.h>
29822 @@ -693,6 +694,8 @@ static int inet_diag_dump(struct sk_buff
29823                         sk_for_each(sk, node, &hashinfo->listening_hash[i]) {
29824                                 struct inet_sock *inet = inet_sk(sk);
29825  
29826 +                               if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
29827 +                                       continue;
29828                                 if (num < s_num) {
29829                                         num++;
29830                                         continue;
29831 @@ -753,6 +756,8 @@ skip_listen_ht:
29832                 sk_for_each(sk, node, &head->chain) {
29833                         struct inet_sock *inet = inet_sk(sk);
29834  
29835 +                       if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
29836 +                               continue;
29837                         if (num < s_num)
29838                                 goto next_normal;
29839                         if (!(r->idiag_states & (1 << sk->sk_state)))
29840 @@ -777,6 +782,8 @@ next_normal:
29841                         inet_twsk_for_each(tw, node,
29842                                     &hashinfo->ehash[i + hashinfo->ehash_size].chain) {
29843  
29844 +                               if (!vx_check(tw->tw_xid, VS_WATCH_P|VS_IDENT))
29845 +                                       continue;
29846                                 if (num < s_num)
29847                                         goto next_dying;
29848                                 if (r->id.idiag_sport != tw->tw_sport &&
29849 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/inet_hashtables.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_hashtables.c
29850 --- linux-2.6.19.1/net/ipv4/inet_hashtables.c   2006-11-30 21:19:45 +0100
29851 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/inet_hashtables.c 2006-11-08 04:57:42 +0100
29852 @@ -140,11 +140,10 @@ static struct sock *inet_lookup_listener
29853                         const __be32 rcv_saddr = inet->rcv_saddr;
29854                         int score = sk->sk_family == PF_INET ? 1 : 0;
29855  
29856 -                       if (rcv_saddr) {
29857 -                               if (rcv_saddr != daddr)
29858 -                                       continue;
29859 +                       if (inet_addr_match(sk->sk_nx_info, daddr, rcv_saddr))
29860                                 score += 2;
29861 -                       }
29862 +                       else
29863 +                               continue;
29864                         if (sk->sk_bound_dev_if) {
29865                                 if (sk->sk_bound_dev_if != dif)
29866                                         continue;
29867 @@ -175,7 +174,7 @@ struct sock *__inet_lookup_listener(stru
29868                 const struct inet_sock *inet = inet_sk((sk = __sk_head(head)));
29869  
29870                 if (inet->num == hnum && !sk->sk_node.next &&
29871 -                   (!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
29872 +                   inet_addr_match(sk->sk_nx_info, daddr, inet->rcv_saddr) &&
29873                     (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
29874                     !sk->sk_bound_dev_if)
29875                         goto sherry_cache;
29876 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/raw.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/raw.c
29877 --- linux-2.6.19.1/net/ipv4/raw.c       2006-11-30 21:19:45 +0100
29878 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/raw.c     2006-12-17 03:23:33 +0100
29879 @@ -78,6 +78,7 @@
29880  #include <linux/seq_file.h>
29881  #include <linux/netfilter.h>
29882  #include <linux/netfilter_ipv4.h>
29883 +// #include <linux/vs_base.h>
29884  
29885  struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
29886  DEFINE_RWLOCK(raw_v4_lock);
29887 @@ -112,7 +113,8 @@ struct sock *__raw_v4_lookup(struct sock
29888  
29889                 if (inet->num == num                                    &&
29890                     !(inet->daddr && inet->daddr != raddr)              &&
29891 -                   !(inet->rcv_saddr && inet->rcv_saddr != laddr)      &&
29892 +                   raw_addr_match(sk->sk_nx_info, laddr,
29893 +                       inet->rcv_saddr, inet->rcv_saddr2)              &&
29894                     !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
29895                         goto found; /* gotcha */
29896         }
29897 @@ -312,6 +314,11 @@ static int raw_send_hdrinc(struct sock *
29898                 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
29899         }
29900  
29901 +       err = -EPERM;
29902 +       if (!vx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW)
29903 +               && (!addr_in_nx_info(sk->sk_nx_info, iph->saddr)))
29904 +               goto error_free;
29905 +
29906         err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
29907                       dst_output);
29908         if (err > 0)
29909 @@ -323,6 +330,7 @@ out:
29910  
29911  error_fault:
29912         err = -EFAULT;
29913 +error_free:
29914         kfree_skb(skb);
29915  error:
29916         IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
29917 @@ -489,6 +497,12 @@ static int raw_sendmsg(struct kiocb *ioc
29918                 }
29919  
29920                 security_sk_classify_flow(sk, &fl);
29921 +               if (sk->sk_nx_info) {
29922 +                       err = ip_find_src(sk->sk_nx_info, &rt, &fl);
29923 +
29924 +                       if (err)
29925 +                               goto done;
29926 +               }
29927                 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
29928         }
29929         if (err)
29930 @@ -793,7 +807,8 @@ static struct sock *raw_get_first(struct
29931                 struct hlist_node *node;
29932  
29933                 sk_for_each(sk, node, &raw_v4_htable[state->bucket])
29934 -                       if (sk->sk_family == PF_INET)
29935 +                       if (sk->sk_family == PF_INET &&
29936 +                               nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
29937                                 goto found;
29938         }
29939         sk = NULL;
29940 @@ -809,7 +824,8 @@ static struct sock *raw_get_next(struct 
29941                 sk = sk_next(sk);
29942  try_again:
29943                 ;
29944 -       } while (sk && sk->sk_family != PF_INET);
29945 +       } while (sk && (sk->sk_family != PF_INET ||
29946 +               !nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)));
29947  
29948         if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) {
29949                 sk = sk_head(&raw_v4_htable[state->bucket]);
29950 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/tcp.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp.c
29951 --- linux-2.6.19.1/net/ipv4/tcp.c       2006-11-30 21:19:45 +0100
29952 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp.c     2006-11-30 20:55:45 +0100
29953 @@ -258,6 +258,7 @@
29954  #include <linux/bootmem.h>
29955  #include <linux/cache.h>
29956  #include <linux/err.h>
29957 +#include <linux/in.h>
29958  
29959  #include <net/icmp.h>
29960  #include <net/tcp.h>
29961 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/tcp_ipv4.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp_ipv4.c
29962 --- linux-2.6.19.1/net/ipv4/tcp_ipv4.c  2006-11-30 21:19:45 +0100
29963 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp_ipv4.c        2006-12-04 04:51:13 +0100
29964 @@ -77,6 +77,7 @@
29965  #include <linux/stddef.h>
29966  #include <linux/proc_fs.h>
29967  #include <linux/seq_file.h>
29968 +// #include <linux/vs_base.h>
29969  
29970  int sysctl_tcp_tw_reuse __read_mostly;
29971  int sysctl_tcp_low_latency __read_mostly;
29972 @@ -1389,6 +1390,12 @@ static void *listening_get_next(struct s
29973                 req = req->dl_next;
29974                 while (1) {
29975                         while (req) {
29976 +                               vxdprintk(VXD_CBIT(net, 6),
29977 +                                       "sk,req: %p [#%d] (from %d)", req->sk,
29978 +                                       (req->sk)?req->sk->sk_nid:0, nx_current_nid());
29979 +                               if (req->sk &&
29980 +                                       !nx_check(req->sk->sk_nid, VS_WATCH_P|VS_IDENT))
29981 +                                       continue;
29982                                 if (req->rsk_ops->family == st->family) {
29983                                         cur = req;
29984                                         goto out;
29985 @@ -1413,6 +1420,10 @@ get_req:
29986         }
29987  get_sk:
29988         sk_for_each_from(sk, node) {
29989 +               vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)",
29990 +                       sk, sk->sk_nid, nx_current_nid());
29991 +               if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
29992 +                       continue;
29993                 if (sk->sk_family == st->family) {
29994                         cur = sk;
29995                         goto out;
29996 @@ -1464,18 +1475,26 @@ static void *established_get_first(struc
29997  
29998                 read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
29999                 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
30000 -                       if (sk->sk_family != st->family) {
30001 +                       vxdprintk(VXD_CBIT(net, 6),
30002 +                               "sk,egf: %p [#%d] (from %d)",
30003 +                               sk, sk->sk_nid, nx_current_nid());
30004 +                       if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
30005 +                               continue;
30006 +                       if (sk->sk_family != st->family)
30007                                 continue;
30008 -                       }
30009                         rc = sk;
30010                         goto out;
30011                 }
30012                 st->state = TCP_SEQ_STATE_TIME_WAIT;
30013                 inet_twsk_for_each(tw, node,
30014                                    &tcp_hashinfo.ehash[st->bucket + tcp_hashinfo.ehash_size].chain) {
30015 -                       if (tw->tw_family != st->family) {
30016 +                       vxdprintk(VXD_CBIT(net, 6),
30017 +                               "tw: %p [#%d] (from %d)",
30018 +                               tw, tw->tw_nid, nx_current_nid());
30019 +                       if (!nx_check(tw->tw_nid, VS_WATCH_P|VS_IDENT))
30020 +                               continue;
30021 +                       if (tw->tw_family != st->family)
30022                                 continue;
30023 -                       }
30024                         rc = tw;
30025                         goto out;
30026                 }
30027 @@ -1499,7 +1518,8 @@ static void *established_get_next(struct
30028                 tw = cur;
30029                 tw = tw_next(tw);
30030  get_tw:
30031 -               while (tw && tw->tw_family != st->family) {
30032 +               while (tw && (tw->tw_family != st->family ||
30033 +                       !nx_check(tw->tw_nid, VS_WATCH_P|VS_IDENT))) {
30034                         tw = tw_next(tw);
30035                 }
30036                 if (tw) {
30037 @@ -1523,6 +1543,11 @@ get_tw:
30038                 sk = sk_next(sk);
30039  
30040         sk_for_each_from(sk, node) {
30041 +               vxdprintk(VXD_CBIT(net, 6),
30042 +                       "sk,egn: %p [#%d] (from %d)",
30043 +                       sk, sk->sk_nid, nx_current_nid());
30044 +               if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
30045 +                       continue;
30046                 if (sk->sk_family == st->family)
30047                         goto found;
30048         }
30049 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/tcp_minisocks.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp_minisocks.c
30050 --- linux-2.6.19.1/net/ipv4/tcp_minisocks.c     2006-11-30 21:19:45 +0100
30051 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/tcp_minisocks.c   2006-11-08 04:57:42 +0100
30052 @@ -28,6 +28,10 @@
30053  #include <net/inet_common.h>
30054  #include <net/xfrm.h>
30055  
30056 +#include <linux/vs_limit.h>
30057 +#include <linux/vs_socket.h>
30058 +#include <linux/vs_context.h>
30059 +
30060  #ifdef CONFIG_SYSCTL
30061  #define SYNC_INIT 0 /* let the user enable it */
30062  #else
30063 @@ -294,6 +298,11 @@ void tcp_time_wait(struct sock *sk, int 
30064                 tcptw->tw_ts_recent     = tp->rx_opt.ts_recent;
30065                 tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp;
30066  
30067 +               tw->tw_xid              = sk->sk_xid;
30068 +               tw->tw_vx_info          = NULL;
30069 +               tw->tw_nid              = sk->sk_nid;
30070 +               tw->tw_nx_info          = NULL;
30071 +
30072  #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
30073                 if (tw->tw_family == PF_INET6) {
30074                         struct ipv6_pinfo *np = inet6_sk(sk);
30075 diff -NurpP --minimal linux-2.6.19.1/net/ipv4/udp.c linux-2.6.19.1-vs2.3.0.6/net/ipv4/udp.c
30076 --- linux-2.6.19.1/net/ipv4/udp.c       2006-11-30 21:19:45 +0100
30077 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv4/udp.c     2006-12-17 03:36:34 +0100
30078 @@ -108,6 +108,7 @@
30079  #include <net/inet_common.h>
30080  #include <net/checksum.h>
30081  #include <net/xfrm.h>
30082 +// #include <linux/vs_base.h>
30083  
30084  /*
30085   *     Snmp MIB for the UDP layer
30086 @@ -195,6 +196,8 @@ gotit:
30087                             (!sk2->sk_reuse        || !sk->sk_reuse)         &&
30088                             (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
30089                              || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
30090 +                               /* FIXME: nx_addr_conflict(sk->sk_nx_info,
30091 +                                       inet_rcv_saddr(sk), sk2) &&     */
30092                             (*saddr_cmp)(sk, sk2)                              )
30093                                 goto fail;
30094         }
30095 @@ -260,6 +263,11 @@ static struct sock *udp_v4_lookup_longwa
30096                                 if (inet->rcv_saddr != daddr)
30097                                         continue;
30098                                 score+=2;
30099 +                       } else if (sk->sk_nx_info) {
30100 +                               if (addr_in_nx_info(sk->sk_nx_info, daddr))
30101 +                                       score+=2;
30102 +                               else
30103 +                                       continue;
30104                         }
30105                         if (inet->daddr) {
30106                                 if (inet->daddr != saddr)
30107 @@ -316,7 +324,8 @@ static inline struct sock *udp_v4_mcast_
30108                 if (inet->num != hnum                                   ||
30109                     (inet->daddr && inet->daddr != rmt_addr)            ||
30110                     (inet->dport != rmt_port && inet->dport)            ||
30111 -                   (inet->rcv_saddr && inet->rcv_saddr != loc_addr)    ||
30112 +                   (inet->rcv_saddr && inet->rcv_saddr != loc_addr &&
30113 +                    inet->rcv_saddr2 && inet->rcv_saddr2 != loc_addr)  ||
30114                     ipv6_only_sock(s)                                   ||
30115                     (s->sk_bound_dev_if && s->sk_bound_dev_if != dif))
30116                         continue;
30117 @@ -626,7 +635,13 @@ int udp_sendmsg(struct kiocb *iocb, stru
30118                                     .uli_u = { .ports =
30119                                                { .sport = inet->sport,
30120                                                  .dport = dport } } };
30121 +               struct nx_info *nxi = sk->sk_nx_info;
30122 +
30123                 security_sk_classify_flow(sk, &fl);
30124 +               err = ip_find_src(nxi, &rt, &fl);
30125 +               if (err)
30126 +                       goto out;
30127 +
30128                 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
30129                 if (err)
30130                         goto out;
30131 @@ -1451,8 +1466,10 @@ static struct sock *udp_get_first(struct
30132  
30133         for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
30134                 struct hlist_node *node;
30135 +
30136                 sk_for_each(sk, node, &udp_hash[state->bucket]) {
30137 -                       if (sk->sk_family == state->family)
30138 +                       if (sk->sk_family == state->family &&
30139 +                               nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))
30140                                 goto found;
30141                 }
30142         }
30143 @@ -1469,7 +1486,8 @@ static struct sock *udp_get_next(struct 
30144                 sk = sk_next(sk);
30145  try_again:
30146                 ;
30147 -       } while (sk && sk->sk_family != state->family);
30148 +       } while (sk && (sk->sk_family != state->family ||
30149 +               !nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)));
30150  
30151         if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
30152                 sk = sk_head(&udp_hash[state->bucket]);
30153 diff -NurpP --minimal linux-2.6.19.1/net/ipv6/addrconf.c linux-2.6.19.1-vs2.3.0.6/net/ipv6/addrconf.c
30154 --- linux-2.6.19.1/net/ipv6/addrconf.c  2006-11-30 21:19:45 +0100
30155 +++ linux-2.6.19.1-vs2.3.0.6/net/ipv6/addrconf.c        2006-12-08 00:31:37 +0100
30156 @@ -2730,7 +2730,10 @@ static void if6_seq_stop(struct seq_file
30157  static int if6_seq_show(struct seq_file *seq, void *v)
30158  {
30159         struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
30160 -       seq_printf(seq,
30161 +
30162 +       /* no ipv6 inside a vserver for now */
30163 +       if (vx_check(0, VS_ADMIN|VS_WATCH))
30164 +               seq_printf(seq,
30165                    NIP6_SEQFMT " %02x %02x %02x %02x %8s\n",
30166                    NIP6(ifp->addr),
30167                    ifp->idev->dev->ifindex,
30168 @@ -3203,6 +3206,10 @@ static int inet6_dump_addr(struct sk_buf
30169         struct ifmcaddr6 *ifmca;
30170         struct ifacaddr6 *ifaca;
30171  
30172 +       /* no ipv6 inside a vserver for now */
30173 +       if (skb->sk && skb->sk->sk_vx_info)
30174 +               return skb->len;
30175 +
30176         s_idx = cb->args[0];
30177         s_ip_idx = ip_idx = cb->args[1];
30178         read_lock(&dev_base_lock);
30179 @@ -3480,6 +3487,10 @@ static int inet6_dump_ifinfo(struct sk_b
30180         struct net_device *dev;
30181         struct inet6_dev *idev;
30182  
30183 +       /* no ipv6 inside a vserver for now */
30184 +       if (skb->sk && skb->sk->sk_vx_info)
30185 +               return skb->len;
30186 +
30187         read_lock(&dev_base_lock);
30188         for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
30189                 if (idx < s_idx)
30190 diff -NurpP --minimal linux-2.6.19.1/net/netlink/af_netlink.c linux-2.6.19.1-vs2.3.0.6/net/netlink/af_netlink.c
30191 --- linux-2.6.19.1/net/netlink/af_netlink.c     2006-11-30 21:19:46 +0100
30192 +++ linux-2.6.19.1-vs2.3.0.6/net/netlink/af_netlink.c   2006-11-08 21:52:09 +0100
30193 @@ -56,6 +56,9 @@
30194  #include <linux/types.h>
30195  #include <linux/audit.h>
30196  #include <linux/selinux.h>
30197 +#include <linux/vs_context.h>
30198 +#include <linux/vs_network.h>
30199 +#include <linux/vs_limit.h>
30200  
30201  #include <net/sock.h>
30202  #include <net/scm.h>
30203 diff -NurpP --minimal linux-2.6.19.1/net/socket.c linux-2.6.19.1-vs2.3.0.6/net/socket.c
30204 --- linux-2.6.19.1/net/socket.c 2006-11-30 21:19:46 +0100
30205 +++ linux-2.6.19.1-vs2.3.0.6/net/socket.c       2006-12-04 05:08:37 +0100
30206 @@ -93,6 +93,8 @@
30207  
30208  #include <net/sock.h>
30209  #include <linux/netfilter.h>
30210 +#include <linux/vs_base.h>
30211 +#include <linux/vs_socket.h>
30212  
30213  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
30214  static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
30215 @@ -540,7 +542,7 @@ static inline int __sock_sendmsg(struct 
30216                                  struct msghdr *msg, size_t size)
30217  {
30218         struct sock_iocb *si = kiocb_to_siocb(iocb);
30219 -       int err;
30220 +       int err, len;
30221  
30222         si->sock = sock;
30223         si->scm = NULL;
30224 @@ -551,7 +553,22 @@ static inline int __sock_sendmsg(struct 
30225         if (err)
30226                 return err;
30227  
30228 -       return sock->ops->sendmsg(iocb, sock, msg, size);
30229 +       len = sock->ops->sendmsg(iocb, sock, msg, size);
30230 +       if (sock->sk) {
30231 +               if (len == size)
30232 +                       vx_sock_send(sock->sk, size);
30233 +               else
30234 +                       vx_sock_fail(sock->sk, size);
30235 +       }
30236 +       vxdprintk(VXD_CBIT(net, 7),
30237 +               "__sock_sendmsg: %p[%p,%p,%p;%d/%d]:%d/%d",
30238 +               sock, sock->sk,
30239 +               (sock->sk)?sock->sk->sk_nx_info:0,
30240 +               (sock->sk)?sock->sk->sk_vx_info:0,
30241 +               (sock->sk)?sock->sk->sk_xid:0,
30242 +               (sock->sk)?sock->sk->sk_nid:0,
30243 +               (unsigned int)size, len);
30244 +       return len;
30245  }
30246  
30247  int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
30248 @@ -589,7 +606,7 @@ int kernel_sendmsg(struct socket *sock, 
30249  static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
30250                                  struct msghdr *msg, size_t size, int flags)
30251  {
30252 -       int err;
30253 +       int err, len;
30254         struct sock_iocb *si = kiocb_to_siocb(iocb);
30255  
30256         si->sock = sock;
30257 @@ -602,7 +619,18 @@ static inline int __sock_recvmsg(struct 
30258         if (err)
30259                 return err;
30260  
30261 -       return sock->ops->recvmsg(iocb, sock, msg, size, flags);
30262 +       len = sock->ops->recvmsg(iocb, sock, msg, size, flags);
30263 +       if ((len >= 0) && sock->sk)
30264 +               vx_sock_recv(sock->sk, len);
30265 +       vxdprintk(VXD_CBIT(net, 7),
30266 +               "__sock_recvmsg: %p[%p,%p,%p;%d/%d]:%d/%d",
30267 +               sock, sock->sk,
30268 +               (sock->sk)?sock->sk->sk_nx_info:0,
30269 +               (sock->sk)?sock->sk->sk_vx_info:0,
30270 +               (sock->sk)?sock->sk->sk_xid:0,
30271 +               (sock->sk)?sock->sk->sk_nid:0,
30272 +               (unsigned int)size, len);
30273 +       return len;
30274  }
30275  
30276  int sock_recvmsg(struct socket *sock, struct msghdr *msg,
30277 @@ -1061,6 +1089,10 @@ static int __sock_create(int family, int
30278         if (type < 0 || type >= SOCK_MAX)
30279                 return -EINVAL;
30280  
30281 +       /* disable IPv6 inside vservers for now */
30282 +       if (family == PF_INET6 && !vx_check(0, VS_ADMIN))
30283 +               return -EAFNOSUPPORT;
30284 +
30285         /* Compatibility.
30286  
30287            This uglymoron is moved from INET layer to here to avoid
30288 @@ -1178,6 +1210,7 @@ asmlinkage long sys_socket(int family, i
30289         if (retval < 0)
30290                 goto out;
30291  
30292 +       set_bit(SOCK_USER_SOCKET, &sock->flags);
30293         retval = sock_map_fd(sock);
30294         if (retval < 0)
30295                 goto out_release;
30296 @@ -1209,10 +1242,12 @@ asmlinkage long sys_socketpair(int famil
30297         err = sock_create(family, type, protocol, &sock1);
30298         if (err < 0)
30299                 goto out;
30300 +       set_bit(SOCK_USER_SOCKET, &sock1->flags);
30301  
30302         err = sock_create(family, type, protocol, &sock2);
30303         if (err < 0)
30304                 goto out_release_1;
30305 +       set_bit(SOCK_USER_SOCKET, &sock2->flags);
30306  
30307         err = sock1->ops->socketpair(sock1, sock2);
30308         if (err < 0)
30309 diff -NurpP --minimal linux-2.6.19.1/net/sunrpc/auth.c linux-2.6.19.1-vs2.3.0.6/net/sunrpc/auth.c
30310 --- linux-2.6.19.1/net/sunrpc/auth.c    2006-11-30 21:19:46 +0100
30311 +++ linux-2.6.19.1-vs2.3.0.6/net/sunrpc/auth.c  2006-11-08 04:57:47 +0100
30312 @@ -13,6 +13,7 @@
30313  #include <linux/errno.h>
30314  #include <linux/sunrpc/clnt.h>
30315  #include <linux/spinlock.h>
30316 +#include <linux/vs_tag.h>
30317  
30318  #ifdef RPC_DEBUG
30319  # define RPCDBG_FACILITY       RPCDBG_AUTH
30320 @@ -263,6 +264,7 @@ rpcauth_lookupcred(struct rpc_auth *auth
30321         struct auth_cred acred = {
30322                 .uid = current->fsuid,
30323                 .gid = current->fsgid,
30324 +               .tag = dx_current_tag(),
30325                 .group_info = current->group_info,
30326         };
30327         struct rpc_cred *ret;
30328 @@ -282,6 +284,7 @@ rpcauth_bindcred(struct rpc_task *task)
30329         struct auth_cred acred = {
30330                 .uid = current->fsuid,
30331                 .gid = current->fsgid,
30332 +               .tag = dx_current_tag(),
30333                 .group_info = current->group_info,
30334         };
30335         struct rpc_cred *ret;
30336 diff -NurpP --minimal linux-2.6.19.1/net/sunrpc/auth_unix.c linux-2.6.19.1-vs2.3.0.6/net/sunrpc/auth_unix.c
30337 --- linux-2.6.19.1/net/sunrpc/auth_unix.c       2006-11-30 21:19:46 +0100
30338 +++ linux-2.6.19.1-vs2.3.0.6/net/sunrpc/auth_unix.c     2006-11-08 04:57:47 +0100
30339 @@ -11,12 +11,14 @@
30340  #include <linux/module.h>
30341  #include <linux/sunrpc/clnt.h>
30342  #include <linux/sunrpc/auth.h>
30343 +#include <linux/vs_tag.h>
30344  
30345  #define NFS_NGROUPS    16
30346  
30347  struct unx_cred {
30348         struct rpc_cred         uc_base;
30349         gid_t                   uc_gid;
30350 +       tag_t                   uc_tag;
30351         gid_t                   uc_gids[NFS_NGROUPS];
30352  };
30353  #define uc_uid                 uc_base.cr_uid
30354 @@ -78,6 +80,7 @@ unx_create_cred(struct rpc_auth *auth, s
30355         if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
30356                 cred->uc_uid = 0;
30357                 cred->uc_gid = 0;
30358 +               cred->uc_tag = dx_current_tag();
30359                 cred->uc_gids[0] = NOGROUP;
30360         } else {
30361                 int groups = acred->group_info->ngroups;
30362 @@ -86,6 +89,7 @@ unx_create_cred(struct rpc_auth *auth, s
30363  
30364                 cred->uc_uid = acred->uid;
30365                 cred->uc_gid = acred->gid;
30366 +               cred->uc_tag = acred->tag;
30367                 for (i = 0; i < groups; i++)
30368                         cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
30369                 if (i < NFS_NGROUPS)
30370 @@ -117,7 +121,8 @@ unx_match(struct auth_cred *acred, struc
30371                 int groups;
30372  
30373                 if (cred->uc_uid != acred->uid
30374 -                || cred->uc_gid != acred->gid)
30375 +                || cred->uc_gid != acred->gid
30376 +                || cred->uc_tag != acred->tag)
30377                         return 0;
30378  
30379                 groups = acred->group_info->ngroups;
30380 @@ -143,7 +148,7 @@ unx_marshal(struct rpc_task *task, __be3
30381         struct rpc_clnt *clnt = task->tk_client;
30382         struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
30383         __be32          *base, *hold;
30384 -       int             i;
30385 +       int             i, tag;
30386  
30387         *p++ = htonl(RPC_AUTH_UNIX);
30388         base = p++;
30389 @@ -153,9 +158,12 @@ unx_marshal(struct rpc_task *task, __be3
30390          * Copy the UTS nodename captured when the client was created.
30391          */
30392         p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
30393 +       tag = task->tk_client->cl_tag;
30394  
30395 -       *p++ = htonl((u32) cred->uc_uid);
30396 -       *p++ = htonl((u32) cred->uc_gid);
30397 +       *p++ = htonl((u32) TAGINO_UID(tag,
30398 +               cred->uc_uid, cred->uc_tag));
30399 +       *p++ = htonl((u32) TAGINO_GID(tag,
30400 +               cred->uc_gid, cred->uc_tag));
30401         hold = p++;
30402         for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
30403                 *p++ = htonl((u32) cred->uc_gids[i]);
30404 diff -NurpP --minimal linux-2.6.19.1/net/sunrpc/clnt.c linux-2.6.19.1-vs2.3.0.6/net/sunrpc/clnt.c
30405 --- linux-2.6.19.1/net/sunrpc/clnt.c    2006-11-30 21:19:46 +0100
30406 +++ linux-2.6.19.1-vs2.3.0.6/net/sunrpc/clnt.c  2006-11-08 04:57:47 +0100
30407 @@ -29,6 +29,7 @@
30408  #include <linux/slab.h>
30409  #include <linux/utsname.h>
30410  #include <linux/workqueue.h>
30411 +#include <linux/vs_cvirt.h>
30412  
30413  #include <linux/sunrpc/clnt.h>
30414  #include <linux/sunrpc/rpc_pipe_fs.h>
30415 @@ -238,7 +239,9 @@ struct rpc_clnt *rpc_create(struct rpc_c
30416                 clnt->cl_autobind = 1;
30417         if (args->flags & RPC_CLNT_CREATE_ONESHOT)
30418                 clnt->cl_oneshot = 1;
30419 -
30420 +       /* FIXME: handle RPC_CLNT_CREATE_TAGGED
30421 +       if (args->flags & RPC_CLNT_CREATE_TAGGED)
30422 +               clnt->cl_tag = 1; */
30423         return clnt;
30424  }
30425  EXPORT_SYMBOL_GPL(rpc_create);
30426 diff -NurpP --minimal linux-2.6.19.1/net/unix/af_unix.c linux-2.6.19.1-vs2.3.0.6/net/unix/af_unix.c
30427 --- linux-2.6.19.1/net/unix/af_unix.c   2006-11-30 21:19:46 +0100
30428 +++ linux-2.6.19.1-vs2.3.0.6/net/unix/af_unix.c 2006-12-04 05:08:47 +0100
30429 @@ -116,6 +116,8 @@
30430  #include <linux/mount.h>
30431  #include <net/checksum.h>
30432  #include <linux/security.h>
30433 +#include <linux/vs_context.h>
30434 +#include <linux/vs_limit.h>
30435  
30436  int sysctl_unix_max_dgram_qlen __read_mostly = 10;
30437  
30438 @@ -252,6 +254,8 @@ static struct sock *__unix_find_socket_b
30439         sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
30440                 struct unix_sock *u = unix_sk(s);
30441  
30442 +               if (!nx_check(s->sk_nid, VS_WATCH_P|VS_IDENT))
30443 +                       continue;
30444                 if (u->addr->len == len &&
30445                     !memcmp(u->addr->name, sunname, len))
30446                         goto found;
30447 @@ -807,7 +811,7 @@ static int unix_bind(struct socket *sock
30448                  */
30449                 mode = S_IFSOCK |
30450                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
30451 -               err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
30452 +               err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
30453                 if (err)
30454                         goto out_mknod_dput;
30455                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
30456 diff -NurpP --minimal linux-2.6.19.1/net/x25/af_x25.c linux-2.6.19.1-vs2.3.0.6/net/x25/af_x25.c
30457 --- linux-2.6.19.1/net/x25/af_x25.c     2006-09-20 16:58:54 +0200
30458 +++ linux-2.6.19.1-vs2.3.0.6/net/x25/af_x25.c   2006-11-08 04:57:42 +0100
30459 @@ -501,7 +501,10 @@ static int x25_create(struct socket *soc
30460  
30461         x25 = x25_sk(sk);
30462  
30463 -       sock_init_data(sock, sk);
30464 +       sk->sk_socket = sock;
30465 +       sk->sk_type = sock->type;
30466 +       sk->sk_sleep = &sock->wait;
30467 +       sock->sk = sk;
30468  
30469         x25_init_timers(sk);
30470  
30471 Files linux-2.6.19.1/scripts/kconfig/mconf and linux-2.6.19.1-vs2.3.0.6/scripts/kconfig/mconf differ
30472 diff -NurpP --minimal linux-2.6.19.1/security/commoncap.c linux-2.6.19.1-vs2.3.0.6/security/commoncap.c
30473 --- linux-2.6.19.1/security/commoncap.c 2006-11-30 21:19:47 +0100
30474 +++ linux-2.6.19.1-vs2.3.0.6/security/commoncap.c       2006-11-30 19:54:52 +0100
30475 @@ -23,10 +23,11 @@
30476  #include <linux/ptrace.h>
30477  #include <linux/xattr.h>
30478  #include <linux/hugetlb.h>
30479 +#include <linux/vs_context.h>
30480  
30481  int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
30482  {
30483 -       NETLINK_CB(skb).eff_cap = current->cap_effective;
30484 +       cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
30485         return 0;
30486  }
30487  
30488 @@ -44,7 +45,7 @@ EXPORT_SYMBOL(cap_netlink_recv);
30489  int cap_capable (struct task_struct *tsk, int cap)
30490  {
30491         /* Derived from include/linux/sched.h:capable. */
30492 -       if (cap_raised(tsk->cap_effective, cap))
30493 +       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
30494                 return 0;
30495         return -EPERM;
30496  }
30497 @@ -142,7 +143,8 @@ void cap_bprm_apply_creds (struct linux_
30498         /* Derived from fs/exec.c:compute_creds. */
30499         kernel_cap_t new_permitted, working;
30500  
30501 -       new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
30502 +       new_permitted = cap_intersect (bprm->cap_permitted,
30503 +                                       vx_current_cap_bset());
30504         working = cap_intersect (bprm->cap_inheritable,
30505                                  current->cap_inheritable);
30506         new_permitted = cap_combine (new_permitted, working);
30507 @@ -311,7 +313,8 @@ void cap_task_reparent_to_init (struct t
30508  
30509  int cap_syslog (int type)
30510  {
30511 -       if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
30512 +       if ((type != 3 && type != 10) &&
30513 +               !vx_capable(CAP_SYS_ADMIN, VXC_SYSLOG))
30514                 return -EPERM;
30515         return 0;
30516  }
30517 diff -NurpP --minimal linux-2.6.19.1/security/dummy.c linux-2.6.19.1-vs2.3.0.6/security/dummy.c
30518 --- linux-2.6.19.1/security/dummy.c     2006-11-30 21:19:47 +0100
30519 +++ linux-2.6.19.1-vs2.3.0.6/security/dummy.c   2006-11-30 19:53:55 +0100
30520 @@ -28,6 +28,7 @@
30521  #include <linux/hugetlb.h>
30522  #include <linux/ptrace.h>
30523  #include <linux/file.h>
30524 +#include <linux/vs_context.h>
30525  
30526  static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
30527  {
30528 @@ -84,7 +85,7 @@ static int dummy_sysctl (ctl_table * tab
30529         return 0;
30530  }
30531  
30532 -static int dummy_quotactl (int cmds, int type, int id, struct super_block *sb)
30533 +static int dummy_quotactl (int cmds, int type, int id, struct dqhash *hash)
30534  {
30535         return 0;
30536  }
30537 @@ -678,7 +679,7 @@ static int dummy_sem_semop (struct sem_a
30538  
30539  static int dummy_netlink_send (struct sock *sk, struct sk_buff *skb)
30540  {
30541 -       NETLINK_CB(skb).eff_cap = current->cap_effective;
30542 +       cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
30543         return 0;
30544  }
30545  
30546 diff -NurpP --minimal linux-2.6.19.1/security/selinux/hooks.c linux-2.6.19.1-vs2.3.0.6/security/selinux/hooks.c
30547 --- linux-2.6.19.1/security/selinux/hooks.c     2006-11-30 21:19:47 +0100
30548 +++ linux-2.6.19.1-vs2.3.0.6/security/selinux/hooks.c   2006-11-30 20:55:45 +0100
30549 @@ -1461,9 +1461,10 @@ static int selinux_sysctl(ctl_table *tab
30550         return error;
30551  }
30552  
30553 -static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
30554 +static int selinux_quotactl(int cmds, int type, int id, struct dqhash *hash)
30555  {
30556         int rc = 0;
30557 +       struct super_block *sb = hash->dqh_sb;
30558  
30559         if (!sb)
30560                 return 0;
This page took 2.205691 seconds and 3 git commands to generate.